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

时间:2017-11-14 12:28:04

标签: javascript vue.js vuejs2 vuex defineproperty

我使用Vue.jsVuex

我制作一个简单的todolist应用程序。

我使用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

感谢您阅读我的问题。 抱歉不擅长英语。 祝你有愉快的一天!

2 个答案:

答案 0 :(得分:0)

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

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}})
    },
    ...
  }
})

答案 1 :(得分:0)

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

但为什么不直接抓住todo项目并直接更改它的done财产?

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