Vue 中组件概念
1 为了能在模板中使用,组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。
1.1 全局注册是通过Vue.component
来向Vue注册,例子
Vue.component('my-component-name', { // ... options ... })
全局注册的组件可以用在其被注册之后的任何 (通过 new Vue
) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
1.2 局部注册,先声名一个局部组件,在 js 文件中直接用变量接收对象
var comp = { template:'<li></li>' }
在根实例中使用 components 属性引入局部组件。
new Vue({ ... components:['comp'] ... })
引入局部组件后就可以在模板中使用子组件了。
2 父组件向子组件传递数据方法,通过 Prop 向子组件传递数据,父组件数据通过绑定子组件的属性向子组件传递数据,在子组件的模板中就可以使用该属性。即成为了子组件的数据属性。
Prop 是你可以在组件上注册的一些自定义属性。当一个值传递给一个 prop 属性的时候,它就变成了那个组件实例的一个属性。例子如下:
2.1 定义一个子组件
Vue.component('list-item',{ template:"<li>{{content}}</li>", props:['content'] });
props 表明子组件接受父组件通过 content 属性传递过来的数据。
此时子组件的 template 就可以使用 props 中声名的属性了。该属性也是子组件的数据属性。
2.2 在父组件的模板中使用声名的组件。
<ul> <list-item v-for="(item,index) of listItems" :key="index" :content="item"></list-item> </ul>
将父组件中的 item 数据绑定到子组件的 content 属性上。
至此就完成了父组件向子组件传递数据的功能。
完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo2</title> <script type="text/javascript" src="../static/vue/vue.js"></script> </head> <body> <div id="root"> <input v-model="inputValue"> <button @click="addItem">点我提交</button> <ul> <list-item v-for="(item,index) of listItems" :key="index" :content="item"></list-item> </ul> </div> </body> <script type="text/javascript"> Vue.component('list-item',{ template:"<li>{{content}}</li>", props:['content'] }); new Vue({ el:"#root", data:{ inputValue:'', listItems:[] }, methods:{ addItem: function () { this.listItems.push(this.inputValue); this.inputValue = ''; } } }) </script> </html>
3 通过事件向父组件发送消息
3.1 子组件触发父组件的一个事件,我们可以调用内建的 $emit
方法并传入事件的名字,来向父级组件触发一个事件。例如:单击按钮,向父组件发送‘enlarge-text’事件。
<button v-on:click="$emit('enlarge-text')"> Enlarge text </button>
3.1.2 通过函数第二个参数向父组件传递参数
<button v-on:click="$emit('enlarge-text', 0.1)"> Enlarge text </button>
然后当在父级组件监听这个事件的时候,我们可以通过 $event
访问到被抛出的这个值:
<blog-post ... v-on:enlarge-text="postFontSize += $event" ></blog-post>
解释二:
通过第二小节可以将父组件的数据传递到子组件中。现在想让父组件接受子组件的数据如何做的呢?通过发布订阅模式。主要函数 $emit 抛出一个事件
例子:单击子组件删除对应的子组件。
3.2.1 绑定子组件单击事件,并向父组件抛出事件和数据。
Vue.component('list-item',{ template:"<li @click='handleClick'>{{content}}</li>", props:['content','index'], methods:{ handleClick:function () { this.$emit('delete',this.index); } } });
当单击子组件时,绑定的是handleClick 方法,首先在子组件中使用该方法处理。处理函数通过 $emit 方法抛出 delete 事件(自定义事件) 和 index 数据。
3.2.2 父组件中监听子组件的自定义的 delete 事件,并绑定处理函数。
<list-item v-for="(item, index) of listItems" :key="index" :content="item" :index="index" @delete="handleDelete" > </list-item>
当父组件监听到子组件的 delete 事件后,使用 handleDelete 方法进行处理:删除对应组件。即将 listItems 中的对应数据删除掉,页面上就会对应删除。
new Vue({ el: "#root", data: { inputValue:'', listItems: [] }, methods: { addItem: function () { this.listItems.push(this.inputValue); this.inputValue=''; }, handleDelete: function (index) { alert(index); this.listItems.splice(index,1); } } })
完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo3</title> <script type="text/javascript" src="../static/vue/vue.js"></script> </head> <body> <div id="root"> <input v-model="inputValue"> <button @click="addItem">添加</button> <ul> <!--<li v-for="(item, index) of listItems" :key="index">{{item}}</li>--> <list-item v-for="(item, index) of listItems" :key="index" :content="item" :index="index" @delete="handleDelete" > </list-item> </ul> </div> </body> <script type="text/javascript"> Vue.component('list-item',{ template:"<li @click='handleClick'>{{content}}</li>", props:['content','index'], methods:{ handleClick:function () { this.$emit('delete',this.index); } } }); new Vue({ el: "#root", data: { inputValue:'', listItems: [] }, methods: { addItem: function () { this.listItems.push(this.inputValue); this.inputValue=''; }, handleDelete: function (index) { alert(index); this.listItems.splice(index,1); } } }) </script> </html>
如果觉得有用,想赞助一下请移步赞助页面:赞助一下