目录
- 1 插槽
- 1.1 默认插槽
- 1.2 插槽设置默认内容
- 1.3 具名插槽
- 1.4 具名与默认插槽同时使用
- 1.5 动态插槽名
- 1.6 作用域插槽
- 1.6.1 默认作用域插槽
- 1.6.2 具名作用域插槽
- 1.6.3 具名与默认 作用域插槽同时使用
1 插槽
-
子组件写插槽位置
-
父组件写内容放入插槽
-
插槽内容无法访问子组件的数据
-
非作用域插槽
- 默认插槽:
<MyComponent> 123 </MyComponent>
- 具名插槽:
- 不简写:
<MyComponent> <template v-slot:header> 123 </template> </MyComponent>
- 不简写:
- 简写:
<MyComponent> <template #header> 123 </template> </MyComponent>
- 具名与默认 插槽同时使用:
- 自定义:
#header
,#xxx
- 自定义:
- 默认:
#default
,或者不写<template></template>
- 默认插槽:
-
作用域插槽:使父组件写的插槽的内容访问到子组件的数据
- 默认作用域插槽
- 不解构:
<MyComponent v-slot="slotProps"> {{ slotProps.text }} </MyComponent>
- 解构:
<MyComponent v-slot="{ text, count }"> {{ text }} {{ count }} </MyComponent>
- 不解构:
- 具名作用域插槽:
<MyComponent> <template #header="headerProps"> {{ headerProps }} </template> </MyComponent>
- 具名与默认 作用域插槽同时使用:
- 不能使用:
<MyComponent v-slot="message"> <template #xxx> {{ message }} </template> </MyComponent>
- 能使用:
<template #xxx="{ message }"> {{ message }} </template>
- 默认作用域插槽
1.1 默认插槽
<!-- 子组件 hello -->
<template><view><solt></solt></view>
</template>
<!-- 父组件 -->
<hello><view>111</view>
</hello>
1.2 插槽设置默认内容
<!-- 子组件 hello -->
<template><view><solt>我是默认内容</solt></view>
</template>
<!-- 父组件 -->
<hello><view>我能替代默认内容</view>
</hello>
1.3 具名插槽
- name 的插槽被称为具名插槽 (named slots)。
- 没有提供 name 的
<slot>
出口会隐式地命名为“default”。 - 要为具名插槽传入内容,需要使用一个含 v-slot 指令的
<template>
元素,并将目标插槽的名字传给该指令 - v-slot 指令 简写为
#
<!-- 子组件 hello -->
<template><view><slot name="header"></slot></view>
</template>
<!-- 父组件 -->
<hello><template v-slot:header><!-- header 插槽的内容放这里 --></template><!-- 简写 --><template #header><!-- header 插槽的内容放这里 --></template>
</hello>
1.4 具名与默认插槽同时使用
当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非 <template>
节点都被隐式地视为默认插槽的内容
<!-- 子组件 hello -->
<template><view><slot name="header"></slot>---<slot></slot></view>
</template>
<!-- 父组件 -->
<hello><template #header><!-- header 插槽的内容放这里 --></template><template #default><!-- 默认插槽的内容放这里 --></template>
</hello>
或
<!-- 父组件 -->
<hello><template #header><!-- header 插槽的内容放这里 --></template><!-- 默认插槽的内容放这里 -->
</hello>
1.5 动态插槽名
动态指令参数在 v-slot 上也是有效的,即可以定义下面这样的动态插槽名:
<base-layout><template v-slot:[dynamicSlotName]> ... </template><!-- 缩写为 --><template #[dynamicSlotName]> ... </template>
</base-layout>
1.6 作用域插槽
- 父组件写的插槽的内容无法访问到子组件的数据
- 如果同时使用父组件域内和子组件域内的数据
可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes
1.6.1 默认作用域插槽
默认插槽通过子组件标签上的 v-slot 指令,直接接收到了一个插槽 props 对象:
<!-- 子组件 -->
<div><slot :text="greetingMessage" :count="1"></slot>
</div>
<!-- 父组件 -->
<MyComponent v-slot="slotProps">{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
<!-- 也可以在 v-slot 中使用解构: -->
<MyComponent v-slot="{ text, count }"> {{ text }} {{ count }} </MyComponent>
1.6.2 具名作用域插槽
- 不使用缩写
v-slot:header="slotProps"
- 使用缩写
#header="slotProps"
- name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽
<!-- 子组件 -->
<div><slot name="header" :text="greetingMessage" :count="1"></slot>
</div>
<!-- 父组件 -->
<MyComponent><template #header="headerProps"> {{ headerProps }} </template><template #default="defaultProps"> {{ defaultProps }} </template>
</MyComponent>
1.6.3 具名与默认 作用域插槽同时使用
如果你混用了具名插槽与默认插槽,则需要为默认插槽使用显式的 标签。尝试直接为组件添加 v-slot 指令将导致编译错误。这是为了避免因默认插槽的 props 的作用域而困惑。举例:
<!-- 该模板无法编译 -->
<MyComponent v-slot="{ message }"><p>{{ message }}</p><template #footer><!-- message 属于默认插槽,此处不可用 --><p>{{ message }}</p></template>
</MyComponent>
为默认插槽使用显式的 标签有助于更清晰地指出 message 属性在其它插槽中不可用:
<MyComponent><!-- 使用显式的默认插槽 --><template #default="{ message }"><p>{{ message }}</p></template><template #footer><p>Here's some contact info</p></template>
</MyComponent>