Vue3插槽

一、前言

插槽其实就是子组件提供给父组件的占位符。子组件定义好插槽后,父组件可以替换插槽内容。

  • 子组件不提供插槽时,父组件填充失效
  • 父组件无填充时,会使用插槽默认内容

二、语法

定义插槽:

<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 动态插槽名 - 子页面默认值
posted @ 2022-08-23 18:18  gaozejie  阅读(547)  评论(0编辑  收藏  举报