Как я могу реактивно обновить значение в компоненте из значения хранилища?

#javascript #vue.js #vuejs2

#javascript #vue.js #vuejs2

Вопрос:

У меня есть два компонента и базовое хранилище в соответствии с документами здесь:https://v2.vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch.

Я хочу сделать так, чтобы при вводе во входные данные значение в другом компоненте обновлялось с помощью хранилища.

Вот базовый пример.

App.vue

 <template>
  <div id="app">
    <h1>Store Demo</h1>
    <BaseInputText /> Value From Store: {{ test }}
  </div>
</template>

<script>
import BaseInputText from "./components/BaseInputText.vue";
import { store } from "../store.js";

export default {
  // This should reactively changed as per the input
  computed: {
    test: function() {
      return store.state.test;
    }
  },
  components: {
    BaseInputText
  }
};
</script>
  

BaseInput.vue

 <template>
  <input type="text" class="input" v-model="test" />
</template>

<script>
import { store } from "../store.js";

export default {
  data() {
    return {
      test: store.state.test
    };
  },
  // When the value changes update the store
  watch: {
    test: function(newValue) {
      store.setTest(newValue);
    }
  }
};
</script>
  

store.js

 export const store = {
  debug: true,
  state: {
    test: "hi"
  },
  setTest(newValue) {
    if (this.debug) console.log("Set the test field with:", newValue);
    this.state.test = newValue;
  }
};
  

Я хочу сделать так, чтобы при вводе строки во входные данные обновлялась test переменная в App.vue. Я пытаюсь понять, как работает шаблон хранилища. Я знаю, как использовать props.

У меня также есть рабочая копия здесь: https://codesandbox.io/s/loz79jnoq ?размер шрифта = 14

Комментарии:

1. Если вы пытаетесь обновить store состояние, вам следует использовать mutations . Прямое изменение хранилища является антишаблоном, и вы увидите предупреждение консоли об этом.

2. Это для шаблона хранилища, на который ссылается документация. Извините, тег vuex немного вводит в заблуждение.

Ответ №1:

Обновлено
2.6.0
Для реактивного использования хранилища Vue.observable (добавлено в версии 2.6.0 )

store.js

 import Vue from 'vue'

export const store = Vue.observable({
  debug: true,
  state: {
    test: 'hi'
  }
})
  

BaseInputText.vue

 <input type="text" class="input" v-model="state.test">
...
data() {
    return {
      state: store.state
    };
  },
  

до версии 2.6.0

store.js

 import Vue from 'vue'

export const store = new Vue({
  data: {
    debug: true,
    state: {
      test: 'hi'
    }
  }
})
  

BaseInputText.vue

 <input type="text" class="input" v-model="state.test">
...
data() {
  return {
    state: store.state
  };
}
  

Старый ответ
Из документации However, the difference is that computed properties are cached based on their reactive dependencies .Хранилище не реагирует

Изменить на

App.vue

   data() {
    return {
      state: store.state
    };
  },
  computed: {
    test: function() {
      return this.state.test;
    }
  },
  

Это выглядит плохо, но я не вижу другого способа заставить это работать

Комментарии:

1. Я видел ваш первый ответ, и он на самом деле ближе к правильному. Я изменил это так, что я больше не ссылаюсь напрямую на значение хранилища, а вместо этого ссылаюсь на состояние. т.е. {{ state.test }} вместо {{ test }}. Если вы измените его обратно, я приму ответ :).

2. Работает ли это для вас? Я перезагрузил страницу, и это не для меня) Вы можете увидеть более понятное решение с помощью observable (требуется версия 2.6)

3. Да, похоже, это работает, если вносить случайные изменения, а затем изменять их обратно. Странно. Мне нравится ваше новое решение, но я пока не использую 2.6. Итак, чтобы прояснить общую проблему, нужно напрямую ссылаться на значение в хранилище.

4. Обновлено решением для предыдущих версий vue. Спасибо за интересный вопрос.