一、前言
插槽其实就是子组件提供给父组件的占位符。子组件定义好插槽后,父组件可以替换插槽内容。
- 子组件不提供插槽时,父组件填充失效
- 父组件无填充时,会使用插槽默认内容
二、语法
定义插槽:
<slot></slot>
使用插槽
<template v-slot></template>
v-slot可简写为#
<template #default></template>
注意:v-slot
只能用在 template
或组件上使用,否则就会报错。
2.1、默认插槽
2.1.1、子组件
<div>
<slot>默认插槽 - 子页面默认值</slot>
</div>
2.1.2、父组件
<Detail>
<!-- 默认插槽 -->
<template #default>#default 默认插槽 - 父页面传值</template>
</Detail>
2.1.3、运行结果:
#default 默认插槽 - 父页面传值
2.2、具名插槽
存在多个插槽时,使用具名插槽,可以根据名称插槽内容。
2.2.1、子组件
<!-- 具名插槽 -->
<div>
<slot name="main">main 具名插槽 - 子页面默认值</slot>
</div>
2.2.2、父组件
<Detail>
<!-- 具名插槽 -->
<template #main>#main 具名插槽 - 父页面传值</template>
</Detail>
2.2.3、运行结果:
#main 具名插槽 - 父页面传值
2.3、作用域插槽
父组件插槽内需要使用子组件数据时,可以使用作用域插槽。
2.3.1、子组件定义
<!-- 作用域插槽 -->
<div>
<div v-for="(item, index) in items" :key="index">
<slot name="scope" :data="item">作用域插槽 - 子页面默认值</slot>
</div>
</div>
2.3.2、子组件数据
interface Student{
id:number,
name:string,
age:number
}
const items = reactive<Student[]>([
{
id:1,
name:"张三",
age:10
},
{
id:2,
name:"李四",
age:10
},
{
id:3,
name:"王五",
age:10
},
{
id:4,
name:"赵六",
age:10
},
{
id:5,
name:"贾七",
age:10
},
])
2.3.3、父组件使用
<Detail>
<!-- 作用域插槽 -->
<template #scope="{ data }">作用域插槽 - 父页面接收值 {{ data.name }}--{{ data.age }}岁 </template>
</Detail>
2.3.4、运行结果:
作用域插槽 - 父页面接收值 张三--10岁
作用域插槽 - 父页面接收值 李四--10岁
作用域插槽 - 父页面接收值 王五--10岁
作用域插槽 - 父页面接收值 赵六--10岁
作用域插槽 - 父页面接收值 贾七--10岁
2.4、动态插槽名
通过函数或变量动态改变插槽名来动态替换子组件对应插槽内容。
2.4.1、子组件定义
<!-- 动态插槽名 -->
<div>
<slot name="dynFirst">dynFirst 动态插槽名 - 子页面默认值</slot>
</div>
<div>
<slot name="dynLast">dynLast 动态插槽名 - 子页面默认值</slot>
</div>
2.4.2、父组件使用
<Detail>
<!-- 动态插槽 -->
<template #[dynFun()]>{{dynFun()}}动态插槽 - 父页面传值</template>
</Detail>
2.4.3、运行结果
dynFirst动态插槽 - 父页面传值
dynLast 动态插槽名 - 子页面默认值
三、完整代码
3.1、子组件:detail.vue
<template>
<div>
<!-- 默认插槽 -->
<div>
<slot>默认插槽 - 子页面默认值</slot>
</div>
<!-- 具名插槽 -->
<div>
<slot name="main">main 具名插槽 - 子页面默认值</slot>
</div>
<!-- 作用域插槽 -->
<div>
<div v-for="(item, index) in items" :key="index">
<slot name="scope" :data="item">作用域插槽 - 子页面默认值</slot>
</div>
</div>
<!-- 动态插槽名 -->
<div>
<slot name="dynFirst">dynFirst 动态插槽名 - 子页面默认值</slot>
</div>
<div>
<slot name="dynLast">dynLast 动态插槽名 - 子页面默认值</slot>
</div>
</div>
</template>
<script setup lang="ts">
import {reactive} from 'vue'
interface Student{
id:number,
name:string,
age:number
}
const items = reactive<Student[]>([
{
id:1,
name:"张三",
age:10
},
{
id:2,
name:"李四",
age:10
},
{
id:3,
name:"王五",
age:10
},
{
id:4,
name:"赵六",
age:10
},
{
id:5,
name:"贾七",
age:10
},
])
</script>
<style lang="scss" scoped></style>
3.2、父组件:main.vue
<template>
<div>
<Detail>
<!-- 默认插槽 -->
<template #default>#default 默认插槽 - 父页面传值</template>
<!-- 具名插槽 -->
<template #main>#main 具名插槽 - 父页面传值</template>
<!-- 作用域插槽 -->
<template #scope="{ data }">作用域插槽 - 父页面接收值 {{ data.name }}--{{ data.age }}岁 </template>
<!-- 动态插槽名 -->
<template #[dynFun()]>{{dynFun()}}动态插槽 - 父页面传值</template>
</Detail>
</div>
</template>
<script setup lang="ts">
import Detail from './detail.vue'
const dynFun = ():string => {
return 'dynFirst'
}
</script>
3.3、运行结果:
#default 默认插槽 - 父页面传值
#main 具名插槽 - 父页面传值
作用域插槽 - 父页面接收值 张三--10岁
作用域插槽 - 父页面接收值 李四--10岁
作用域插槽 - 父页面接收值 王五--10岁
作用域插槽 - 父页面接收值 赵六--10岁
作用域插槽 - 父页面接收值 贾七--10岁
dynFirst动态插槽 - 父页面传值
dynLast 动态插槽名 - 子页面默认值
标签:10,name,作用域,插槽,Vue3,组件,页面
From: https://www.cnblogs.com/gaozejie/p/16617344.html