Как вручную добавить геттеры / мутации в хранилище Vuex после того, как оно уже создано? - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь добавить новые переменные, геттеры и мутации в «созданный» хук жизненного цикла в одном из моих компонентов Vuejs. Переменные работают нормально. Но с геттерами / мутациями кажется, что это не так просто, как добавить новые функции в объект хранилища vuex. Проблема, которую я пытаюсь решить, - это создание «общих» повторно используемых компонентов.

Вот компонент:

<template>
  <div>
    <h2 class="headline">Number of items:</h2>
    <v-select
      :items="limits"
      item-value="value"
      item-text="text"
      label="Select"
      v-model="selected_limit"/>
  </div>
</template>

<script>
  import {selectLimitComponentVariables} from './index';
  import {selectLimitComponentGetters} from './getters';
  import {selectLimitComponentMutations} from './mutations';

  export default {
    created: function () {
      // Add the variables
      Object.assign(this.$store.state[this.ns], selectLimitComponentVariables(this.var_prefix));
      // Add the getters
      Object.assign(this.$store.getters, selectLimitComponentGetters(this.ns, this.var_prefix));
      // Add the mutations
      Object.assign(this.$store._mutations, selectLimitComponentMutations(this.ns, this.var_prefix));
    },
    name: 'SelectLimitComponent',
    props: {
      ns: {
        type: String,
        default: null
      },
      var_prefix: {
        type: String,
        default: ''
      }
    },
    computed: {
      selected_limit: {
        get () {
          return this.$store.state[this.ns].selected_limit;
        },
        set (value) {
          this.$store.commit(`${this.ns}/update${this.var_prefix}selected_limit`, value)
        }
      },
      limits: {
        get() {
          return this.$store.state[this.ns].limits;
        }
      }
    }
  }
</script>

А вот и импортированные функции. selectLimitComponentVariables:

export const selectLimitComponentVariables = function (prefix) {
  return {
    [`${prefix}selected_limit`]: '100',
    [`${prefix}limits`]: [
      {'text': '10', 'value': '10'},
      {'text': '50', 'value': '50'},
      {'text': '100', 'value': '100'},
      {'text': '250', 'value': '250'},
      {'text': 'No limit', 'value': '-1'}]}
};

selectLimitComponentGetters:

export const selectLimitComponentGetters = function(namespace, prefix){
  return {
    [`${namespace}/${prefix}selected_limit`]: state => state[`${prefix}selected_limit`]
  }
};

selectLimitComponentMutations:

export const selectLimitComponentMutations = function (namespace, prefix){
  return {
    [`${namespace}/update${prefix}selected_limit`]: (state, newLimit) => state[`${prefix}selected_limit`] = newLimit
  }
};

Есть ли способ вручную добавить или зарегистрировать новые геттеры / мутации после создания хранилища vuex?

Ответы [ 3 ]

0 голосов
/ 14 мая 2018

Проблема с добавлением значений после создания экземпляра состоит в том, что они не становятся реактивными без использования set

Когда вы добавляете новое свойство, которого не было при наблюдении данных.Из-за ограничений ES5 и обеспечения согласованного поведения во всех браузерах Vue.js не может обнаруживать добавление / удаление свойств.Лучше всего всегда объявлять свойства, которые должны быть активными заранее.В случаях, когда вам абсолютно необходимо добавить или удалить свойства во время выполнения, используйте глобальные методы Vue.set или Vue.delete.

, попробуйте вместо этого

import Vue from 'vue';

export const selectLimitComponentMutations = function (namespace, prefix){
  return {
    [`${namespace}/update${prefix}selected_limit`]: (state, newLimit) => {
      Vue.$set(state, `${prefix}selected_limit`, newLimit);
    }
  }
};
0 голосов
/ 14 мая 2018

Похоже, что вы пытаетесь сделать, это иметь состояние Vuex для каждого компонента.

Если вы случайным образом модифицируете схему Vuex таким образом, вам будет очень трудно управлять разделением состояний (вы просто исправляете корневое состояние Vuex).

Вот другой подход. Вы можете создать отдельный модуль Vuex и динамически зарегистрировать его в хуке created вашего компонента.

Vue.use(Vuex);

const HomeModule = {
  namespaced: true,
  state() {
    return {
      count: 0,
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    },
  },
};

const ns = 'home';

Vue.component('home', {
  template: '<div><button @click="increment">+</button> {{ count }}</div>',
  created() {
    if (!this.$store.state[ns]) {
      this.$store.registerModule(ns, HomeModule);
    }
  },
  computed: Vuex.mapState(ns, ['count']),
  methods: Vuex.mapMutations(ns, ['increment']),
});

new Vue({
  el: '#app',
  store: new Vuex.Store(),  // Empty root store
});
<script src="https://cdn.rawgit.com/vuejs/vuex/dev/dist/vuex.min.js"></script>
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>

<div id="app">
  <home></home>
</div>
  • Я использовал здесь глобальную переменную ns, но вы можете получить ее у проп, как в вашем примере.
  • Вы можете динамически собирать модуль вместо его жесткого кодирования.
  • При необходимости вы также можете отменить регистрацию модуля при уничтожении компонента.
0 голосов
/ 14 мая 2018

Лучше использовать store.registerModule функцию vuex для динамического добавления новых модулей в vuex

this.$store.registerModule(`${this.ns}selected_limit`, {
  state: selectLimitComponentVariables...,
  getters: selectLimitComponentGetters...,
  mutations: selectLimitComponentMutations...,
  namespaced: true
})

Вы можете проверить официальный документ в Dynamic Module Registration разделе https://vuex.vuejs.org/en/modules.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...