Vue

【vue】插槽

12-24 11:04

插槽是什么

插槽(slot)是 Vue 为组件的封装者提供的能力,允许开发者在封装组件时,把“不确定的、希望由用户指定的部分”定义为插槽。


体验插槽基本用法

定义插槽:在封装组件时,可以通过 <slot> 元素定义插槽,从而为用户预留内容占位符,通过案例说明,比如:在 SlotMain  中使用 SlotA 的插槽。

1、在 SlotA.vue  中定义插槽:

<template>

<p>SlotA组件第一个标签</p>

<!-- 通过 slot 标签,为用户预留内容占位符(插槽),组件使用者可在此插入自定义内容 -->

<slot></slot>

<p>SlotA组件最后一个标签</p>

</template>

<script>

export default {

name: 'SlotA',

}

</script>

2、在 SlotMain.vue 中使用插槽:引入 SlotA 组件,使用其中的插槽

<template>

<!-- 在使用 SlotOne 组件时,为插槽指定具体的内容 -->

<SlotA>

<p>插槽数据</p>

</SlotA>

</template>

<script>

import SlotA from 'SlotA.vue'

export default {

name: 'SlotMain',

components: {

SlotA

}

}

</script>


没有预留插槽的内容会被丢弃

如果在封装组件时,没有预留任何 <slot> 插槽,则用户提供的任何自定义内容都会被丢弃。

<template>

<p>SlotA 组件第一个标签</p>

<!-- 封装组件时,没有预留任何插槽 -->

<p>SlotA 组件最后一个标签</p>

</template>

使用插槽:

<template>

<SlotA>

<!-- 自定义的内容会被丢弃-->

<p>插槽数据</p>

</SlotA>

</template>


插槽后备内容

封装组件时,可以为预留的 <slot> 插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。


具名插槽

如果在封装组件时需要预留多个插槽节点,则需要为每个 <slot> 插槽指定具体的 name 名称。这种带有具体名称的插槽叫做“具名插槽”。


为具名插槽提供内容

引入含有具名插槽的组件后,向具名插槽提供内容时,可以在一个 <template> 元素上使用 v-slot 命令,并以 v-slot 的参数的形式提供其名称。

使用具名插槽的注意事项:

1、起了 name 名称的插槽,一定要使用 template 标签来包裹,并使用 v-slot 指明插槽名称;

2、v-slot 只能在 template 标签上,放在 div、h1 等 html 标签上不生效;

3、只有默认插槽在使用时可以省略外层的 template;

4、没有指定 name 时,默认都放到 default 插槽中。

 补充:template 是 vue 提供的标签,它不会被渲染成任何实质性元素,只提供包裹作用。


具名插槽的简写形式

类似 v-on 和 v-bind 的简写“@”和“:”,v-slot 也有缩写,即把“v-slot:”命令替换为“#”,如下:

<template v-slot:header></template>

<!-- v-slot:header 可以被简写为 #header -->

<template #header></template>

具体案例


作用域插槽

在封装组件的过程中,可以为预留的 <slot> 插槽通过 v-bind 绑定 props 数据,这种带有 props 数据的 <slot> 叫做“作用域插槽”。

 通俗理解,作用域插槽可以动态绑定数据,组件中 data 节点和 props 节点中的数据都可以绑定到插槽上。

在组件中定义作用域插槽,如下:

外界在使用当前组件时,除了对这个插槽进行内容填充,还可以接收插槽对外提供的数据

外界怎么接收?在v-slot:插槽名称后面用等号接收插槽对外提供的数据(接收时参数名可随意,scope比较常见)比如:

<template v-slot:default="scope"> ... </template>

<!-- 简写具名插槽 -->

<template #default="scope"> ... </template>

无需事先定义变量,接收到即可直接使用

<template v-slot:default="scope">

{{ scope }}

</template>

比如:

外界接收到的变量是一个大对象(Json),里面包含插槽绑定的所有数据,比如上面案例中插槽绑定的数据,接收到的结果如下:

获取其中某个值:

<template #default="scope">

<p>{{ scope.info.name }}</p>

<template>


解构作用域插槽的prop

作用域插槽对外提供的是一个对象数据,外面使用时,接收到的也是一个对象,里面包含了插槽通过属性绑定方式对外提供的所有数据,访问某个数据时,需要通过接收到的对象依次往下访问。

既然接收到的是一个对象,直接使用对象的结构赋值也可以,即:需要对外传递的哪个属性,直接把对应的名字放在花括号中即可,比如:

<template #default="{ info, message }"> ... <template>


作用域插槽的实际应用

比如要封装一个列表数据,此时有个表示状态的字段,值是布尔,但组件中无法确定怎样展示,需要交给组件使用者确定

抛出问题的代码:

解决方法:在封装组件的过程中,通过作用域插槽把表格每一行数据传递给组件使用者。

使用组件时,接收作用域插槽对外提供的数据,自定义单元格的渲染方式。

得到如下效果:


微信小程序
大潇博客 版权所有 Copyright ©2016~2026
京ICP备17004217号-6  合作QQ:284710375
天玺科技