2

Vue3 Slot—插槽全家桶使用详解

 3 years ago
source link: https://www.fly63.com/article/detial/11898
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

插槽 slot 就是子组件中提供给父组件使用的一个占位符,用 <slot></slot> 表示,父组件可以给这个占位符内填充任何模板代码,填充的内容会自动替换 <slot></slot> 标签。

插槽被分为三种:匿名插槽、具名插槽、作用域插槽。

1、匿名插槽

没有名字的插槽就是匿名插槽,组件可以放置一个或多个 <slot></slot>。

子组件内放置一个插槽:

<template>
    <div>
       <slot></slot>
    </div>
</template>

父组件使用插槽:

<Header>
 <div>哈哈哈哈哈哈</div>
</Header>

// 或
<Header>
 <template v-slot>
  哈哈哈哈哈哈
 </template>
</Header>

如果有多个 slot 时,父组件中需要填充的内容就会被多次插入。

2、具名插槽

组件内可以放置多个插槽,如果都是匿名插槽的时候,渲染的都是父组件默认内容,无法实现插入多个不同内容,此时就需要给插槽设置名字以便于区分它们。

具名插槽就是给插槽取个名字,可以把组件内多个插槽放在不同的地方,父级填充内容时,可以根据名字把内容填充到对应的插槽内。

定义为多个插槽的组件:

<template>
  <div>
    头部:
    <slot name="header"></slot>
    主体:
    <slot></slot>
    底部:
    <slot name="footer"></slot>
  </div>
</template>

父组件填充内容需要对象插槽名:

<Com>
  <template v-slot:header>
    <div>我是header</div>
  </template>
  <template v-slot>
    <div>中间匿名插槽</div>
  </template>
  <template v-slot:footer>
    <div>我是 footer</div>
  </template>
</Com>

可以简写为:

<Com>
  <template #header>
    <div>我是header</div>
  </template>
  <template #default>
      <div>中间匿名插槽</div>
  </template>
  <template #footer>
    <div>我是 footer</div>
  </template>
</Com>

3、作用域插槽

匿名插槽和具名插槽父组件只能访问父组件中编译的内容,子组件只能访问子组件内的内容,有时我们在父组件需要访问到子组件中的内容,此时 vue 给我们提供了作用域插槽。

作用域插槽子组件内定义要传送的数据

<template>
  <div v-for="item in 10" :key="item">
    <slot :data="item" name="list"></slot>
  </div>
</template>

在调用组件的父组件内接收数据:

<SlotCom>
  <template #list="{data}">
    {{ data }}
  </template>
</SlotCom>

4、动态插槽

有多个插槽,不同状态下展示不同的插槽,此时我们就可以使用动态插槽,插槽名是一个变量名,其值可以是动态修改的。

<Dialog>
  <template #[name]>
    <div>
    动态插槽
    </div>
</template>
</Dialog>

我们可以做一个类似于选项卡的效果:

父组件代码:

<button v-for="item in slotList" :key="item.name" @click="changeSlot(item)">
  {{ item.content }}
</button>
<childCom>
  <template #[name]>
    <div>我是{{ name }}插槽</div>
  </template>
</childCom>
<script>
import { reactive, ref } from 'vue'
let name: string = ref('header')

type Slots = {
  name: string
  content: string
}
const slotList = reactive<Slots[]>([
  { name: 'header', content: '头' },
  { name: 'body', content: '中间' },
  { name: 'footer', content: '尾' },
])
const changeSlot = (item: Slots): void => {
  name.value = item.name
}
</script>

子组件代码:

<template>
  <div>
    <slot name="header"></slot>
    <slot name="body"></slot>
    <slot name="footer"></slot>
  </div>
</template>

此时就可以动态地选择其中任意一个插槽展示。

链接: https://www.fly63.com/article/detial/11898

</div


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK