vuex中对象数组发生改变,页面渲染无法自动更新

目前在state中有一个对象数组

arr = [
    {
        name: 'name1'
        id: 1
    },
    {
        name: 'name2'
        id: 2
    }
]

该对象数组存在于vuex中

如果我直接修改数组中的值,比如

let newArr = this.$store.state.arr
newArr[0].name = 'name111'
this.$nextTick(() => {
    this.$store.commit('setArr', newArr)
})

因为此处为浅拷贝,所以其实原数组没有发生改变,只是改变了该数组下面对象的值

此时页面是可以更新渲染的

但由于我的业务场景,需要深拷贝(此处引入lodash辅助函数进行深拷贝),所以代码如下

let newArr = this.$lodash.cloneDeep(this.$store.state.arr)
newArr[0].name = 'name111'
this.$nextTick(() => {
    this.$store.commit('setArr', newArr)
})

也就是说,此时的arr经过赋值已经变成了一个全新的数组

但此时子组件页面渲染无法再发生改变了,请问要如何解决这个问题?

如上述代码,目前:

  • this.$nextTick 是已经使用了的
  • 页面动态渲染引用的值也是直接引用的 this.$store.state.arr

这是我百度到的解决方法,但是我已经是这样的了。
第一种情况下是适用的
但在第二种情况下,页面并没有得到更新进行重新渲染,请问要如何解决这个问题?

我打开vue扩展工具,发现在手动点击了这个按钮之后可以触发页面更新

image.png

可是我在mutation里输入了一句 console.log 的测试方法,输出语句是证实了mutation是被触发了的

但是为什么在扩展工具里手动触发mutation才会引起页面更新?不懂是什么道理

阅读 9.4k
4 个回答

最后自己发现可能是element组件的问题

该问题出在动态加载的表格里面,更改了表格的对象数组,但页面无法及时更新渲染

目前使用比较极端的方式,通过v-if使组件重新渲染加载...

你试下setArr这样写

setArr(state, newArr) {
  state.arr = [...newArr];
  //Vue.set(state, 'arr', newArr); //如果上面代码无效试下这段
},

楼主我有点好奇你的setArr是怎么写的?

let newArr = this.$store.state.arr
newArr[0].name = 'name111'

第一种情况:由于newArr是引用对象,实际上这两行代码就已经完成了对数据的修改。你的setArr里做了什么已经不重要了。
第二种情况:不能更新是因为你使用了deepClone,所以引用对象不再是对应的vuex数据,你没有直接修改到vuex数据。

总结一下:第一种情况不需要调用commit,第二种情况的commit下面这样写

    setArr: function (state, arr) {
        state.arr = arr;
    }
推荐问题