前言:之前学VUE对插槽只有一个模糊的存值概念,最近在封装自定义组件时,再次学习一下。
通过slot插槽向组件内部指定位置传递内容,通过slot可以父子传参,简化了进行自定义组件的封装和使用。
自己对插槽理解
就是一个站位HTML模板,用来携带内容,插入到合适的位置,由父组件来决定其显示的内容,使得模块具有更强的复用性。
单个slot (默认插槽 或 匿名插槽)
就是没有名字的插槽,一个组件里面只允许存在一个匿名插槽。
父组件内容
<div class="fa">
<h1>父组件</h1>
<child>
<p>父组件中写的文本</p>
</child>
</div>
子组件内容
- 父组件如果要在子组件中插入内容,子组件中必须存在slot 标签
<div class="child">
<h2>子组件</h2>
<slot>匿名插槽的默认内容</slot>
</div>
编译结果如下:
- child组件slot里的内容会替换成 p标签里面的内容,如果父组件没有在子组件插入内容则会渲染slot里面的默认内容。
<div class="fa">
<div class="child">
<h2>子组件</h2>
<p>父组件中写的文本</p>
</div>
</div>
具名slot
slot 元素有一个name特性,可以为slot命名,多个 slot 可以有不同的名字,用来渲染不同的内容。
父组件内容
<div class="fa">
<h1>父组件</h1>
<child>
<div class="son" slot="s1">
<span>111</span>
</div>
<div class="son" slot="s2">
<span>222</span>
</div>
<-- 以下是多余的内容,将会自动填充到匿名插槽中-->
<div class="son">
<span>333</span>
</div>
</child>
</div>
子组件内容
<div class="child">
<h2>子组件</h2>
// s1插槽
<slot name="s1"></slot>
// s2插槽
<slot name="s2"></slot>
// 匿名插槽
<slot></slot>
</div>
编译结果如下:
- 父组件插入在子组件中的内容如果没有加入slot特性,则自动填充到子组件的匿名插槽中。
<div class="fa">
<h1>父组件</h1>
<div class="child">
<h2>子组件</h2>
<div class="son">
<span>111</span>
</div>
<div class="son">
<span>222</span>
</div>
<div class="son">
<span>333</span>
</div>
</div>
</div>
具名插槽的缩写方式
- 以#号形式加上插槽名称
<div class="fa">
<h1>父组件</h1>
<child>
<div class="son" #s1>
...
</div>
</child>
</div>
作用域插槽
在父组件中渲染子组件的内容,并且将子组件数据传递到插槽中
父组件内容
- 在向具名插槽提供内容的时候,可以在 template 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
<div class="fa">
<h1>父组件</h1>
<child >
<template v-slot="props">
{{props.item}}
</template>
</child>
</div>
注意点1:在Vue 2.6+中,如果只存在默认插槽,可以用以上简写法 ,否则必须完整书写: v-slot:default=“props”
注意点2:在Vue 2.6+ 引入了v-slot 指令,在接下来所有的 2.x 版本中 slot 和 slot-scope 还可以使用,但不会出现在 Vue 3.0 中,详细的内容自己查阅官方文档吧。
子组件内容
<template>
<div class="child">
<h2>子组件</h2>
<ul>
<li v-for="item of arr" >
<slot :item="item"></slot>
</li>
</ul>
</div>
<template/>
<scirpt>
data(){
return {
arr:[111, 222, 333]
}
}
<scirpt/>
编译结果如下:
<div class="fa">
<h1>父组件</h1>
<div class="child">
<h2>子组件</h2>
<ul>
<li >111</li>
<li >222</li>
<li >333</li>
</ul>
</div>
</div>
动态插槽名
动态指令参数
从 Vue2.6 开始,新增了动态指令参数,利用 [ ],如下例子:
<img v-bind:[attributeName]="url" />
data(){
return {
attributeName : 'src'
}
}
以上代码在模板中相当于:
还可以用于 v-on 绑定动态事件、a标签 的连接等。
<img :src="url" />
动态插槽名的写法:
<child>
<template v-slot:[slotName]>
...
</template>
</child>
注意点
- 默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:
- Vue 2.6+引入了插槽名,不建议在元素上写名字 ,最好就在template写,规范一下 。
<child >
<template v-slot:default="props">
{{props.item}}
</template>
<template v-slot:s1="props">
{{props.item}}
</template>
</child>
<-- ----------------------------------------两种写法,不可混用 -->
<child >
<template #default="props">
{{props.item}}
</template>
<template #s1="props">
{{props.item}}
</template>
</child>
结束语
利用好插槽,可以提高代码复用性。现在了解的只是很浅的东西,觉得不会的东西是越来越多了,哎呀,加油啦~