Vue3中slot插槽基本使用

目录
  • 1.插槽基本使用
  • 2.插槽默认内容
  • 3.具名插槽
    • 3.1 基本使用
    • 3.2 简写
    • 3.3 默认插槽与具名插槽混用
  • 4.动态插槽名
  • 5.插槽作用域问题
  • 6.作用域插槽
    • 6.1 默认插槽作用域传值
    • 6.2 具名插槽作用域传值
  • 总结

使用Vue的小伙伴相信你一定使用过插槽,如果你没有用过,那说明你的项目可能不是特别复杂。插槽(slot)可以说在一个Vue项目里面处处都有它的身影,比如我们使用一些UI组件库的时候,我们通常可以使用插槽来自定义我们的内容。

1.插槽基本使用

插槽的用途就和它的名字一样:有一个缺槽,我们可以插入一些东西。

插槽slot通常用于两个父子组件之间,最常见的应用就是我们使用一些UI组件库中的弹窗组件时,弹窗组件的内容是可以让我们自定义的,这就是使用了插槽的原理。

我们在项目中新建一个child.vue文件,用来当作子组件,它的代码也非常的简单。

child.vue 代码如下:

<template>
  <div class="child-box">
    <p>我是子组件</p>
    <!-- 插槽 -->
    <slot></slot>
  </div>
</template>
<style>
.child-box {
  display: flex;
  flex-direction: column;
  align-items: center;
}
</style>

然后我们直接在App.vue引用该子组件,代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child></child>
</template>
<script setup lang="ts">
import Child from "./child.vue";
</script>

输出结果:

child子组件代码非常的简单,唯一不同的里面我们添加了一对<slot></slot>标签,这就是插槽标签。这对标签就好比我们在child组件内部挖了一个槽出来,我们接下来就可以往这个槽里面放置一些内容。

那么我们如何往这个槽里面放置内容呢?

我们在App.vue里面通过一对闭合标签<child></child>调用了子组件,我们都知道HTML标签之间是可以插入内容的,虽然child不是HTML自带的标签,但是它却有着类似的特征,比如我们往<child></child>之间插入一点内容,代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <div>小猪课堂</div>
  </child>
</template>

输出结果:

我们发现在<child></child>标签之间插入的内容被渲染出来了,那么这是为何呢?

前面我们说slot就是挖了一个槽出来,可以放置东西,这里我们在父组件中添加的div便就是我们要添加的东西,子组件中slot标签被替换为了我们插入的div元素。这就是插槽的最基本使用。

结论:

为了更好理解插槽,简单总结为以下几点:

  • slotVue3中的内置标签。
  • slot相当于给子组件挖出了一个槽,可以用来填充内容。
  • 父组件中调用子组件时,子组件标签之间的内容元素就是要放置的内容,它会把slot标签替换掉。

最简单的理解:我们的使用U盘需要将U盘插入USB口中,此时USB口就是插槽,U盘就是插口。在Vue中,<slot></slot>就是电脑插槽,父组件的内容就可以理解为U盘插口。

2.插槽默认内容

我们通常将插槽比作一个占位符,有内容进来时,自动把slot给替换掉。但是,如果没有内容进来时,那么应该渲染什么呢?

在很多场景下都会有这种需求,比如UI组件库中的弹窗,如果我们没有传入弹窗的头部或者底部,那么弹窗便会有默认的样式效果,这里就用到了slot的默认内容功能。

修改一下 child.vue 代码:

<template>
  <div class="child-box">
    <p>我是子组件</p>
    <!-- 插槽 -->
    <slot>
      <p>我是默认内容</p>
    </slot>
  </div>
</template>

当我们的App.vue没有向child组件传入内容时,会是什么效果呢?

App.vue 代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child></child>
</template>

输出结果:

可以看到子组件同样渲染了内容,而且就是slot标签内的内容。那么我们我们往child组件传入一点内容会是什么效果呢?

App.vue 代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <div>{{ message }}</div>
  </child>
</template>
<script setup lang="ts">
import { ref } from "vue";
import Child from "./child.vue";
const message = ref("小猪课堂");
</script>

输出结果:

可以看到此时页面上渲染的App.vue父组件传入的内容了。

总结:

从上面例子不难看出,slot 标签内的内容就是默认内容,也就是当父组件没有传递给子组件内容时,子组件就会默认渲染 slot 内部的内容,但是 slot 标签是不会渲染出来的。

3.具名插槽

很多时候我们子组件中都不止只有一个slot,比如弹窗组件,我们可能允许调用者同时传入headercontentfooter等等,这个时候如果子组件中只有一个slot,那么这么多内容该如何区分,或者说该如何渲染呢?

3.1 基本使用

这个时候为了区分插槽与内容的对应关系,我们可以分别给slot和内容都加上一个名字,插入插槽的时候大家按照名字区分好就可以了。

我们给child组件添加上多个slot,并且给每个slot取上一个名字。

代码如下:

<template>
  <div class="child-box">
    <p>我是子组件</p>
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

上段代码中我们添加了3slot插槽,并且给其中两个slot标签添加了一个name属性,也就是每个插槽的名字。需要注意的是,上段代码中有一个插槽我们没有添加name属性,这个时候Vue会隐式的将这个插槽命名为“default”,接下来就是我们父组件App.vue添加内容了。

代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template v-slot:header>
      <div>我是 header:{{ message }}</div>
    </template>
    <div>我没有名字:{{ message }}</div>
    <template v-slot:footer>
      <div>我是 footer:{{ message }}</div>
    </template>
  </child>
</template>

输出结果:

既然slot有了名字,那么我们在父组件中传入内容时就要和名字关系对应起来,我们采用v-slot:header指令的形式找到对应的插槽,需要注意的是该指令需要作用在template元素上。从上图可以看出,我们传入的内容都渲染到了对应的插槽内,没有命名的插槽渲染了我们传入的未添加指令的内容。

3.2 简写

Vue中,很多指令都有简写形式,v-slot:name指令也有简写形式,比如看我们下面的示例。

原写法:

<template v-slot:footer>
</template>

简写法:

<template #footer>
</template>

接下来我们在借用官网的一张图来清楚的了解具名插槽中的父子组件关系。

其中BaseLayout为一个子组件,就和我们child组件一样。

3.3 默认插槽与具名插槽混用

当一个子组件中既有具名插槽,又有默认插槽时,该如何渲染呢?

前面我们说默认插槽会被隐式的命名为default,所以我们传入内容时可以将插槽名字改为defalut即可。

修改 child 组件:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template v-slot:header>
      <div>我是 header:{{ message }}</div>
    </template>
    <template v-slot:default>
      <div>我没有名字:{{ message }}</div>
      <div>我没有名字:{{ message }}</div>
      <div>我没有名字:{{ message }}</div>
    </template>
    <template v-slot:footer>
      <div>我是 footer:{{ message }}</div>
    </template>
  </child>
</template>

虽然说子组件中有一个slot没有取名字,但是默认可以用default来代表它,就好比人刚出生的时候没有名字,但是他又一个默认属性:“人”。

当然,既然大家都是默认的,在父组件中你也可以不用名字,这个时候内容会默认传入到未命名插槽中去。

代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template v-slot:header>
      <div>我是 header:{{ message }}</div>
    </template>
    <div>我没有名字:{{ message }}</div>
    <div>我没有名字:{{ message }}</div>
    <div>我没有名字:{{ message }}</div>
    <template v-slot:footer>
      <div>我是 footer:{{ message }}</div>
    </template>
  </child>
</template>

输出结果:

4.动态插槽名

前面我们给插槽命名的时候都是直接写死的,其实我们有时候可以动态给插槽命名的,以满足更多的业务场景。

代码如下:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
  <!-- 缩写为 -->
  <template #[dynamicSlotName]>
    ...
  </template>
</base-layout>

上段代码就是在父组件中采用动态插槽名传入内容的示例。

5.插槽作用域问题

我们仔细思考插槽的使用,会发现这有一点类似于父子组件传递,只不过插槽传递的是模板内容罢了。那么涉及到传值,就会有一个作用域的问题,我们回顾一下App.vue中的一段代码。

代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <div>{{ message }}</div>
  </child>
</template>
<script setup lang="ts">
import { ref } from "vue";
import Child from "./child.vue";
const message = ref("小猪课堂");
</script>

上段代码中message是我们在父组件中定义的数据,但是在我们的子组件child中渲染了出来,说明子组件中的插槽是可以访问到父组件中的数据作用域的,但是反过来是不行的,因为我们无法通过插槽拿到子组件的数据。

总结:

所以我们这里总结为两点

  • 插槽内容可以访问到父组件的数据作用域,就好比上述中的message是父组件的。
  • 插槽内容无法访问到子组件的数据,就好比上述App.vue中的插槽内容拿不到子组件child的数据。

6.作用域插槽

前一节我们说父组件中的插槽内容是无法访问到子组件中的数据的,但是,万一我们有需求就是需要在插槽内容中获取子组件数据怎么办呢?

Vue3给我们提供了方法,使用起来也比较简单。

6.1 默认插槽作用域传值

我们先来演示默认插槽如何获取子组件的数据。

child.vue 代码如下:

<template>
  <div class="child-box">
    <p>我是子组件</p>
    <slot text="我是子组件小猪课堂" :count="1"></slot>
  </div>
</template>

App.vue 组件代码:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child v-slot="slotProps">
    <div>{{ slotProps.text }}---{{ slotProps.count }}</div>
  </child>
</template>

输出结果:

上段代码中我们在子组件中slot标签上添加了一些自定义属性,属性值就是我们想要传递给父组件的一些内容。在父组件App.vue中通过v-slot="slotProps"等形式接收子组件传毒过来的数据,slotProps的名字是可以任意取的,它是一个对象,包含了所有传递过来的数据。

需要注意的是,子组件传递过来的数据只能在子组件这个标签内使用。

解构写法:

我们都知道对象是可以解构的,所以我们在父组件中还可以直接使用解构的写法来获取数据。

代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child v-slot="{ text, count }">
    <div>{{ text }}---{{ count }}</div>
  </child>
</template>

6.2 具名插槽作用域传值

具名插槽作用域之间的传递其实默认插槽作用域传值原理是一样的,只不过写法不一样罢了。

child.vue 代码如下:

<template>
  <div class="child-box">
    <p>我是子组件</p>
    <slot name="header" text="我是子组件小猪课堂" :count="1"></slot>
  </div>
</template>

App.vue 代码如下:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <child>
    <template #header="{ text, count }">
      <div>{{ text }}---{{ count }}</div>
    </template>
  </child>
</template>

上段代码中我们给slot添加了一个name,在父组件中接收数据的时候不在采用v-slot=""形式了,而是直接再插槽内容上采用#header=""形式,当时这是简写形式,你也可以写为:v-slot:header=""

总结

插槽的作用非常广泛,学好插槽对我们的项目开发有着非常大的帮助,当然,想要非常优雅的使用插槽,还是需要费一些功夫的。这里可以推荐大家去看一看element组件库中的table的使用,看看它是如何使用插槽的,如何优雅的将表格组件中的数据共享给父组件的。

到此这篇关于Vue3中slot插槽使用方式的文章就介绍到这了,更多相关Vue3插槽使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue3中插槽(slot)用法汇总(推荐)

    目录 什么是插槽 默认内容 具名插槽 动态插槽名 作用域插槽 作用域插槽 具名作用域插槽 写在最后 Vue中的插槽相信使用过Vue的小伙伴或多或少的都用过,但是你是否了解它全部用法呢?本篇文章就为大家带来Vue3中插槽的全部用法来帮助大家查漏补缺. 什么是插槽 简单来说就是子组件中的提供给父组件使用的一个 坑位 ,用 <slot></slot> 表示,父组件可以在这个坑位中填充任何模板代码然后子组件中 <slot></slot> 就会被替换成这些内容.比如一

  • vue父子组件slot插槽的使用

    目录 vue父子组件slot插槽 1.创建一个子组件并在vue实例中注册 2.在HTML代码中使用子组件 3.在vue实例中写入想要插入到子组件的内容 4.在子组件的模板中通过一个slot标签 vue插槽v-slot实现父向子传值 vue父子组件slot插槽 关于父组件在使用子组件的时候,向子组件插入内容的方法 1.创建一个子组件并在vue实例中注册 这是创建子组件 var testzujian = {         template:`<div>             <span&

  • Vue3系列教程之插槽slot详解

    目录 1匿名插槽 2具名插槽 3作用域插槽 4动态插槽 插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML.组件等,填充的内容会替换子组件的<slot></slot>标签. 1匿名插槽 (1)在子组件放置一个插槽,mytest.vue <template> <div> <slot>我这里设置默认值</slot> </d

  • Vue3中插槽(slot)的全部使用方法

    目录 什么是插槽 默认内容 具名插槽 动态插槽名 作用域插槽 作用域插槽 具名作用域插槽 写在最后 Vue中的插槽相信使用过Vue的小伙伴或多或少的都用过,但是它的所有用法你是否全部理解呢?本篇文章就为大家带来Vue3中插槽的全部用法来帮助大家查漏补缺. 什么是插槽 简单来说就是子组件中的提供给父组件使用的一个坑位,用<slot></slot> 表示,父组件可以在这个坑位中填充任何模板代码. 比如一个最简单插槽例子: //父组件 <template> <div&g

  • Vue插槽slot详细介绍(对比版本变化,避免踩坑)

    目录 插槽是什么? 怎么使用插槽? 基本用法 后备(默认)内容 具名插槽 作用域插槽 插槽版本变化 总结 Vue中的插槽(slot)在项目中用的也是比较多的,今天就来介绍一下插槽的基本使用以及Vue版本更新之后的插槽用法变化. 插槽是什么? 插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML.组件等,填充的内容会替换子组件的<slot></slot>标签.简单理解就是子组

  • Vue3插槽Slot实现原理详解

    目录 Vue官方对插槽的定义 Slot到底是什么 如何使用插槽 回顾组件渲染的原理 插槽的初始化原理 解析插槽中的内容 作用域插槽原理 具名插槽原理 默认内容插槽的原理 Vue官方对插槽的定义 Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 <slot> 元素作为承载分发内容的出口. Slot到底是什么 那么Slot到底是什么呢?Slot其实是一个接受父组件传过来的插槽内容,然后生成VNode并返回的函数. 我们一般是使用 <

  • Vue深入理解插槽slot的使用

    目录 一.插槽(slot)是什么 二.使用场景 三.slot的分类 默认插槽 具名插槽 作用域插槽 四.介绍对slot的理解 一.插槽(slot)是什么 slot是组件内的一个占位符,该占位符可以在后期使用自己的标记语言填充. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信方式,适用于父组件===>子组件 例子: //父组件中 <Category> <div>html结构</div> </Category> //子组件中: &l

  • vue作用域插槽详解、slot、v-slot、slot-scope

    目录 vue 插槽slot和具名插槽 作用域插槽的核心作用是 实例说明 子组件 父组件 效果图 vue 插槽slot和具名插槽 作用都是在调用组件的时候传递一些DOM结构进去, 不同点是:具名插槽在传递DOM时需要声明,传递给哪个slot的名字 name 他们用法简单不在赘述. 重点说一下作用域插槽 slot-scope 的使用,以及vue2.6.X开始的新语法v-slot 作用域插槽的核心作用是 子组件给父组件传递数据,当然也包含上述插槽的能力 老版作用域插槽, slot="test"

  • Vue中slot插槽作用与原理详解

    目录 1.作用 2.插槽内心 2.1.默认插槽 2.2.具名插槽(命名插槽) 2.3.作用域插槽 实现原理 1.作用 父组件向子组件传递内容 扩展.复用.定制组件 2.插槽内心 2.1.默认插槽 把父组件中的数组,显示在子组件中,子组件通过一个slot插槽标签显示父组件中的数据. 子组件 <template> <div class="slotChild"> <h4>{{msg}}</h4> <slot>这是子组件插槽默认的值&

  • Vue3中slot插槽基本使用

    目录 1.插槽基本使用 2.插槽默认内容 3.具名插槽 3.1 基本使用 3.2 简写 3.3 默认插槽与具名插槽混用 4.动态插槽名 5.插槽作用域问题 6.作用域插槽 6.1 默认插槽作用域传值 6.2 具名插槽作用域传值 总结 使用Vue的小伙伴相信你一定使用过插槽,如果你没有用过,那说明你的项目可能不是特别复杂.插槽(slot)可以说在一个Vue项目里面处处都有它的身影,比如我们使用一些UI组件库的时候,我们通常可以使用插槽来自定义我们的内容. 1.插槽基本使用 插槽的用途就和它的名字一

  • vue3中的render函数里定义插槽和使用插槽

    目录 render函数里定义插槽和使用插槽 定义插槽 定义有插槽的组件使用插槽 vue3 render函数小变动 render函数的参数 render函数签名 VNode属性格式 render函数里定义插槽和使用插槽 vue3中this.slots和vue2的区别 vue3:this.slots是一个{ [name: string]: (…args: any[]) => Array | undefined }的对象,每个具名插槽的内容都要通过函数调用.如v-slot:foo插槽分发的内容通过th

  • 详解Vue中使用插槽(slot)、聚类插槽

    一.基本的插槽 这里总结两点 如果不在子组件中使用插槽(slot),那么在子组件中写任何代码都是无效的的,不会显示 (插槽默认值)如果子组件中没有插入任何代码的话就会显示组件插槽中的内容 slot 代表父组件往子组件中 插入的标签 这里就代表组件子组件中的 <p>Dell</p> <child> <p>Dell</p> </child> 这里如果是这样的 <child> </child> 就会显示 <sl

  • JavaScript--在Vue中使用插槽:slot

    目录 在Vue中使用插槽:slot 作用域插槽:使用template标签包裹 总结 在Vue中使用插槽:slot 1.在子组件的template里可以直接使用slot标签<slot></slot>,它可以显示父组件向子组件插入的内容. 2.slot标签里面可以写一些默认值,当父组件没有插入内容的时候它就会显示默认值,插入内容时就只显示插入的内容. 3.当使用多个slot标签时,直接插入多个内容时,每个slot标签内都会包括所有插入的内容. 可以通过slot属性给插入的不同内容设置指

  • vue3中轻松实现switch功能组件的全过程

    what 编程语言里面,除了使用 if 语句来做条件判断,还有另外一个常用的就是 switch 了. 而在 vue 中,官方已经帮助我们实现了 v-if 这个指令,但是还没有 switch ,那我们能不能自己实现一个呢? 这篇文章就是来探索这个问题,并且最终实现一个 Switch 组件 以终为始 先来看看我们希望用户是如何使用 Switch 的 用 js 的方式来对比一下: 用户可以通过一个 VSwitch 组件来应用 switch 功能 通过 case 来确定匹配的条件 然后每一个 case

  • Vue.js slot插槽的作用域插槽用法详解

    目录 没有插槽的情况 Vue2.x 插槽 有插槽的情况 具名插槽 没有slot属性 插槽简单实例应用 作用域插槽 ( 2.1.0 新增 ) Vue3.x 插槽 插槽 作用域插槽 没有插槽的情况 <div id="app"> <child> <span>1111</span> </child> </div> <script> // 注册子组件 Vue.component("child"

  • vue3中的props组件抽离

    目录 props组件抽离 引言 场景 组件模板抽离的写法 props组件抽离 引言 假设你已经了解了Vue3的setup函数,不了解的话可以先看看这篇文章. vue3中setup函数的使用 在setup函数中我们知道它有两个参数,用于接收父组件传递参数的props.与负责表示上下文对象的context,在context中常用的是分发自定义事件的函数emit,用于组件抽象化后的通信. 在了解了概念后我们可以在本文中动手抽象分离一个组件. 场景 现在假设需要抽象出一个移动端的顶部Header组件,首

随机推荐