目的
-
Vue文档中解释: 这是Vue实现了
一套内容分发的API
,<slot> 元素作为承载分发内容的出口
-
我理解是: 插槽机制完成了由父组件制定子组件内容的又一种方式
(也可以通过传递props来制定)
,而slot
用来指定父组件传递的内容应该放在何处 -
两个机制相比:
props通过传递参数,子组件内部需要提前定义好内容生成的逻辑,接到对应参数后,由子组件内部来根据参数生成内容;
而slot直接传递需要展示的内容, 子组件只负责管理内容的具体展示位置; - 应用场景: 根据之前的对比,可以看出,两者都是由父组件指定子组件内容的方式,区别是:
使用slot时:子组件并不需要知道具体内容是什么
使用props时: 具体的内容是由子组件提前定义好的
因此,slot适用于灵活且没有限制的自定义内容,如element-ui中的自定义表格内容
使用
基本用法
使用slot
时首先捋清父子组件与传递内容的关系 :
- 父组件中指定传递的内容
放在子组件标签之间
- 子组件使用
<slot></slot>
来指定接受的内容放在何处
-
简单的demo :
编译作用域
-
Vue文档:
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的
- 即是说: 写在父组件(app)中的变量或方法引用都只能引用
父组件(app)中存在的数据
,即使该变量会以插槽的方式出现在子组件(test-comp)的内部
<div id="app">
<test-comp>
<p >{{this_data}}</p>
<p>{{sub_data}}</p> // 该数据为子组件数据,访问不到,控制台会报错
</test-comp>
</div>
<template id="test">
<div>
<slot></slot>
<p>p in sub</p>
</div>
</template>
Vue.component('test-comp',{
template: '#test',
data () {
return {
sub_data: 'data store in sub_com'
}
}
})
new Vue({
el: "#app",
data: {
this_data: 'data store in root'
}
})
上面这个例子会出现报错,原因是sub_data
是写在父组件模板上的数据引用,因此不可能访问到子组件中定义的数据sub_data
插槽后备内容
- 不赘述,可类比video标签的替换内容
<video>video is not aviailable in your browser ... </video>
指定对应的具名插槽
- 当出现多个需要分发的内容时,可以为插槽命名,并在子组件中根据不同的名称进行分开管理
- 使用
<template v-slot:xxx />
来指定我是<slot name="xxx">
插槽的内容
插槽 Prop
- 上面的引用方式无法访问到子组件中的数据,这对于一些需要父子组件数据交互来定义模板的情况来说会很不适用,Vue通过为插槽提供Prop的方式解决了这个问题
- 虽然该特性被称为 prop,但是相对于我们通常使用的用来给子组件传参的 prop 还是很有区别的 :
-
prop
提供了一个父组件传参给子组件的方式, - 而
插槽prop
则可以让父组件中的插槽访问子组件的数据(可以理解为子组件向父组件传参,但只传递到了slot内部)
-
<div id="app"> // 父组件
<sub-comp>
<template v-slot:default="DataFromSub"> // 将传递的参数接收并重命名
{{DataFromSub.data}} // 展示子组件传递的数据
<br>
{{DataFromSub.user}}
</template>
</sub-comp>
</div>
<template id="sub"> // 子组件
<section id="sub_comp">
<p>this is sub_component</p>
<slot :data="subData" :user="user"></slot> // 向slot中的内容传递参数
</section>
</template>
Vue.component('sub-comp', { // 子组件
template:'#sub',
data() {
return {
subData: 'sub_data',
user: 'admin'
}
}
})
var vm = new Vue({ // 父组件
el : "#app"
})