Vue学习:使用组件改造ToDoList与组件间的传值

本文介绍了如何使用Vue将原本的ToDoList改造为组件化,并详细讲解了组件定义、替换li标签、通过v-bind传值以及组件间的事件通信。通过定义全局和局部组件,实现列表项的动态添加与删除,展示了Vue中组件的复用性和父子组件间的数据传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue学习:使用组件改造ToDoList与组件间的传值

一、原本的ToDoList

每一个li可以当作页面的一个部分,便可以拆开来编写,原本这里是利用v-for循环li标签来显示的,可以将li标签组件化

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="inputValue"/>
            <button v-on:click="handleBtnClick">提交</button>
            <ul>
                <li v-for="item in list">{{item}}</li>
            </ul>
        </div>
    </body>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                list:[],
                inputValue:''
            },
            methods:{
                handleBtnClick:function(){
                    this.list.push(this.inputValue),
                    this.inputValue=''
                }
            }
        })
    </script>
</html>

二、组件化改造ToDoList
2.1 定义全局组件

vue.component定义的是全局组件,组件名称是TodoItem,内容是li标签

        //Vue定义全局组件
        Vue.component("TodoItem",{
            template:"<li>todo item</li>"
        })
2.2 代替li标签

每点一次提交,都会多一次< li >todo item< /li >显示在页面,因为我们定义的组件名称是TodoItem,所以将大写的T和I用t和i代替,但是后面的驼峰都需要接一个-符号

            <ul>
               <!--<li v-for="item in list">{{item}}</li>--> 
               <todo-item v-for="item in list"></todo-item>
            </ul>
2.3 v-bind传值

我们上面2.2中li标签内容只是显示todo item,在相对于我们外层容器div="app"来说,我们定义的组件是子组件,所以需要传递内容给子组件

这里便需要用到v-bind,这里将list每一项内容赋值给item,再把item利用v-bind的形式传递给todo-item组件,利用content来传值,所以需要在组件中去接收,接收父组件传值的需要定义props

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="inputValue"/>
            <button v-on:click="handleBtnClick">提交</button>
            <ul>
               <!--<li v-for="item in list">{{item}}</li>-->
               <!--将list每一项内容赋值给item,再把item利用v-bind的形式传递给todo-item组件,利用content来传-->
               <todo-item v-bind:content="item" v-for="item in list"></todo-item>
            </ul>
        </div>
    </body>
    <script>
        //Vue定义全局组件
        Vue.component("TodoItem",{
            //props代表从父组件接收内容
            props:['content'],
            template:"<li>{{content}}</li>"
        })

        var app = new Vue({
            el:'#app',
            data:{
                list:[],
                inputValue:''
            },
            methods:{
                handleBtnClick:function(){
                    this.list.push(this.inputValue),
                    this.inputValue=''
                }
            }
        })
    </script>
</html>
2.4 局部组件

利用var定义一个对象,这里便是一个局部组件,然后再父组件里面注册

 <!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="inputValue"/>
            <button v-on:click="handleBtnClick">提交</button>
            <ul>
               <!--<li v-for="item in list">{{item}}</li>-->
               <!--将list每一项内容赋值给item,再把item利用v-bind的形式传递给todo-item组件,利用content来传-->
               <todo-item v-bind:content="item" v-for="item in list"></todo-item>
            </ul>
        </div>
    </body>
    <script>
        //定义一个对象,这个就是一个局部组件
        var TodoItem = {
            props:['content'],
            template:"<li>{{content}}</li>"
        }

        var app = new Vue({
            el:'#app',
            //注册局部组件
            components:{
                TodoItem:TodoItem
            },
            data:{
                list:[],
                inputValue:''
            },
            methods:{
                handleBtnClick:function(){
                    this.list.push(this.inputValue),
                    this.inputValue=''
                }
            }
        })
    </script>
</html>

三、组件间的传值
3.1 给子组件的li标签绑定事件,$emit向外触发事件

v-on:click的简写为@click,然后handleItemClick需要写在子组件的methods中,由于数据放在父组件中,利用$emit向外触发事件,父组件创建子组件的时候监听delete事件

		var TodoItem = {
            props:['content','index'],
            template:"<li @click='handleItemClick'>{{content}}</li>",
            methods:{
                handleItemClick:function(){
                    this.$emit("delete",this.index);
                }
            }
        }
		    <ul>
                    <todo-item v-bind:content="item" 
                          v-for="item in list"
                          @delete="handleItemDelete">
                    </todo-item>
            </ul>
        var app = new Vue({
            el:'#app',
            //注册局部组件
            components:{
                TodoItem:TodoItem
            },
            data:{
                list:[],
                inputValue:''
            },
            methods:{
                handleBtnClick:function(){
                    this.list.push(this.inputValue),
                    this.inputValue=''
                },
                handleItemDelete:function(index){
 					//父组件监听的delete事件
                }
            }
        })
3.2 父组件handleItemDelete改变list

向子组件传递下标,利用v-bind传递值给子组件

            <ul>
                    <todo-item v-bind:content="item"
                          v-bind:index="index"  
                          v-for="(item,index) in list"
                          @delete="handleItemDelete">
                    </todo-item>
            </ul>

子组件接收下标,$emit也传递index参数给父组件

        var TodoItem = {
            props:['content','index'],
            template:"<li @click='handleItemClick'>{{content}}</li>",
            methods:{
                handleItemClick:function(){
                    this.$emit("delete",this.index);
                }
            }
        }

在handleItemDelete进行处理,splice进行删除list里面的数据

        var app = new Vue({
            el:'#app',
            //注册局部组件
            components:{
                TodoItem:TodoItem
            },
            data:{
                list:[],
                inputValue:''
            },
            methods:{
                handleBtnClick:function(){
                    this.list.push(this.inputValue),
                    this.inputValue=''
                },
                handleItemDelete:function(index){
                    this.list.splice(index,1)
                }
            }
        })
3.3 完整代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="inputValue"/>
            <button v-on:click="handleBtnClick">提交</button>
            <ul>
                    <todo-item v-bind:content="item"
                          v-bind:index="index"  
                          v-for="(item,index) in list"
                          @delete="handleItemDelete">
                    </todo-item>
            </ul>
        </div>
    </body>
    <script>
        //定义一个对象,这个就是一个局部组件
        var TodoItem = {
            props:['content','index'],
            template:"<li @click='handleItemClick'>{{content}}</li>",
            methods:{
                handleItemClick:function(){
                    this.$emit("delete",this.index);
                }
            }
        }

        var app = new Vue({
            el:'#app',
            //注册局部组件
            components:{
                TodoItem:TodoItem
            },
            data:{
                list:[],
                inputValue:''
            },
            methods:{
                handleBtnClick:function(){
                    this.list.push(this.inputValue),
                    this.inputValue=''
                },
                handleItemDelete:function(index){
                    this.list.splice(index,1)
                }
            }
        })
    </script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值