45TodoList 使用组件标记_ ref _处理父子孙数据交互问题

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>
posted @ 2022-09-16 16:44  Redskaber  阅读(32)  评论(0)    收藏  举报