Vue3中插槽(slot)用法汇总

简介: Vue3中插槽(slot)用法汇总

image.png


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


Vue中的插槽相信使用过Vue的小伙伴或多或少的都用过,但是你是否了解它全部用法呢?本篇文章就为大家带来Vue3中插槽的全部用法来帮助大家查漏补缺。


什么是插槽



简单来说就是子组件中的提供给父组件使用的一个坑位,用<slot></slot> 表示,父组件可以在这个坑位中填充任何模板代码然后子组件中<slot></slot>就会被替换成这些内容。比如一个最简单插槽例子

//父组件
<template>
  <div>
    <Child>Hello Juejin</Child>
  </div>
</template>
<script setup lang="ts">
import Child from './Child.vue'
</script>
//子组件Child
<template>
    <div>
        <p>1</p>
        <slot />
        <p>2</p>
    </div>
</template>

子组件中的<slot /> 便是父组件放在子组件标签<Child>之间的内容。当然这之间你可以传入任何代码片段,都会被放到<slot />这个位置。

image.png

同样的你也可以在标签<Child>之间放入变量,比如

//父组件
<template>
  <div>
    <Child>{{ msg }}</Child>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './Child.vue'
const msg = ref('Hello Juejin')
</script>

先解释一下后面频繁出现的两个词 插槽插槽内容,防止后面阅读搞混了:

image.png

同样的 插槽表示的就是这个msg变量。所以子组件 插槽是可以访问到父组件的数据作用域,而插槽内容是无法访问子组件的数据(即父组件中两个<Child>之间是不能使用子组件中的数据的),这就是所谓的渲染作用域。后面会介绍插槽插槽内容传参的方式


默认内容



在父组件没有提供任何插槽内容的时候,我们是可以为子组件的插槽指定默认内容的,比如

//子组件
<template>
    <div>
        <slot>我是默认内容</slot>
    </div>
</template>
//父组件1
<template>
  <div>
    <Child></Child>
  </div>
</template>
<script setup>
import Child from './Child.vue'
</script>
//父组件2
<template>
  <div>
    <Child>Hello Juejin</Child>
  </div>
</template>
<script setup>
import Child from './Child.vue'
</script>

此时父组件1展示默认内容

image.png

父组件2展示提供的内容

image.png


具名插槽



很多时候一个 插槽满足不了我们的需求,我们需要多个 插槽。于是就有了具名插槽,就是具有名字的 插槽。简单来说这个具名插槽的目的就是让一个萝卜一个坑,让它们呆在该呆的位置去。比如带 name 的插槽 <slot name="xx">被称为具名插槽。没有提供 name<slot> 会隐式地命名为“default”。在父组件中可以使用v-slot:xxx(可简写为#xxx) 指令的 <template> 元素将目标插槽的名字传下去匹配对应 插槽。比如

//子组件
<template>
    <div>
        <!-- 大萝卜 -->
        <div>
            <slot name="bigTurnip"></slot>
        </div>
        <!-- 小萝卜 -->
        <div>
            <slot name="smallTurnip"></slot>
        </div>
        <!-- 中萝卜 -->
        <div>
            <slot name="midTurnip"></slot>
        </div>
    </div>
</template>
//父组件
<template>
  <div>
    <Child>
      <!-- #smallTurnip 为v-slot:smallTurnip缩写 -->
      <template #smallTurnip>
        小萝卜
      </template>
      <template #midTurnip>
        中萝卜
      </template>
      <template #bigTurnip>
        大萝卜
      </template>
    </Child>
  </div>
</template>
<script setup>
import Child from './Child.vue'
</script>

image.png


所以父组件中无需在意顺序,只需要写好模板命好名,它就会自动去到它所对应的位置。


动态插槽名



动态插槽名就是插槽名变成了变量的形式,我们可以随时修改这个变量从而展示不同的效果。它的写法是v-slot:[变量名]或者缩写为#[变量名]

//父组件
<template>
  <div>
    <Child>
      <!-- 等同于#smallTurnip -->
      <template #[slotName]>
        小萝卜
      </template>
      <template #midTurnip>
        中萝卜
      </template>
      <template #bigTurnip>
        大萝卜
      </template>
    </Child>
  </div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const slotName = ref('smallTurnip')
</script>


作用域插槽



作用域插槽


上面说过插槽内容是无法访问子组件的数据的,但是如果我们想在插槽内容访问子组件的状态该怎么办呢?

其实插槽可以像对组件传递 props 那样,在slot标签绑定属性从而传递给父组件中的插槽内容。首先来看下默认插槽的传值方式

//子组件
<template>
    <div>
        <slot personName="xiaoyue" age="18"></slot>
    </div>
</template>
//父组件
<template>
  <div>
    <Child v-slot="slotProps">
      My name is {{ slotProps.personName }} and I am {{ slotProps.age }} years old this year
    </Child>
  </div>
</template>
<script setup>
import Child from './Child.vue'
</script>

你还可以以结构的形式获取slot提供的数据

<template>
  <div>
    <Child v-slot="{ personName, age }">
      My name is {{ personName }} and I am {{ age }} years old this year
    </Child>
  </div>
</template>

image.png

注意不能绑定name属性,因为你绑定了name它就成了具名插槽了。同样具名插槽中的name属性也不会传递给插槽内容。这种在父组件作用域中获取到了子组件作用域中的变量,可以认为作用域插槽延伸了子组件数据的作用范围,所以这类能够接受参数的插槽就被称为了作用域插槽


具名作用域插槽


下面再看下具名作用域插槽它的传参方式。它接收参数的方式是通过template标签的指令v-slot的值获取的,所以可以缩写成这样

//父组件
<template>
  <div>
    <Child>
      <template #bigTurnip="bigTurnipProps">
        {{ bigTurnipProps.message }}
      </template>
    </Child>
  </div>
</template>
<script setup>
import Child from './Child.vue'
</script>
//子组件Child.vue
<template>
    <div>
        <!-- 大萝卜 -->
        <div>
            <slot name="bigTurnip" message="我是萝北"></slot>
        </div>
    </div>
</template>

image.png

这类插槽便是具名作用域插槽


写在最后



到这里插槽(slot)的全部用法基本就已经介绍完啦。如果感觉对你有用的话赶紧点赞收藏吧!


相关文章
|
15天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
35 7
|
16天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
38 3
|
15天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
36 1
|
15天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
36 1
|
5天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
5天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
5天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
5天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
4天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
6天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。