文章目录
Vue(07)——slot插槽和自定义事件1、slot插槽2、自定义事件Vue(07)——slot插槽和自定义事件
1、slot插槽
什么是插槽
Vue 实现了一套内容分发的 API,将<slot>
元素作为承载分发内容的出口,称为插槽。
插槽实质是对子组件的扩展,通过<slot>
插槽向组件内部指定位置传递内容。
插槽的使用
准备一个待办事项(todo),该组件由待办事项(todo-title)和待办内容(todo-items)组成,下面就把todo-title和todo-items插入todo中:
<!DOCTYPE html ><html lang="en" xmlns:v-bind="/1999/xhtml"><head><meta charset="UTF-8"><title>计算属性</title></head><body><script src="/npm/vue@2.5.21/dist/vue.min.js"></script><div id="app"><todo><!-- :是v-bind:的缩写--><todo-title slot="todo-title" :title="title"></todo-title><!--从todoItems循环遍历出的每个值为item,然后props里的item接收到item,再把数据显示到模板上,最后再插入slot--><todo-items slot="todo-items" v-for="item in todoItems" :item="item"></todo-items></todo></div><script>//父组件,插槽,把其他组件的内容添加到里面ponent("todo",{//插槽通过name属性绑定组件template: '<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});//子组件ponent("todo-title",{props: ['title'],template: '<div>{{title}}</div>'});//子组件ponent("todo-items",{props: ['item'],template: '<li>{{item}}</li>'});var vm = new Vue({el: '#app',data: {title: "技术栈",todoItems: ['Java','Python','Linux']}});</script></body></html>
到这里,我们就实现了将todo-title子组件和todo-items子组件分发到todo(父组件)的插槽中。
2、自定义事件
在上面例子中,子组件使用props接收父组件传递的数据,但如果子组件要把数据传递回去,就需要使用自定义事件!
我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:
使用$on(eventName)
监听事件使用$emit(eventName)
触发事件
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
<!DOCTYPE html ><html lang="en" xmlns:v-bind="/1999/xhtml"><head><meta charset="UTF-8"><title>自定义事件</title></head><body><script src="/npm/vue@2.5.21/dist/vue.min.js"></script><div id="app"><todo><!-- :是v-bind:的缩写--><todo-title slot="todo-title" :title="title"></todo-title><!--遍历出数组的数据以及下标--><todo-items slot="todo-items" v-for="(item,index) in todoItems":item="item" :index="index" @remove1="removeItem(index)" :key="index"></todo-items><!--自定义事件绑定vue实例中的removeItem方法--></todo></div><script>//插槽,把其他组件的内容添加到里面ponent("todo",{//插槽通过name属性绑定组件template: '<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});ponent("todo-title",{props: ['title'],template: '<div>{{title}}</div>'});ponent("todo-items",{props: ['item','index'],// @是v-on的缩写 index 数组下标template: '<li>{{index}}---{{item}} <button @click="remove2">删除</button></li>',methods: {remove2: function (index){//$emit(自定义事件的名称,自定义事件处理程序需要的参数)this.$emit('remove1',index);//触发自定义事件}}});var vm = new Vue({el: '#app',data: {title: "技术栈",todoItems: ['Java','Python','Linux']},methods: {removeItem: function (index){//根据数组下标删除元素console.log("删除"+this.todoItems[index]+" OK")this.todoItems.splice(index,1)//从下标为index开始删除,一次删除一个元素}}});</script></body></html>