Vue/Vuex > 使用 Object.defineProperty() 方法时无法跟踪状态更改

Vue/Vuex > Cannot track state changed when I use Object.defineProperty() method

我使用 Vue.jsVuex

我制作了一个简单的待办事项应用程序。

我用 Vuex 使用 Object.defineProperty() 方法制作了一个完成切换按钮。

当我单击完成切换按钮时,VueVuex 无法立即跟踪更改。

它只在我重新分配 属性 的值时跟踪变化。

例如

这个有效:

Vuex.Store({
    state: {
        todolist: [
            { todo: 'test1', done: false },
            { todo: 'test2', done: true },
            { todo: 'test3', done: false },
            { todo: 'test4', done: false }
        ]
    },
    mutations: {
        ...
        [Constant.DONE_TOGGLE]: (state, payload) => {
            const changeState = state;
            changeState.todolist[payload.index].done = !state.todolist[payload.index].done;
        },
        ...
    }
});

但这不起作用!

Vuex.Store({
    state: {
        todolist: [
            { todo: 'test1', done: false },
            { todo: 'test2', done: true },
            { todo: 'test3', done: false },
            { todo: 'test4', done: false }
        ]
    },
    mutations: {
        ...
        [Constant.DONE_TOGGLE]: (state, payload) => {
            Object.defineProperty(state.todolist[payload.index], 'done', { value: !state.todolist[payload.index].done });
        },
        ...
    }
});

下面的代码跟踪完成切换的更改,仅其他突变更改状态。

为什么会这样?

这是我的 github repository link.

我的应用在 /EX11/todolistapp.

我的 Vuex 文件在 /EX11/todolistapp/src/store/index.js

感谢阅读我的问题。 抱歉英语不好。 祝你有美好的一天!

我不确定...这是您想要实现的目标吗?

Vuex.Store({
  state: {
    todolist: [
      { todo: 'test1', done: false },
      { todo: 'test2', done: true },
      { todo: 'test3', done: false },
      { todo: 'test4', done: false }
    ]
  },
  mutations: {
    ...
    [Constant.DONE_TOGGLE]: (state, payload) => {
      var val = !state.todolist[payload.index].done
      state.todolist[payload.index] = Object.assign(state.todolist[payload.index], {done: {value: val}})
    },
    ...
  }
})

这是由于 Javascript 的限制 -- Vue cannot detect changes 通过索引完成时对数组元素的限制。

但为什么不抓住待办事项并直接更改它的 done 属性?

var item = state.todolist[payload.index];
item.done = !item.done;