小小插槽一会标签<slot></slot>
,一会属性v-slot
,一会#
的,到底是怎么用,列个表一眼看明白。
默认插槽 | 具名插槽 | 作用域插槽 | |
---|---|---|---|
定义 | <slot></slot> |
<slot name="header"></slot> |
v-bind:user="user" |
使用 | v-slot | v-slot:header | v-slot="slotProps" v-slot:default="{ user }" v-slot:other="slotProps" |
缩写使用 | #default | #header | #default="{ user }" |
注意 v-slot
只能添加在 <template>
上
最简单的定义及使用
定义child.vue
<button>
<slot>这是当使用的时候没传参的时候显示的内容</slot>
</button>
使用father.vue
<child>编辑</child>
结果:
<button>编辑</button>
定义的child组件,如果没有写<slot></slot>
那使用的时候不管<child></child>
标签里面写什么内容都会丢失。
定义<slot></slot>
后,如果<child></child>
使用的时候里面什么都没写那渲染结果为<slot></slot>
标签里面的内容。
具名插槽的使用
一个不带 name
的 <slot>
出口会带有隐含的名字"default"。
定义child.vue
<div class="title">
<slot>标题位置</slot>
</div>
<div class="subtitle">
<slot name="subTitle">这是副标题</slot>
</div>
使用father.vue
<child>
默认插槽,可以写template v-slot:default也可以不写
<h3>我还能加个标签</h3>
<template v-slot:subtitle>这是副标题</template>
这个地方也是默认插槽里面的
</child>
结果:
<div class="title">
默认插槽,可以写template v-slot:default也可以不写
<h3>我还能加个标签</h3>
这个地方也是默认插槽里面的
</div>
<div class="subtitle">这是副标题</div>
任何没有被包裹在带有 v-slot
的 <template>
中的内容都会被视为默认插槽的内容。
然而,如果想更明确一些,仍然可以在一个 <template>
中包裹默认插槽的内容
作用域插槽默认使用方法
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
想让插槽内容能够访问子组件中才有的数据就用到了作用域
定义child.vue
<div class="title">
<slot v-bind:user="user">{{ user.firstName }}</slot>
<!-- 简写:
<slot :user="user">{{ user.firstName }}</slot> -->
</div>
<script setup>
import { reactive } from "vue";
const user = reactive({
firstName: "Zhang",
lastName: "San",
});
</script>
独占默认插槽的缩写语法
使用father.vue
<child v-slot="slotProps">
我的名字是{{ slotProps.user.lastName }}
</child>
结果:
<div class="title">我的名字是San</div>
终级 - 作用域+命名插槽使用方法
只要出现多个插槽,请始终为所有的 插槽使用完整的基于 <template>
的语法
定义child.vue
<div class="title">
<slot :user="user">标题位置</slot>
</div>
<div class="subtitle">
<slot name="subTitle" :user="user">这是副标题</slot>
</div>
<script setup>
import { reactive } from "vue";
const user = reactive({
firstName: "Zhang",
lastName: "San",
});
</script>
使用father.vue
<child>
<template v-slot="slotProps">
有命名插槽的时候v-slot就不能写到child标签里面了 {{slotProps.user.firstName}}
</template>
<template v-slot:subTitle="{user}">{{user.lastName}}</template>
</child>
使用father2简写.vue
<child>
<template #default="{ user }">
有命名插槽的时候v-slot就不能写到child标签里面了 {{ user.firstName }}
</template>
<template #subTitle="{ user: { lastName } }">{{ lastName }}</template>
</child>
结果:
<div class="title">有命名插槽的时候v-slot就不能写到child标签里面了 Zhang</div>
<div class="subtitle">San</div>