Vue-Slot

Vue Slot

  1. 向子组件传入值可以用属性Props ,但是无法像组件传入模板。为了弥补某些场景下,向子组件传入模板,让子组件在它们的组件中渲染这些片段

  2. 无渲染组件

基础使用

1
2
3
4
5
6
7
<button class="fancy-btn">
<slot></slot> <!-- 插槽出口 -->
</button>

<FancyButton>
Click me! <!-- 插槽内容 -->
</FancyButton>

作用域

插槽内容无法访问子组件的数据。Vue 模板中的表达式只能访问其定义时所处的作用域

所以默认插槽内容上下文是当前父组件,因为模板内容是定义在父组件里面

插槽类型

  1. 默认插槽 :<slot></slot> 实际会隐式等效于 name=”default”

  2. 具名插槽: <slot name="footer"></slot> 具名插槽需要template包裹

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <template v-slot:header>
    <!-- header 插槽的内容放这里 -->
    </template>

    <template #header>
    </template>
    <!-- 动态插槽名 -->
    <template v-slot:[dynamicSlotName]>
    ...
    </template>

    image-20240221091407194

作用域插槽

由于渲染作用域问题,插槽内容无法访问子组件的数据。Vue 模板中的表达式只能访问其定义时所处的作用域

但是某些场景下需要混合渲染,父组件的某些数据结合子组件的某些数据渲染模板。所以需要子组件把数据提供给插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 <!-- 默认插槽作用域 -->
<div>
<slot :text="greetingMessage" :count="1"></slot>
</div>

<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>

<!--具名作用域插槽-->
<MyComponent>
<template #header="headerProps">
{{ headerProps }}
</template>

<template #default="defaultProps">
{{ defaultProps }}
</template>

<template #footer="footerProps">
{{ footerProps }}
</template>
</MyComponent>

<slot name="header" message="hello"></slot>

<!--同时具名作用域插槽和默认作用域插槽-->
<MyComponent>
<!-- 使用显式的默认插槽 -->
<template #default="{ message }">
<p>{{ message }}</p>
</template>

<template #footer>
<p>Here's some contact info</p>
</template>
</MyComponent>

注意点:

同时具名作用域插槽和默认作用域插槽,需要显示指名默认插槽 ,防止混淆。

无渲染组件

一些组件可能只包括了逻辑而不需要自己渲染内容,视图输出通过作用域插槽全权交给了消费者组件。我们将这种类型的组件称为无渲染组件

1
2
3
<MouseTracker v-slot="{ x, y }">
Mouse is at: {{ x }}, {{ y }}
</MouseTracker>

vue3 里面采用了组合式函数实现类似的效果 ,更加高级,并且还不会带来额外组件嵌套的开销


Vue-Slot
https://godbuttton.github.io/2024/02/21/Vue-Slot/
作者
godbutton
发布于
2024年2月21日
许可协议