插槽
作者:Yuan Tang
更新于:5 个月前
字数统计:560 字
阅读时长:2 分钟
使用
子组件 Child.vue
:
vue
<template>
<div>Child</div>
<slot />
</template>
父组件:
vue
<script setup>
import Child from './Child.vue'
</script>
<template>
<div>Parent</div>
<Child>124</Child>
</template>
渲染作用域
插槽作用域取决于组件在哪里定义,作用域就在哪里。与组件最终放置渲染地方无关。
子组件 Child.vue
:
vue
<script setup>
import { ref } from 'vue'
const text = ref('子组件')
function show() {
console.log(text.value)
}
</script>
<template>
<div @click="show">
<slot />
</div>
</template>
父组件:
vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const text = ref('父组件')
function show() {
console.log(text.value)
}
</script>
<template>
<Child>
<div @click="show">
click
</div>
</Child>
</template>
最终触发点击事件的是父组件的 show
函数方法与变量。
默认值
子组件 Child.vue
:
vue
<script setup>
</script>
<template>
<div>
<slot>默认值</slot>
</div>
</template>
父组件:
vue
<script setup>
import Child from './Child.vue'
</script>
<template>
<Child>
<div>click</div>
</Child>
</template>
此时父组件传了一个内容为 click
的盒子,子组件接收页面渲染为 click
,如果父组件不传,则默认渲染“默认值”。
具名插槽
要为具名插槽传入内容,我们需要使用一个含 v-slot
指令的 <template>
元素,并将目标插槽的名字传给该指令:
子组件 Child.vue
:
vue
<script setup>
</script>
<template>
<div>
<slot name="top" />
<slot name="middle" />
<slot name="bottom" />
</div>
</template>
父组件:
vue
<script setup>
import Child from './Child.vue'
</script>
<template>
<Child>
<template #top>
top
</template>
<template #middle>
middle
</template>
<template #bottom>
bottom
</template>
</Child>
</template>
总结:
- 如果不起名,插槽默认名称为
default
,父组件不使用具名插槽的内容都会在这里渲染。- 具名插槽的使用:
v-slot:插槽名称
(简写形式:#插槽名称
)。
动态插槽名
插槽名称也是可以动态设置的,设置的方式与类名相同,同样也受相同的语法限制。
vue
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</base-layout>
插槽传递数据
子组件 Child.vue
:
vue
<script setup>
</script>
<template>
<div>
<slot id="1" title="tydumpling" content="内容" />
</div>
</template>
父组件:
vue
<script setup>
import Child from './Child.vue'
</script>
<template>
<Child>
<!-- 全部获取 -->
<template #default="record">
{{ record }} // {id: 1, title: tydumpling, content: 内容}
</template>
<!-- 单独获取 -->
<template #default="{ id }">
{{ id }} // 1
</template>
</Child>
</template>
简写默认插槽
vue
<script setup>
import Child from './Child.vue'
</script>
<template>
<Child v-slot="record">
{{ record }}
</Child>
</template>
此时无法再使用其他插槽,无效果且会报错。