Vue之组件基础(插槽)

news2025/1/14 0:59:59

在HTML中,开发者可以在双标签内添加一些信息。而在Vue中,组件以标签的形式引用,那么如何在组件的标签内添加一些信息并将信息渲染到页面中呢?其实,Vue 提供了插槽,专门用来实现这样的效果。


一.什么是插槽

Vue为组件的封装者提供了插槽(slot),插槽是指开发者在封装组件时不确定的、希望由组件的使用者指定的部分。也就是说,插槽是组件封装期间为组件的使用者预留的占位符,允许组件的使用者在组件内展示特定的内容。通过插槽,可以使组件更灵活、更具有可复用性。

插槽需要定义后才能使用,下面对定义插槽和使用插槽分别进行讲解。


1.定义插槽

在封装组件时,可以通过<sot>标签定义插槽,从而在组件中预留占位符。假设项目中有一个 MyButton组件,在MyButton 组件中定义插槽的示例代码如下。

<template>
    <button>
        <slot></slot>
    </button>
</template>

        在上述代码中,第3行代码通过<slot>标签定义了一个插槽,父组件提供的插槽内容将在该标签所在的位置被渲染。MyButon组件仅负责渲染<slot>标签外部的DOM元素以及相应的样式。

        在<slot>标签内可以添加一些内容作为插槽的默认内容。如果组件的使用者没有为插槽提供任何内容,则默认内容生效;如果组件的使用者为插槽提供了插槽内容,则该插槽内容会取代默认内容。

     另外,如果一个组件没有预留任何插槽,则组件的使用者提供的任何插槽内容都会起作用。

2.使用插槽

        使用插槽即在父组件中使用子组件的插槽,在使用时需要将子组件写成双标签的形在双标签内提供插槽内容。例如,使用MyButton组件的插槽的示例代码如下。

<template>
    <MyButton>
        按钮
    </MyButton> 
</template>

        在上述代码中,第 2~4行代码将 MyButton 组件写成了双标签的形式,开始标签和结束标签之间的内容就是插槽内容。
        因为插槽内容是在父组件模板中定义的,所以在插槽内容中可以访问到父组件的数据插槽内容可以是任意合法的模板内容,不局限于文本。例如,可以使用多个元素或者组件作为插槽内容,示例代码如下。

<MyButton>
    <span style-"color:yellow;">按钮</span>
<MyLeft />
</MyButton>

        在上述代码中,第2行代码定义了 span 元素用于展示文字信息;第3行代码用于展示MvLet 组件中的内容。
        接下来通过实际操作的方式演示插槽的使用方法,具体步骤如下。① 创建src\components\SlotSubComponent.vue 文件,用于展示子组件的相关内容,具体代码如下。

<template>
    <div>测试插槽的组件</div>
    <slot></slot>
</template>

        在上述代码中,第3行代码用于定义一个插槽。
②创建 src\components\MySlot.vue 文件,用于展示插槽的相关内容,具体代码如下。

<template>
    父组件-----{{message }}
    <hr>
    <SlotSubComponent>
        <p>{{ message }}</p>
    </SlotSubComponent>
</template>
<scrip setup>
import SlotSubComponent from './SlotSubComponent .vue'
    const message ='这是组件的使用者自定义的内容'
 </script>

        在上述代码中,第2行代码用于输出 message 的值;第4~6行代码用于以标签的形式引用SlotSubComponent 组件;第5行代码将 message 的值作为插槽内容传递给 SlotSubComponent组件;第9行代码用于通过 import 语法将 SlotSubComponent 组件导人 MySlot 组件;第 10行代码用于定义 message 数据。
③ 修改 srcmain.js,切换页面中显示的组件,示例代码如下。

import App from'./components/MySlot.vue'

保存上述代码后,在浏览器中访问 http://127.0.0.1:5173/,使用插槽后的页面效果如图所示。

从图可以看出,将组件的使用者自定义的内容在页面中成功渲染出来了。

接下来演示插槽的默认内容,实现当组件的使用者没有自定义内容时默认内容生效的效果,具体步骤如下。

① 注释 MySlo组件中插槽内容,具体代码如下。

<!--<p>{{ message }}</p> -->

②在 SloSubComponem 组件中为<sot>标签提供默认内容,具体代码如下。

<slot>
    <p>这是默认内容</p>
</slot>

        在上述代码中、第2 行代码为新增代码,模拟组件的使用者没有自定义内容时显示 </slot>

标签中的内容。

保存上述代码后,插槽提供默认内容的页面效果如图所示。

        从图可以看出,由于组件的使用者没有自定义内容,所以在封装组件时为插槽据供的默认内容在页面中显示出来。
        将 Myslot 组件中的插槽内容取消注释,保存代码后,页面效果与第一张图相同。说明当组件的使用者自定义内容时,插槽中定义的默认内容不生效。


二.具名插槽

        在 Vue 中当需要定义多个插槽时,可以通过具名插槽来区分不同的插槽。具名插槽是给每一个插槽定义一个名称,这样就可以在对应名称的插槽中提供对应的数据了。

插槽通过<slot>标签来定义,<slot>标签有一个 name 属性,用于给各个插槽分配唯一的名称,以确定每一处要渲染的内容。添加name 属性的<slot>标签可用来定义具名插槽。

定义具名插槽的语法格式如下。

<slot name="插槽名称"></slot>

        在上述语法格式中,通过 name属性定义了插槽名称。

        在父组件中,如果要把内容填充到指定名称的插槽中,可以通过一个包含 v-sot 指的<template>标签来实现,语法格式如下。

<组件名>
    <template v-slot:插槽名称></template>
 </组件名>

        在上述语法格式中,第1~3行代码以标签的形式引用子组件,其中第2行代码用邘<template>标签包裹的内容传人子组件的对应插槽名称的插槽中。

与yon和v-bhind 类似,v-slot也有简写形式。即把v-slot:替换为#。例如,v-slot:title可以简写为#itle。

接下来通过实际操作的方式演示具名插槽的使用,具体步骤如下。

① 创建 sre\components\Artclelnfo.vue 文件,用于展示文章内容模板,具体代码如下。

<template>
    <div class-"article-container">
    <div class="header-box">
        <slot name="header"></slot>
    </div>
    <div class-"content-box">
        <slot name="content"></slot>
</div><div class="footer-box">
    <slot name="footer"></slot>
</div>
 </div>
 </template>
<style> 
.article-container > div { 
        border: 1px solid black;
}
</style>

        在上述代码中,第1~13 行代码定义了模板,其中,第 4、7、10 行代码通过<slot>标签定义了插槽,并为<slot>标签添加了 name 属性,用于为每个插槽指定具体的名称,名称分别为 header、content、footer;第 15~17 行代码设置了<div>标签的样式,设置了 1px 的黑色实线边框。

② 创建 src\components\MyArticle.vue 文件,用于提供文章数据,在 MyArticle 组件中导人并使用 Articlelnfo 组件,并在<Articlelnfo>标签中为不同插槽添加不同的信息,具体代码如下。

<template>
    <ArticleInfo>
    <template v-slot:header>
    <p>这是文章的头部区域</p>
</template>
<template v-slot:content>
    <p>这是文章的内容区域</p>
</template>
<template #footer>
    <p>这是文章的尾部区域</p>
</template>
    </ArticleInfo>
</template>
<script setup>
 import ArticleInfo from ./ArticleInfo.vue
</script>

        在上述代码中,第3、6、9行代码在<template>标签上使用了 v-slot 指令,分别向名称为 header、content、footer 的具名插槽提供了内容。

③ 修改 sre\main.js,切换页面中显示的组件,示例代码如下。

import App from'./components/MyArticle.vue'

保存上述代码后,在浏览器中访问 hp:/127.0.0.1:5173/,使用具名插槽的页面效果如图所示。

        从图 可以看出,已经成功将对应的内容放置到插槽名称为header、content、footer的插槽中。


三.作用域插槽

        一般情况下,在父组件中不能使用子组件中定义的数据。如果想要在父组件中使用子组件中定义的数据,则需要通过作用域插槽来实现。作用域插槽是带有数据的插槽,子组件提供一部分数据给插槽,父组件接收子组件的数据进行页面渲染。

        作用域插槽的使用分为定义数据和接收数据两个部分,下面分别进行讲解。

1.定义数据

        在封装组件的过程中,可以为预留的插槽定义数据,供父组件接收并使用子组件中的数据。在作用域插槽中,可以将数据以类似传递props 属性的形式添加到<slot>标签上。

        例如,在封装 MyHeader 组件时,在插槽中定义数据供父组件使用,示例代码如下。

<slot message="Hello Vue.js"></slot>

        在上述代码中,在定义插槽时定义了message 属性,表示可以从子组件传递到父组件的信息。

2.接收数据

        使用默认插槽和具名插槽接收数据的方式不同,接下来分别进行讲解。

(1)默认插槽

        在 Vue 中,每个插槽都有 name 属性,表示插槽的名称。在定义插槽时虽然省略了<slot>标签的 name 属性,但是 name 属性默认为 defaut,这样的插槽属于默认插槽。

        在父组件中可以通过 v-slot 指令接收插槽中定义的数据,即接收作用域插槽对外提供的数据。通过v-slot指令接收到的数据可以在插槽内通过 Mustache语法进行访问。

        例如,在父组件中使用 MyHeader 组件中的插槽时,通过v-slot 指令的值接收传递的数据的示例代码如下。

<MyHeader v-slot="scope">
    <p>{{ scope.message }}</p>
 </MyHeader>

        在上述代码中,通过 v-slot 接收从作用域插槽中传递的数据,scope 为形参,表示从作用域插槽中接收的数据,该形参的名称可以自定义。第2行代码通过 Mustache 语法将数据在页面中输出。

        作用域插槽对外提供的数据对象可以使用解构赋值以简化数据的接收过程,示例代码如下。

<MyHeader v-slot="{ message }">
    <p>{{ message }}</p>
</MyHeader>


        在上述代码中,第1行代码通过解构赋值解构对象,解构后子组件中定义的数据可以直接访问,而不是以“形参.属性”的方式访问。

(2)具名插槽

        在 Vue 中,通过<slot>标签添加 name 属性来定义具名插槽,在具名插槽中也可以向父组件中传递数据。

        例如,在封装 MyHeader 组件时,向具名插槽中传入数据的语法格式如下。

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

        具名插槽和作用域插槽可以作用在同一个<slot>标签上且并不冲突。<slot>标签的 name属性不会作为数据传递给插槽,所以最终传递给组件的数据只有message属性。

        在使用具名插槽时,插槽属性可以作为v-slot的值被访问到,基本语法格式为“v-slot插槽名称="形参"”,简写形式为“#插槽名称="形参"”,使用简写形式来使用插槽的示例代码如下。

<MyHeader>
    <template #header="{ message }">
        {{ message }}
    </template>
</MyHeader>

        如果在一个组件中同时定义了默认插槽和具名插槽,并且它们均需要为父组件提供数据,这时就需要为默认插槽使用显式的<template>标签来接收数据,示例代码如下。

<MyHeader>
    <template #default="{ message }">
        {{ message )}
    </template>
</MyHeader>

接下来通过实际操作的方式演示作用域插槽的使用,具体步骤如下。

① 创建 sre\components\SubScopeSlot.vue 文件,用于展示作用域插槽,具体代码如下。

<template>
    <slot message="Hello 默认插槽"></slot>
    <hr>
    <slot message="Hello Vue.js" name="header"></slot>
    <hr>
    <slot user="user" name="content"></slot>
    </template>
 <script setup> 
import {reactive }from 'vue'
 const user = reactive({ name; 'xiaoyuan',age:'15’})
</script>

在上述代码中,第 2、4、6 行代码分别定义了一个插槽,分别定义了不同的需要传到父组件中的数据,这样父组件可以使用Scopeslo 组件中的数据。其中、第2行代码定了一个默认插槽:第4、6行代码定义了一个具名插槽,名称分别为 header、content。第。行代码导入了 maeuve()函数。第 10行代码定义了页面所需的数据,user 对象表示用户信息,其中 name 属性表示用户名称,age 属性表示用户年龄。

②创建 srecomponents\Scopeslot.vue 文件,用于为作用域插槽提供数据,具体代码如下。
 

<template>
    <SubScopeSlot>
    <template v-slot:default="scope">
    <p>{{ scope }}</p>
</template>

<template v-slot:header="scope">
    <p>{{ scope }}</p>
    <p>{{ scope.message }}</p>
</template>

<template #content="{ user }">
    <p>{{ user.name }}</p>
    <p>{{ user.age }}</p>
</template>

    </SubScopeSlot>
 </template>
<script setup>
import SubScopeSlot from './SubScopeSlot .vue'
</script>

        在上述代码中,第 3~5行代码定义了默认插槽;第6~9行代码定义了名称为 heade的作用域插槽,该插槽提供的数据通过 v-slot 指令的属性值 scope 接收;第 10~13 行代码定义了名称为 content 的作用域插槽,该插槽提供的数据使用解构赋值以简化数据的接收过程;第17行代码在 SeopeSlot 组件中导人了 SubScopeSlot 组件。

③ 修改 src\main.js,切换页面中显示的组件,示例代码如下。

import App from './components/ScopeSlot.vue'

保存上述代码后,在浏览器中访问bup:/127.0.0.1:5173/,作用域插槽的页面效果如图所示。

从图可以看出,成功接收到作用域插槽对外提供的数据并在页面上成功富染出来。


感谢大家的阅读,如有不对的地方,可以私信我,感谢大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1720725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么使用Python代码在图片里面加文字

在Python中&#xff0c;给图片添加文字可以使用Pillow库&#xff08;PIL的一个分支&#xff09;&#xff0c;它是一个强大的图像处理库。如果你还没有安装Pillow&#xff0c;可以通过pip安装&#xff1a; pip install Pillow下面使用一个简单的示例&#xff0c;演示如何使用Pi…

系统架构设计师【第9章】: 软件可靠性基础知识 (核心总结)

文章目录 9.1 软件可靠性基本概念9.1.1 软件可靠性定义9.1.2 软件可靠性的定量描述9.1.3 可靠性目标9.1.4 可靠性测试的意义9.1.5 广义的可靠性测试与狭义的可靠性测试 9.2 软件可靠性建模9.2.1 影响软件可靠性的因素9.2.2 软件可靠性的建模方法9.2.3 软件的可靠性模…

CISCN 2023 初赛 被加密的生产流量

题目附件给了 modbus.pcap 存在多个协议 但是这道题多半是 考 modbus 会发现 每次的 Query 末尾的两个字符 存在规律 猜测是base家族 可以尝试提取流量中的数据 其中Word Count字段中的22871 是10进制转16进制在转ascii字符串 先提取 过滤器判断字段 tshark -r modbus.pcap …

java线程状态介绍

1.新建&#xff08;New&#xff09;: 线程对象已创建&#xff0c;但还没有调用 start() 方法。 2.可运行&#xff08;Runnable&#xff09;: 线程已启动&#xff0c;处于就绪状态&#xff0c;等待 JVM 的线程调度器分配CPU时间。 3.阻塞&#xff08;Blocked&#xff09;: 线程…

自动化桌面整理新时代:Llama 3驱动的智能文件管理系统

在信息爆炸的时代,个人和企业用户的电脑桌面常常被海量文件占据,导致查找特定文件如同大海捞针。为了解决这一痛点,Llama 3应运而生——一个集成了先进多模态AI技术的智能文件管家,旨在将杂乱无章的文件世界变得井然有序。本文将深入探讨Llama 3如何利用其创新功能,不仅自…

上传RKP 证书签名请求息上传到 Google 的后端服务器

上传证书签名请求 1.准备环境&#xff1a;OK pip3 install google-auth2.13.0 requests2.28下载 device_info_uploader.py 。 没找到先跳过 选项 1&#xff1a;通过 GCP 帐户使用 device_info_uploader.py 运行脚本。 ./device_info_uploader.py --credentials /secure/s…

简要分析学习spring内存马,劫持马

简要分析学习spring内存马&#xff0c;劫持马 本文主要是通过SpringMemShell这个工程&#xff0c;来对spring内存马进行演示&#xff0c;利用。 写在前面&#xff1a; 参考的是大佬给的流程以及思路,其中的解释与分析非常详细 ----->>大佬的链接 这里的内存马文件取自gi…

python采集汽车价格数据

python采集汽车价格数据 一、项目简介二、完整代码一、项目简介 本次数据采集的目标是车主之家汽车价格数据,采集的流程包括寻找数据接口、发送请求获取响应、解析数据和持久化存储,先来看一下数据情况,完整代码附后: 二、完整代码 #输入请求页面url #返回html文档 imp…

Scikit-Learn 基础教程

目录 &#x1f40b;Scikit-Learn 基础教程 &#x1f40b;Scikit-Learn 简介 &#x1f40b; 数据预处理 &#x1f988;数据集导入 &#x1f988;数据清洗 &#x1f988;特征选择 &#x1f988;特征标准化 &#x1f40b; 模型选择 &#x1f988;分类模型 &#x1f988;回…

Resilience4j结合微服务出现的异常

Resilience4j结合微服务出现的异常 1、retry未生效 由于支持aop&#xff0c;所以要引入aop的依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>2、circ…

解决:【无法安装“vue.volar“扩展,因为它与当前 VIsual Studio Code 版本不兼容(版本 1.80.0)】

目录 问题复现问题分析解决步骤1、进入VSCode插件市场&#xff0c;搜索Vue.volar2、点击搜索结果&#xff0c;进入详情页面3、下载.vsix文件完成后&#xff0c;用解压软件打开 4、复制package.json文件&#xff0c;修改vscode版本5、保存package.json文件&#xff0c;并更新.v…

2024 HN CTF WebMisc 部分 wp

Web ez_tp 判断是thinkphp 3.2 参考官方手册:https://www.kancloud.cn/manual/thinkphp/1697 判断路由模式 URL_CASE_INSENSITIVE > true, // 默认false 表示URL区分大小写 true则表示不区分大小写URL_MODEL > 1, // URL访问模式,可选参数0、1、…

cURL error 60: SSL certificate problem: unable to get local issuer certifica

本地小程序把接口换到本地的服务器接口&#xff0c;然后就报错了&#xff1a; cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) 经查询查到&#xff1a;此问题的出现是由于没有配…

第八十九周周报

学习目标&#xff1a; 论文 学习时间&#xff1a; 2024.05.25-2024.05.31 学习产出&#xff1a; 一、论文 SAN: INDUCING METRIZABILITY OF GAN WITH DISCRIMINATIVE NORMALIZED LINEAR LAYER 将GAN与切片最优输运联系起来&#xff0c;提出满足方向最优性、可分离性和单射…

数据资产价值如何评估?一文详解如何构建数据资产评估的综合框架

数据资产&#xff0c;如同其构成的数据本身&#xff0c;具备物理、存在和信息三重属性。数据资产的物理属性体现在其对存储空间的占用&#xff1b;其存在属性则体现在数据的可读取性上&#xff0c;若数据无法读取&#xff0c;则其作为资产的价值便无从体现。这两个属性共同构成…

LeetCode 算法: 字母异位词分组c++

原题链接&#x1f517;&#xff1a;字母异位词分组 难度&#xff1a;中等⭐️⭐️ 题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“e…

centos7.9离线安装mysql5.7

centos7.9离线安装mysql5.7 查询mysql查询组查询用户不存在创建即可&#xff0c;创建mysql用户组上传下载的安装包创建my.cnf文件修改配置文件修改mysql登陆密码 centos7.9 mysql5.7 查询mysql rpm -qa | grep mysql我这里查询是不存在&#xff0c;如果你的存在可以用rm -rf […

云原生架构相关技术_4.服务网格

1.技术特点 服务网格&#xff08;ServiceMesh&#xff09;是分布式应用在微服务软件架构之上发展起来的新技术&#xff0c;旨在将那些微服务间的连接、安全、流量控制和可观测等通用功能下沉为平台基础设施&#xff0c;实现应用与平台基础设施的解耦。这个解耦意味着开发者无需…

ROS2在RVIZ2中加载机器人urdf模型

参考ROS2-rviz2显示模型 我这边用的solid works生成的urdf以及meshes&#xff0c;比参考的方法多了meshes 问题一&#xff1a;Error retrieving file [package://rm_dcr_description/meshes/leftarm_link7.STL]: Package [rm_dcr_description] does not exist 这个是urdf模型中…

react 怎样配置ant design Pro 路由?

Ant Design Pro 是基于 umi 和 dva 的框架&#xff0c;umi 已经预置了路由功能&#xff0c;只需要在 config/router.config.js 中添加路由信息即可。 例如&#xff0c;假设你需要为 HelloWorld 组件创建一个路由&#xff0c;你可以将以下代码添加到 config/router.config.js 中…