学习目标:
Vue中插槽的使用
学习内容:
1、 插槽
2、自定义分发事件
学习时间:
学习产出:
七、内容分发Slot
1、插槽Slot:
-
介绍: Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 元素作为承载分发内容的出口。
-
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>内容分发Slot(插槽)</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.2/dist/vue.min.js"></script>
</head>
<body>
<!--View层-->
<!--内容分发-->
<div id="app">
<!--父插槽todo,下面有两个子插槽todo-title、todo-items-->
<todo>
<!--插槽todo-tilte,绑定组件中的参数name,取出数据title赋给参数name-->
<todo-title slot="todo-title" v-bind:name="title"></todo-title>
<!--插槽todo-items,遍历取出todoItems中的数据item,然后绑定参数item,将取出的item数据赋给参数item,在组件中的template显示出来-->
<todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item"></todo-items>
</todo>
</div>
<script>
/*ViewModel层*/
/*定义插槽todo,必须要写在前面,不然出不来数据*/
/*父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。*/
Vue.component("todo", {
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
/*定义组件:插槽todo-title*/
Vue.component("todo-title", {
/*参数*/
props: ['name'],
/*模板*/
template: '<div>{{name}}</div>'
});
/*定义组件:插槽todo-items*/
Vue.component("todo-items", {
props: ['item'],
template: '<li>{{item}}</li>'
});
/*Model层*/
var vm = new Vue({
el: "#app",
data: {
title: "CS系列",
todoItems: ['Java', "Linux", "数据库"]
}
});
</script>
</body>
</html>
2、自定义分发事件
- 通过自定义分发事件使View层可以通过双向绑定(View层通过ViewModel层访问(假定)Model层数据)操作实现删除数据等操作,
即使用this.$emit (‘自定义事件名’,参数)
- 前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>内容分发Slot(插槽)</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.2/dist/vue.min.js"></script>
</head>
<body>
<!--自定义内容分发-->
<div id="app2">
<todo1>
<todo1-title slot="todo1-title" :name="title1"></todo1-title>
<!--v-bind绑定了VM层的remove方法,参数就是Model层定义的removeItems方法,只要点击了模板中定义的删除就会触发模板定义的remove方法
从而做到了让model删除元素-->
<todo1-items slot="todo1-items" v-for="(item1,index1) in todoItems1" :items="item1"
:index="index1" @remove="removeItems(index1)">删除</todo1-items>
</todo1>
</div>
<script>
Vue.component("todo1", {
template: '<div>\
<slot name="todo1-title"></slot>\
<ul>\
<slot name="todo1-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo1-title",{
props:['name'],
template:'<div>{{name}}</div>'
});
Vue.component("todo1-items",{
props:['items','index'],
template:'<li>{{index}}----{{items}} <button @click="remove">删除</button> </li>',
methods:{
remove:function (index){
/*this.$emit:自定义事件分发*/
this.$emit('remove',index)
}
}
})
var vm = new Vue({
el: "#app2",
data: {
title1: "计算机",
todoItems1: ['Java', 'C语言', 'Python']
},
methods:{
/*定义一个removeItems方法并传入data中todoItems1中数据的下标*/
removeItems:function (index){
console.log("删除了"+this.todoItems1[index]+"OK");
/*splice(index,1):从index处开始删除1个元素*/
this.todoItems1.splice(index,1)
}
}
});
</script>
</body>
</html>