TodoList 使用组件标记_ ref _处理父子孙数据交互问题
1.父组件
<template>
<div class="todo-container">
<div class="todo-wrap">
<MyList :todos="todos" ref="myList" />
</div>
</div>
</template>
<script>
import MyList from './components/MyList';
export default {
name:'App',
components:{MyHeader,MyList,MyFooter},
data(){
return {
todos:JSON.parse( localStorage.getItem('todos')) || [],
}
},
methods:{
checkTodo(tid){
this.todos.forEach((todo)=>{
if(todo.tid==tid) todo.done= !todo.done;
})
},
deleteTodo(tid){
this.todos = this.todos.filter( todo => todo.tid != tid )
},
},
watch:{
todos:{
deep:true,
handler(todo){
localStorage.setItem('todos',JSON.stringify(todo))
}
}
},
mounted(){
// 通过父组件中的$refs属性可以获取所有的子孙组件,可以通过给子孙设置ref,逐级寻找。(list!=[])
if (this.$refs.myList.$refs.myItem) this.$refs.myList.$refs.myItem.forEach(item=>{item.$on('checkTodo',this.checkTodo)});
if (this.$refs.myList.$refs.myItem) this.$refs.myList.$refs.myItem.forEach(item=>{item.$on('deleteTodo',this.deleteTodo)});
},
updated(){
// list == [] ++
if (this.$refs.myList.$refs.myItem) this.$refs.myList.$refs.myItem.forEach(item=>{item.$on('checkTodo',this.checkTodo)});
if (this.$refs.myList.$refs.myItem) this.$refs.myList.$refs.myItem.forEach(item=>{item.$on('deleteTodo',this.deleteTodo)});
}
}
</script>
2.子组件
<template>
<ul class="todo-main">
<MyItem
v-for="todo in todos"
:key="todo.tid"
:todo="todo"
ref="myItem"
/>
</ul>
</template>
<script>
import MyItem from './MyItem'
export default {
name:'MyList',
components:{MyItem},
props:['todos']
}
</script>
3.孙组件
<template>
<li>
<label>
<input type="checkbox" :checked="todo.done" @change="updateDone(todo.tid)"/>
<span>{{todo.title}}</span>
</label>
<button class="btn btn-danger" @click="removeTodo(todo.tid)">删除</button>
</li>
</template>
<script>
export default {
name:'MyItem',
props:['todo'],
methods:{
updateDone(tid){
this.$emit('checkTodo',tid);
},
removeTodo(tid){
// this.$emit('event',params)
if(confirm('你确定要删除么?')) this.$emit('deleteTodo',tid);
}
}
}
</script>