Vuex商店仅保留一个组件,而不是两者

时间:2018-05-11 16:10:17

标签: vue.js vuex

所以我有一个带有一些变量的Vuex商店,它看起来像这样:

var dataStore = new Vuex.Store({
    state: {
        consumer_id: undefined,
        some_other_data: 0
    },
    mutations: {
        update: function(type, payload) {
            state = Object.assign(type, payload);
        }
    }
});

我有两个组件,两个组件都是顶级Vue组件。但是MultiSim围绕Sim。他们都使用以下方法访问consumer_id

consumer_id: {
    get: function () {
        return this.$store.state.consumer_id;
    },
    set: function (value) {
        this.$store.commit('update', {consumer_id: value});
    }
},

问题在于,当consumer_id的更改传播到Sim时,MultiSim只会看到undefined(默认值)。 MultiSim更改consumer_id,所有三个组件都会正确捕获,但如果Sim发生更改,则MultiSim不会更新。

例如:

  • MultiSim设置consumer_id = 10
  • [MultiSim: 10, Sim: 10, Store: 10]
  • Sim设置consumer_id = 5
  • [MultiSim: 10, Sim: 5, Store: 5]

谁能看到我可能出错的地方?有没有办法强制更新所有组件?

修改:

所以我找到了一个解决方案,但它更像是一个黑客攻击:

  • MultiSim设置consumer_id = 10
  • [MultiSim: 10, Sim: 10, Store: 10]
  • Sim设置consumer_id = 5
  • `[MultiSim:this。$ store.state.consumer_id / * 5 * /,Sim:5,Store:5]

基本上,MultiSim的计算方法不会更新,即使它可以正常访问实际存储的值。

1 个答案:

答案 0 :(得分:1)

假设您在创建商店时初始化了所有状态属性,您可以使用以下方法向更新突变发送通用有效负载:

const store = new Vuex.Store({
  state: {
    consumer_id: undefined,
    some_other_data: 0
  },
  mutations: {
    update: function(state, payload) {
      for ([key, value] of Object.entries(payload))
        state[key] = value
    }
  }
})

这将允许您的update变异是通用的,并将属性设置为状态。

这是一个例子。

console.clear()

const store = new Vuex.Store({
  state: {
    consumer_id: undefined,
    some_other_data: 0
  },
  mutations: {
    update: function(state, payload) {
      for ([key, value] of Object.entries(payload))
        state[key] = value
    }
  }
})

const Sim = {
  template: `
<div>
Sim <input v-model="consumer_id"> {{consumer_id}}
</div>
`,
  computed:{
    consumer_id: {
      get: function () {
        return this.$store.state.consumer_id;
      },
      set: function (value) {
        this.$store.commit('update', {consumer_id: value});
      }
    },    
  }
}

const MultiSim = {
  template: `
    <div>
      MultiSim <input v-model="consumer_id"> {{consumer_id}}
    </div>
    `,
  computed:{
    consumer_id: {
      get: function () {
        return this.$store.state.consumer_id;
      },
      set: function (value) {
        this.$store.commit('update', {consumer_id: value});
      }
    },    
  }
}

new Vue({
  el: "#app",
  store,
  components: {Sim, MultiSim}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  <sim></sim>
  <multi-sim></multi-sim>
</div>

如果在创建商店时状态初始化,则需要使用Vue.set。

const store = new Vuex.Store({
  state: {
  },
  mutations: {
    update: function(state, payload) {
      for ([key, value] of Object.entries(payload))
        Vue.set(state, key, value)
    }
  }
})

此外,这两个都假定您在每种情况下都在创建有效负载,就像在计算集中一样。

注意:IE中不支持Object.entries,因此您可能需要使用Object.keys。