Vuex getter 用于过滤器在改变状态数组后不更新

Vuex getter for filter not updating after mutating array of state

我正在构建一个待办事项应用程序。有一个按钮可以切换所有待办事项的 checked/completed 状态。我正在改变 state 的数组,但 getters 没有更新。当我单击 toggle complete 按钮时,数据库和数组 state.todos 更新,但 $store.getters.filteredTodos 没有更新。

所以有些待办事项显示不正确(有些被选中,有些则没有,而所有这些都应该被选中或取消选中)

    // in getters
    filteredTodos(state) {
        if (state.filter == 'active') {
            return state.todos.filter(todo => !todo.completed);
        }

        if (state.filter == 'completed') {
            return state.todos.filter(todo => todo.completed);
        }

        return state.todos;
    },

    // in mutations
    retrieveTodos(state, todos) {
        Vue.set(state, 'todos', todos);

        // tried the following, but also didn't work
        //state.todos.splice(0, state.todos.length, ...todos);
    },

    // in actions
    toggleCompleted(context, completed) {
        axios.patch('/todos/toggle-completed', {completed})
            // response.data is the array of the updated todo items
            .then(response => context.commit('retrieveTodos', response.data))
            .catch(e => console.log(e));
    },

从 Whosebug 和 VueForum 的几篇帖子中,我看到了相同的解决方案:

        Vue.set(state, 'todos', todos);
        // or
        state.todos.splice(0, state.todos.length, ...todos);

None 他们成功了。 $store.state 更新,但 $store.getters.filteredTodos 不更新。

如何解决?

更新

我正在关注 this tutorial series on YouTube 以开始使用 Vue,但我正在自己做一些事情。在本教程中,该人员为前端创建了 Vue 项目,为后端创建了 Laravel 项目。我也是这样做的。

我发现问题与gettersstate无关。两者都以我尝试过的三种方式正确更新。

问题出在 Todo 组件中。以前,代码是这样的:

// in the template 
        <label class="todo-action" :for="`todo-checked-${id}`">
            <input type="checkbox" v-model="completed" 
                   :id="`todo-checked-${id}`" @change="update">
        </label>

        <div class="todo-title">
            {{title}}
        </div>

// inside script tag
    data() {
        // this allow me to access this.id, this.completed, and this.title 
        // instead of this.todo.id, this.todo.completed, and this.todo.title
        return this.todo;
    },

问题是 data 没有更新。我按如下方式修复它

// in the template I access the props from the todo item, so it is always up to date
        <label class="todo-action" :for="`todo-checked-${todo.id}`">
            <input type="checkbox" v-model="todo.completed" 
                   :id="`todo-checked-${todo.id}`" @change="update">
        </label>

        <div class="todo-title">
            {{todo.title}}
        </div>

是的,这是一个非常简单的解决方案