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 项目。我也是这样做的。
我发现问题与getters
或state
无关。两者都以我尝试过的三种方式正确更新。
问题出在 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>
是的,这是一个非常简单的解决方案
我正在构建一个待办事项应用程序。有一个按钮可以切换所有待办事项的 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 项目。我也是这样做的。
我发现问题与getters
或state
无关。两者都以我尝试过的三种方式正确更新。
问题出在 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>
是的,这是一个非常简单的解决方案