美文网首页
四、实现todolist的删除功能(知识点:子组件向父组件传值)

四、实现todolist的删除功能(知识点:子组件向父组件传值)

作者: 李浩然_6fd1 | 来源:发表于2019-02-13 15:35 被阅读0次

    依然利用沿用上次的例子(去掉了component组件中的点击事件,出现"clicked"弹窗的方法):

    <body>
        <div id="root">
            <div>
                <input v-model="inputValue" />
                <button @click="handleSubmit">提交</button>
            </div>
            <ul>
                <todo-item
                v-for="(item, index) of list"
                :key="index"
                :content="item"
                >
                </todo-item>
            </ul>
        </div>
        
        <script>
            Vue.component('todo-item',{
                props:['content'],
                template:'<li @click="handleClick">{{content}}</li>',
            })
            new Vue({
                el:"#root",
                data:{
                    inputValue:'hello',
                    list:[]
                },
                methods:{
                    handleSubmit:function(){
                        this.list.push(this.inputValue)
                        this.inputValue =''
                    }
                }
            })
        </script>
    </body>
    

    现在要实现一个需求:点击li标签的数据,数据可以被删除。
    分析一下这个需求:li标签是在子组件中创建的,但是li标签内的数据是来自父组件,如果要删除子组件的这个数据,肯定要删除父组件中对应的数据。
    在Vue中,实现子组件和父组件之间的通讯,需要一个发布订阅模式来处理。

    在处理这个需求之前,还需要一个参数,是当前子组件在list中的下标。在ul中,父组件循环显示子组件的时候,额外再带一个参数index,这个参数等于循环显示的下标index(即“:index='index'”),然后再component组件中的props内增加这个index(即:“props:['content','index']”),让子组件接收父组件中的content属性的同时,接收index属性,
    尝试下能不能接收到index属性,component中的template模板增加一个插值表达式{{index}},template的模板即写成:

    template:'<li @click="handleClick">{{content}}{{index}}</li>',
    

    结果是:


    图片.png

    可以看到子组件成功接收了list下标。现在删除template中的{{index}}。
    在需求中,可以看到是点击li标签,然后会删除li标签的内容。
    这样其实是在点击li标签的时候,触发了是一个事件,这个事件将删除li标签的内容。
    但是li标签是在子组件中创建的,list的内容是是在父组件中创建的,如何将删除li标签的删除传达到父组件中,将是这节的重点。
    点击li标签将触发事件,这个事件的方法删除父组件中的数据。直接删除是不可能的,因为无法通信。
    答案是通过订阅模式,子组件创建一个自定义的事件,在模板中绑定delete事件和一个新的方法(handleDelete,方法将删除数据),当触发这个方法的时候,模板中会监听到这个事件的触发,然后handleDelete事件将起作用,然后删除数据。
    下面是代码的具体表现:

    <body>
        <div id="root">
            <div>
                <input v-model="inputValue" />
                <button @click="handleSubmit">提交</button>
            </div>
            <ul>
                <todo-item
                v-for="(item, index) of list"
                :key="index"
                :content="item"
                :index="index"
                @delete="handleDelete"
                >
                </todo-item>
            </ul>
        </div>
        
        <script>
            Vue.component('todo-item',{
                props:['content','index'],
                template:'<li @click="handleClick">{{content}}</li>',
                methods:{
                    handleClick:function(){
                        this.$emit('delete',this.index)
                    }
                }
            })
            new Vue({
                el:"#root",
                data:{
                    inputValue:'hello',
                    list:[]
                },
                methods:{
                    handleSubmit:function(){
                        this.list.push(this.inputValue)
                        this.inputValue =''
                    },
                    handleDelete: function(index) {
                        this.list.splice(index, 1)
                    }
                }
            })
        </script>
    </body>
    

    当点击li标签的时候,会触发handleClick方法,这个方法向外释放了一个名为delete的事件,这个事件对应的值是触发的内容的下标签。
    因为在父标签中订阅了delete事件(@delete="handleDelete"),当触发的时候,就会执行handleDelete方法(handleDelete方法是父组件还是子组件的?是父组件的,因为它写在父组件对应的模板中),这个方法将删除所点击的内容(function括号内的index参数是接收的参数,将指导下标对应的什么数据内容)

    相关文章

      网友评论

          本文标题:四、实现todolist的删除功能(知识点:子组件向父组件传值)

          本文链接:https://www.haomeiwen.com/subject/magssqtx.html