什么是插槽
在Vue.js中,使用<slot>
元素,作为承载内容分发的出口`。即,在模板中开一个口,用于拼接其他模板。
案例
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Slot</title>
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
</head>
<body>
<div id="vueScope">
<main_struct>
<sub_struct slot="slotA" v-bind:title="title"></sub_struct>
<sub_struct2 slot="slotB" v-for="movie in movies" v-bind:item="movie"></sub_struct2>
</main_struct>
</div>
<script>
/*主体模板,在其中打入插槽,并为slot标签的name属性赋值,表明该插槽需要的模板名*/
Vue.component("main_struct",{
template:
"<div>"
+"<slot name='slotA'></slot>"
+"<ul>"
+"<slot name='slotB'></slot>"
+"</ul>"
+"</div>"
});
/*子模板,通过插槽拼接到主模板上*/
Vue.component("sub_struct",{
props: ['title'],
template: "<p>{{title}}</p>"
});
/*子模板,通过插槽拼接到主模板上*/
Vue.component("sub_struct2",{
props: ['item'],
template: "<li>{{item}}</li>"
});
//实例化Vue对象
let vueApp = new Vue({
el: "#vueScope",
data: {
title: "电影名单",
movies:["射雕英雄传","旺角卡门","梅兰芳"]
}
});
</script>
</body>
</html>
【注】:模板的命名,不能使用aB或者a_B的形式,但是可以使用a_b的形式,否则无法识别
自定义事件
现在有个问题:如何利用Vue组件中定义的方法调用Vue对象中定义的方法?
可以通过调用$emit()方法来实现:
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Slot</title>
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
</head>
<body>
<div id="vueScope">
<main_struct>
<sub_struct slot="slotA" v-bind:title="title"></sub_struct>
<sub_struct2 slot="slotB" v-for="(movie,index) in movies" v-bind:item="movie"
v-on:diyevent="removeElements(index)">
</sub_struct2>
</main_struct>
</div>
<script>
/*主体模板,在其中打入插槽,并为slot标签的name属性赋值,表明该插槽需要的模板名*/
Vue.component("main_struct",{
template:
"<div>"
+"<slot name='slotA'></slot>"
+"<ul>"
+"<slot name='slotB'></slot>"
+"</ul>"
+"</div>"
});
/*子模板,通过插槽拼接到主模板上*/
Vue.component("sub_struct",{
props: ['title'],
template: "<p>{{title}}</p>"
});
/*子模板,通过插槽拼接到主模板上*/
Vue.component("sub_struct2",{
props: ['item'], //index用于接收遍历数组的下标
template: "<li>{{item}}<button v-on:click='remove'>删除</button></li>",
methods: {
remove: function(index){
//用于删除对应数组元素,调用组定义方法,index表示需要传递的参数
this.$emit("diyevent",index);
}
}
});
//实例化Vue对象
let vueApp = new Vue({
el: "#vueScope",
data: {
title: "电影名单",
movies:["射雕英雄传","旺角卡门","梅兰芳"]
},
methods: {
removeElements: function(index){
//splice(a,b) 表示从数组下标a开始,删除b个元素
this.movies.splice(index,1);
}
}
});
</script>
</body>
</html>
- 在Vue对象中定义了一个removeElements方法,该方法用于删除movies数组中对应下标的元素。
removeElements: function(index){
//splice(a,b) 表示从数组下标a开始,删除b个元素
this.movies.splice(index,1);
}
- 在Vue.component组件中定义了remove方法,该方法调用了$emit()方法,用于调用自定义事件:
remove: function(index){
//用于删除对应数组元素,调用组定义方法,index表示需要传递的参数
this.$emit("diyevent",index);
}
- 接下来就需要在前端自定义事件:diyevent,通过v-on:xxx指令来实现
<sub_struct2 slot="slotB"
v-for="(movie,index) in movies"
v-bind:item="movie"
v-on:diyevent="removeElements(index)">
</sub_struct2>
流程图大致如下:
这样就实现了Vue组件的方法调用(绑定)Vue对象中的方法。