Vue子组件传值到父组件再传另一子组件,初始加载不生效无控制台报错
问题根因
你的代码有两个核心错误导致渲染异常:
- TodoList.vue 中props类型定义错误
你给todosprop定义的类型是Object,但父组件App.vue传入的是Array类型的数组,类型不匹配会导致prop接收异常。 - TodoList.vue 中转存储的
todosList未监听props更新
你在data初始化时仅将this.todos赋值给todosList一次,后续父组件的todos更新时,data里的todosList不会同步更新,自然不会触发页面重新渲染。
你热修改代码后恢复正常是因为热重载会重新触发组件初始化,此时props里已经有数据了,所以todosList能拿到最新值,刷新后回到初始空值状态,问题就复现了。
修复步骤
第一步:修正TodoList.vue的props类型
// 修改前 props: { todos: Object, filterClass: String }, // 修改后 props: { todos: Array, // 改为数组类型 filterClass: String },
第二步:取消中转存储,直接在模板中使用props的todos
不需要在data里额外定义todosList,直接把模板里的遍历源换成props的todos即可,既减少冗余代码,又能保证props更新时页面同步渲染:
<!-- 模板里修改遍历对象 --> <li class="drop-zone" v-for="(listItem, index) in todos" :class="listItem.complete" :key="listItem.taskID" @drop='onDrop($event, index)' @dragover.prevent @dragenter.prevent>
同时删除data里的todosList定义,对应的方法里用到todosList的地方也全部替换为this.todos即可:
// data中删除todosList的声明 data() { return { // completedTodos: [], // activeTodos: [], }; }, // 拖拽方法同步修改 onDrop (evt, list) { const itemID = evt.dataTransfer.getData('itemID'); const movedData = this.todos[itemID]; this.todos.splice(itemID,1); this.todos.splice(list,0, movedData); },
可选优化:修正TodoCreate的不合理逻辑
不建议在TodoCreate子组件中存储全量的todos数组,后续增删改操作都会出现数据不同步的问题,修改为每次新增时仅传递新的待办项给父组件,由父组件统一维护todos数组:
// TodoCreate.vue的addTodo方法修改 methods: { addTodo() { const val = this.todoval.trim(); if(!val) return; // 加个空值判断 const newTodo = { taskID: this.taskNumber, value: val, complete : 'not-completed'}; this.todoval = ''; this.taskNumber++; this.$emit('addedTodos', newTodo); }, }
// App.vue的updateTodos方法同步修改 updateTodos(newTodo) { this.todos.push(newTodo); console.log(this.todos); },
修改完后刷新页面,新增待办就会正常渲染了。
内容的提问来源于stack exchange,提问作者kandi_galaxy
相关产品推荐
相关产品推荐

