代码之家  ›  专栏  ›  技术社区  ›  Andriy Stolyar

如何在Vuex存储区已经创建之后手动将其添加到Vuex存储区?

  •  3
  • Andriy Stolyar  · 技术社区  · 6 年前

    我正试图在我的一个Vuejs组件中的“创建的”生命周期挂钩中添加新的变量、getter和变体。变量工作正常。但对于getter/translation,似乎不像向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>
    

    下面是导入的函数。 选择LimitComponentVariables:

    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`]
      }
    };
    

    SelectLimitComponent突变:

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

    在创建vuex存储之后,是否有方法手动添加或注册新的getter/translation?

    3 回复  |  直到 6 年前
        1
  •  6
  •   ittus    6 年前

    最好使用 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

        2
  •  2
  •   Decade Moon    4 年前

    看起来您要做的是按组件设置Vuex状态。

    如果这样随意修改Vuex模式,将很难管理状态分离(您只是在对根Vuex状态进行猴补)。

    这是另一种方法。您可以创建一个单独的Vuex模块,并在 beforeCreate 部件的挂钩。

    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>',
      beforeCreate() {
        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://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.3/vuex.js"></script>
    
    <div id="app">
      <home></home>
    </div>
    • 我用过 ns 这里是全局变量,但您可以从示例中的道具获取它。
    • 您可以动态构建模块,而不是将其硬编码。
    • 如有必要,还可以在组件销毁时注销模块。
        3
  •  1
  •   Daniel    6 年前

    实例化后添加值的问题是,如果不使用 set

    当您添加数据 观察到。由于ES5的限制,并确保 跨浏览器的行为,Vue。js无法检测属性 添加/删除。最佳做法是始终声明属性 这需要提前做出反应。在你绝对需要的情况下 要在运行时添加或删除属性,请使用全局Vue。设置或 Vue。删除方法。

    试试这个

    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);
        }
      }
    };