直接在模板

时间:2018-01-12 15:12:27

标签: vue.js vuex mutation

我认为我对vue + vuex的工作有误解。

鉴于以下情况。

我有一个vuex状态,其中包含列表的过滤器。可以将每个过滤器项目标记为已选中。但是 - 只有在单击应用按钮时才应通过修改器修改vuex状态,以便其他组件可以对更改做出反应。例如,列表将根据所选过滤器重新加载数据。当状态更新时,应该更新组件。

我创建了一支笔

https://codepen.io/anon/pen/OzEJWP?editors=1010

https://jsfiddle.net/rxqu7ame/

Vue.component('filter-item', {
template: ` <div>
            <!--{{item.color}} ({{item.selected}}) <button @click="item.selected = !item.selected">toggle</button>-->
            {{item.color}} ({{isSelected}}) <button @click="isSelected = !isSelected">toggle</button>
          </div>`,
data: function () {
return {
  isSelected: this.item.selected
}
},
computed: {
/*isSelected : function(){
  return this.item.selected;
}*/
},

props: ['item']
});   

我遇到了不同的问题。

  1. 当我在“过滤器项目”#34;中直接切换所选的'属性时模板,vuex状态也会更新。
  2. 所以我尝试用状态初始化数据属性。现在只更新数据变量isSelected'。当我按下“应用”按钮时,将更新vuex状态(稍后我将使用变异)。到现在为止还挺好。但现在,当状态发生变化时,isSelected'属性不会自动更新。
  3. 如果我使用计算属性,则无法在点击事件中更改“isSelected”。
  4. 实现既定方案的正确方法是什么?

    非常感谢!

2 个答案:

答案 0 :(得分:0)

更新了codepen:https://codepen.io/guanzo/pen/xpzrMm?editors=0010

之前我遇到过这种情况,发现添加一个临时的&#34;最容易。 &#34;实际&#34;旁边的变量商店中的变量。 &#34;实际&#34;变量是selected,&#34;临时&#34;变量是tempSelected&#34;。当用户切换颜色时,tempSelected会更新,当您&#34;适用于商店&#34;时,selected会更新。

这是默认商店状态的样子

filter: [
      {
        color: 'red',
        selected: false,
        tempSelected: false,
      },
      {
        color: 'green',
        selected: false,
        tempSelected: false,
      }      
    ]

这里是如何通过突变切换单一颜色。你不应该通过引用直接更新商店,总是通过突变来实现。如果您对计算的get / set语法感到困惑,请查看此处:https://vuejs.org/v2/guide/computed.html#Computed-Setter

Vue.component('filter-item', {
  template: ` <div>
                {{item.color}} ({{item.tempSelected}}) 
<button @click="isSelected = !isSelected">toggle</button>
              </div>`,
  computed: {
     isSelected:{
       get(){
         var filter = this.$store.state.filter.find(filter=>filter.color === this.item.color)
         return filter.tempSelected
       },
       set(value){
         this.$store.commit('updateSelected',{
           color: this.item.color,
           selected: value
         })
       }
     }
  },

这里是商店突变以更新单一颜色。

updateSelected(state,payload){
  var filter = state.filter.find(filter=>filter.color===payload.color)
  filter.tempSelected = payload.selected
}

现在你有了存储用户输入的临时变量。要&#34;应用于商店&#34;,您只需要将实际变量的值设置为临时变量的值

updateFilters(state){
      state.updates++;
      state.filter.forEach(filter=>{
          filter.selected = filter.tempSelected
      })
    },

要切换所有值,只需翻转当前的selected值即可。但请务必保持tempSelected变量同步。

toggleFilters(state){
      state.updates++;
      state.filter.forEach(filter=>{
          filter.selected = !filter.selected
          filter.tempSelected = filter.selected
      })
    },

实施&#34;取消更改&#34;现在已经微不足道了。特征。如果用户希望撤消所有更改,您可以将tempSelected设置为selected的值,从而有效地将状态恢复为上一个已知值。

答案 1 :(得分:0)

1)例如,您可以将computed属性添加到此属性的filter-item和watcher。因此,filter-item组件将知道vuex是否已更改,并更改isSelected属性:

data: function () {
  return {
    isSelected: this.$store.state.filter[this.index].selected
  }
},
computed: {
  storeSelected: function(){
    return this.$store.state.filter[this.index].selected;
  },
  color: function(){
    return this.$store.state.filter[this.index].color;
  }
},
watch: {
  storeSelected: function(){
    this.isSelected = this.$store.state.filter[this.index].selected;
  }
},
props: ['index']

codepen:https://codepen.io/aircrisp/pen/MrXEgd?editors=0010

2)

  

在Vuex商店中实际更改状态的唯一方法是提交变异。 https://vuex.vuejs.org/en/mutations.html

因此,如果你使用变异来改变vuex状态 - 你可以在filter-item组件中订阅变异,例如,在组件安装之后:

mounted: function(){
  this.$store.subscribe((mutation, state) => {
     if(mutation === 'changeFilterItem'){
       this.isSelected = state.filter[this.index].selected;
     }
  })
 },

codepen:https://codepen.io/aircrisp/pen/MrXEgd?editors=0010(评论代码)