Vue.js待办列表应用出现task prop意外突变报错如何解决?
报错成因
- Vue遵循单向数据流规则,
props是父组件传递给子组件的只读属性,子组件不允许直接修改传入的props内容。你在子组件中直接通过v-model绑定task.completed修改了传入的taskprop 属性,直接触发了Vue的props修改校验警告。 - 你使用的
task对象本身是Vuex store中state的引用,Vuex规则要求所有state的修改必须通过mutation执行,直接修改state属性也违反了Vuex的状态修改规范。
解决方案
需要遵守Vue单向数据流和Vuex的状态修改规则,通过触发Vuex mutation的方式修改任务完成状态,具体修改步骤如下:
步骤1:给Vuex的task模块添加状态修改方法
首先在task模块的mutations、actions中新增切换任务完成状态的逻辑:
// Vuex task模块代码 const state = { tasks:[{ title: "Wake up", completed: false }, { title: "Item 2", completed: false }, ] } const mutations = { // 新增切换任务完成状态的mutation TOGGLE_TASK_COMPLETED(state, taskIndex) { state.tasks[taskIndex].completed = !state.tasks[taskIndex].completed } } const actions = { // 新增对应action toggleTask({commit}, taskIndex) { commit('TOGGLE_TASK_COMPLETED', taskIndex) } } const getters = { tasks: state => state.tasks }
步骤2:修改子组件Task.vue,禁止直接修改prop
将直接绑定task.completed的v-model拆分为属性绑定+事件触发的形式,点击复选框时触发Vuex的action修改状态:
<template> <q-item clickable :class="!task.completed ? 'bg-orange-1' : 'bg-green-1'" v-ripple> <q-item-section side top> <!-- 拆分v-model为属性绑定+事件回调 --> <q-checkbox :model-value="task.completed" @update:model-value="toggleTask(id)" /> </q-item-section> <q-item-section> <q-item-label :class="{'text-strikethrough' : task.completed}">{{task.title}}</q-item-label> </q-item-section> </q-item> </template> <script> import {mapActions} from 'vuex' export default { props: ["task", "id"], methods: { ...mapActions('task', ['toggleTask']) } } </script>
如果希望继续使用v-model语法,也可以在子组件中定义带get/set的计算属性实现:
// Task.vue的script部分新增计算属性 computed: { taskCompleted: { get() { return this.task.completed }, set() { this.toggleTask(this.id) } } }
模板中就可以直接写:
<q-checkbox v-model="taskCompleted" />
额外提示:原代码中子组件使用了
{{task.name}}渲染任务标题,但Vuex state中定义的任务属性是title,需要同步修改为{{task.title}}避免渲染空白。
内容的提问来源于stack exchange,提问作者Prasanga Thapaliya
相关产品推荐
相关产品推荐

