vue3.2中使用slot插槽

491 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

前言

本文主要记录了如何在vue3.2中使用slot插槽,包含具名插槽、默认插槽以及作用域插槽。

slot插槽

slot插槽可以将父组件的内容传递给子组件,常用于组件的复用和扩展。

初识slot

首先,我们创建两个组件,index.vue作为父组件,index1.vue作为子组件。

在父组件中引入子组件,并将子组件写成双标签,在双标签中写入要穿给子组件的内容:

<index1>初始slot</index1>

子组件中对应写入<slot></slot> 标签,即可在子组件中显示父组件传递过来的内容。

image.png

在子组件中写入多个<slot></slot> 标签,会多次渲染出父组件传递过来的内容。

image.png

当然,<slot> 标签可以设置默认值。 即:父组件<index1></index1>, 子组件<slot>子组件默认值</slot>

image.png

具名插槽

具名插槽(命名插槽),就是将插槽命名以确保多个插槽相互传递内容的准确性。

在子组件<slot>标签上使用name属性为插槽命名(要注意插槽的命名);

在父组件中<template>标签上使用v-slot:xxx属性传递内容;

ps:

1.v-slot:xxx属性必须在<template>标签上使用

2.v-slot:xxx属性中间是 “:”,而不是“=”

父组件:

   <index1>
      <template v-slot:header>
         <div>具名插槽</div>
      </template>
   </index1>

子组件:

 <slot name="header"></slot>

v-slot:xxx属性可以简写为#xxx;

即,父组件可以写为:

   <index1>
      <template #header>
         <div>具名插槽</div>
      </template>
   </index1>

其实像element-ui这样的ui框架也是这么用的。

默认插槽

默认插槽是相对于具名插槽而言的,子组件的name属性,没有给出具体的值(即:使用默认值),所以父组件可以在<template>标签上使用#default传递内容;

父组件:

   <index1 #default>默认插槽</index1>

子组件:

  <slot>子组件slot默认值</slot>

当然父组件直接这样写也是可以的:

   <index1>默认插槽</index1>

作用域插槽

作用域插槽稍稍有点麻烦,但不复杂。

举一个栗子:父组件调用子组件,但父组件希望用子组件的属性,来替换掉子组件slot的默认内容。

示例中,子组件的默认内容是data.a 即:1。这里我们期望父组件用data.b2 来替换掉 1

在子组件中我们通过自定义属性objdata传送到objProps,然后在父组件中使用{{objProps.obj.b}}

ps: 注意是data传送到 objProps

父组件:

   <index1>
      <template #default = "objProps">
         <div>{{objProps.obj.b}}</div>
      </template>
   </index1>

子组件:

<template>
   <slot :obj="data">{{ data.a }}</slot>
</template>

<script lang="ts" setup>
const data = {
    a: 1,
    b: 2,
}
</script>

代码示例:

父组件:

<template>
   <div>父组件</div>

   <!-- 初始slot -->
   <!-- <index1>初始slot</index1> -->

   <!-- 默认插槽 -->
   <!-- <index1 #default>默认插槽</index1> -->

   <!-- 具名插槽 -->
   <!-- <index1>
      <template v-slot:header>
         <div>具名插槽</div>
      </template>
   </index1> -->

   <!-- 具名插槽--缩写-->
   <!-- <index1>
      <template #header>
         <div>具名插槽</div>
      </template>
   </index1> -->

   <!-- 作用域插槽 -->
   <index1>
      <template #default = "objProps">
         <div>{{objProps.obj.b}}</div>
      </template>
   </index1>
</template>

<script lang="ts" setup>
import index1 from './index1.vue'
</script>
<style scoped lang="less">

</style>

子组件:

<template>
   <div>子组件</div>
   <!-- 初始slot -->
   <!-- <slot></slot> -->

   <!-- 默认插槽 -->
   <!-- <slot>子组件slot默认值</slot> -->

   <!-- 具名插槽 -->
   <!-- <slot name="header"></slot> -->

      <!-- 作用域插槽 -->
   <!-- <slot :obj="data">{{ data.a }}</slot> -->
</template>

<script lang="ts" setup>
const data = {
    a: 1,
    b: 2,
}
</script>
<style scoped lang="less">

</style>


本文到此结束

如果大家还有什么其他想法,欢迎在评论区交流!