当一项有一些更改时更新vuex数组的状态

时间:2018-07-03 08:16:34

标签: vue.js vuejs2 vuex

我的vuex商店中有一个名为case的数组。

当我更新数组中现有项目中的几个字段时,我想用新内容更新数组。

我以为我可以在突变中做类似的事情,但是无法正常工作并收到错误typeError: undefined is not an object (evaluating 'state.objects.find')

EDIT_CASE (state, payload) {
    const item = state.objects.find(item => item.id === payload.recordId);
Object.assign(item, payload.case_status);

我的数组如下:

[
    {
        "case_name": "Laptop not working",
        "case_status": "live",
        "case_summary": "This is some summary content",
        "createdBy": "zippy",
        "createdDate": "2018-06-21T15:20:22.932Z",
        "id": "-LFXvk9yY5c-O8yIdf8k"
    },
    {
        "case_name": "Something else",
        "case_status": "live",
        "case_summary": "This is some summary content",
        "createdBy": "zippy",
        "createdDate": "2018-06-21T15:20:22.932Z",
        "id": "-STVvk9yY5c-O3yiTy8k"
    }
]

我还认为,根据我的阅读,Vue不会观察到数组内的变化,因此这可能是我完全走错了路,需要删除然后重新添加数组项吗?

基本上我有一个列表,我对后端进行了更改,现在我希望该列表反映出我通过更新案例状态所做的更改,有人可以帮忙吗?

5 个答案:

答案 0 :(得分:4)

您的示例没有数组问题,因为您尝试更改对象属性-而不是数组元素 reference 。 问题是Object.assign(item, payload.case_status);-您应该提供对象而不仅仅是字段。 (您还说过名为cases的数组,但是示例中有objects,也许这也是个问题);

所以这应该起作用:

EDIT_CASE (state, payload) {
    const item = state.objects.find(item => item.id === payload.recordId);
    Object.assign(item, payload);
}

错误:

  

未定义不是对象

我认为与Object.assign有关,因为您可能将字段传递为未定义

P.S。有一个小的示例可以帮助您了解何时出现阵列问题以及何时一切正常。查看代码注释:)

new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript" },
      { text: "Learn Vue" },
      { text: "Play around in JSFiddle" },
      { text: "Build something awesome" }
    ]
  },
  methods: {
    // work because object property is reactive
  	changeItemProperty() {
    	this.todos[3].text = "changedItemProperty";
    },
    // same reason, properties are reactive
    changeItemWithAssign() {
    	Object.assign(this.todos[3], { text: "changedItemWithAssign" });
    },
    // does not work, can not track changes in array
    // also this will brake all attempts to change TEXT property in UI
    // because property is not reactive after this due to new object
    // try to changeItemProperty or  changeItemWithAssign - doses not work!
    // changeItem2 will fix it :)
    changeItem() {
    	this.todos[3] = { text: "changedItem" }
    },
    // works
    changeItem2() {
    	Vue.set(this.todos, 3, { text: "changedItem2" });
    }	
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  <div v-for="todo in todos" :key="todo.text">
     {{todo.text}}
  </div>
  <button @click="changeItemProperty">changeItemProperty(works)</button>
  <button @click="changeItemWithAssign">changeItemWithAssign(works)</button>
  <button @click="changeItem">changeItem(does not work!)</button>
  <button @click="changeItem2">changeItem2(works)</button>
</div>

答案 1 :(得分:4)

JavaScript(非特定于Vue)无法直接通过索引arr[3] = 'stop';检测设置Array项的值 它还无法检测到添加新密钥或删除对象中的现有密钥。 您必须定义商店的初始状态,例如

const store = new Vuex.Store({
  state: {
    objects: []
  },
  mutations: {
    EDIT_CASE (state, payload) {
      const index = state.objects.findIndex(item => item.id === payload.id);
      if (index !== -1) state.objects.splice(index, 1, payload);
    }
  }
})

答案 2 :(得分:1)

您需要更新阵列

const store = new Vuex.Store({
  state: {
    objects: [
      {id: 1, someProps: 'blablabla'},
      {id: 2, someProps: 'ololololo'}
   ]
  },
  mutations: {
    EDIT_CASE (state, data) {
      const index = state.objects.findIndex(item => item.id === data.id);
      state.objects[index].someProps = data.newPropsValue;

      //this is for vue reaction
      state.objects.push('dog-nail');
      state.objects.splice(-1,1);
  }
})

答案 3 :(得分:1)

您可以使用Vue.set使新对象具有反应性

  const store = new Vuex.Store({
  state: {
    objects: []
  },
  mutations: {
    EDIT_CASE (state, payload) {
      const index = state.objects.findIndex(item => item.id === payload.id);
      if (index !== -1) {
        Vue.set(state.objects, index, payload);
      }
    }
  }
});

答案 4 :(得分:0)

我遇到了类似的问题,并且解决了以下问题: //在组件中

 computed: {

     data: {
         get() {
             this.$store.commit('updateData', this.$store.state.data)
             return this.$store.state.data;
         },
     }
 }

//在商店中

 mutations: {
      updateData(state,item){
          store.state.data = item;
      }
  }

是的,这太神奇了。