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

mac2024-04-10  33

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>
最新回复(0)