vue3-深入组件-插槽

news2024/11/27 8:49:09

插槽 Slots

组件用来接收模板内容

插槽内容与出口

<slot> 元素是一个插槽出口 (slot outlet),,标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。

插槽内容可以是任意合法的模板内容,不局限于文本。例如我们可以传入多个元素,甚至是组件:

<FancyButton>
  <span style="color:red">Click me!</span>
  <AwesomeIcon name="plus" />
</FancyButton>

渲染作用域

插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的。举例来说:

<span>{{ message }}</span>
<FancyButton>{{ message }}</FancyButton>

这里的两个 {{ message }} 插值表达式渲染的内容都是一样的。

插槽内容无法访问子组件的数据。

父组件模板中的表达式只能访问父组件的作用域;子组件模板中的表达式只能访问子组件的作用域。

默认内容

在外部没有提供任何内容的情况下,可以为插槽指定默认内容。

<SubmitButton\> 组件

<button type="submit">
  <slot></slot>
</button>

如果我们想在父组件没有提供任何插槽内容时在 <button> 内渲染“Submit”,只需要将“Submit”写在 <slot> 标签之间来作为默认内容:

<button type="submit">
  <slot>
    Submit <!-- 默认内容 -->
  </slot>
</button>

如果写入内容

<SubmitButton>Save</SubmitButton>

则会被渲染为

<button type="submit">Save</button>

具名插槽

有时在一个组件中包含多个插槽出口是很有用的。举例来说,在一个 <BaseLayout\> 组件中,有如下模板:

<div class="container">
  <header>
    <!-- 标题内容放这里 -->
  </header>
  <main>
    <!-- 主要内容放这里 -->
  </main>
  <footer>
    <!-- 底部内容放这里 -->
  </footer>
</div>

对于这种场景,<slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 <slot\> 出口会隐式地命名为“default”。

使用具名插槽

要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:

  <BaseLayout>
  <template v-slot:header>
    <!-- header 插槽的内容放这里 -->
  </template>
</BaseLayout>
  • v-slot 有对应的简写 “#”,

  • <template v-slot:header\> 简写为<template #header\>其意思就是“将这部分模板片段传入子组件的 header 插槽中”。

完整代码

<BaseLayout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

  <template #default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</BaseLayout>

当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非 <template> 节点都被隐式地视为默认插槽的内容。所以上面也可以写成:

<BaseLayout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

  <!-- 隐式的默认插槽 -->
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</BaseLayout>

使用 JavaScript 函数来类比可能更有助于你来理解具名插槽:

// 传入不同的内容给不同名字的插槽
BaseLayout({
  header: `...`,
  default: `...`,
  footer: `...`
})

// <BaseLayout> 渲染插槽内容到对应位置
function BaseLayout(slots) {
  return `<div class="container">
      <header>${slots.header}</header>
      <main>${slots.default}</main>
      <footer>${slots.footer}</footer>
    </div>`
}

动态插槽名

动态指令参数在 v-slot 上也是有效的,即可以定义下面这样的动态插槽名:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>

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

注意这里的表达式和动态指令参数受相同的语法限制:

  1. 动态参数值的限制

动态参数中表达式的值应当是一个字符串,或者是 null。特殊值 null 意为显式移除该绑定。其他非字符串的值会触发警告。

  1. 动态参数语法的限制​

动态参数表达式因为某些字符的缘故有一些语法限制,比如空格和引号,在 HTML attribute 名称中都是不合法的。

作用域插槽

场景 : 插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。

我们也确实有办法这么做!可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes:

<!-- <MyComponent> 的模板 -->
<div>
  <slot :text="greetingMessage" :count="1"></slot>
</div>
默认插槽接收插槽 props
<MyComponent v-slot="slotProps">
  {{ slotProps.text }} {{ slotProps.count }}
</MyComponent>

你可以将作用域插槽类比为一个传入子组件的函数。子组件会将相应的 props 作为参数传给它:

MyComponent({
  // 类比默认插槽,将其想成一个函数
  default: (slotProps) => {
    return `${slotProps.text} ${slotProps.count}`
  }
})

function MyComponent(slots) {
  const greetingMessage = 'hello'
  return `<div>${
    // 在插槽函数调用时传入 props
    slots.default({ text: greetingMessage, count: 1 })
  }</div>`
}

实际上,这已经和作用域插槽的最终代码编译结果、以及手动编写渲染函数时使用作用域插槽的方式非常类似了。

具名作用域插槽

具名作用域插槽的工作方式也是类似的,插槽 props 可以作为 v-slot 指令的值被访问到:v-slot:name="slotProps"。当使用缩写时是这样:

<MyComponent>
  <template #header="headerProps">
    {{ headerProps }}
  </template>

  <template #default="defaultProps">
    {{ defaultProps }}
  </template>

  <template #footer="footerProps">
    {{ footerProps }}
  </template>
</MyComponent>

向具名插槽中传入 props:

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

注意插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽。因此最终 headerProps 的结果是 { message: 'hello' }。

如果你同时使用了具名插槽与默认插槽,则需要为默认插槽使用显式的 标签。尝试直接为组件添加 v-slot 指令将导致编译错误。

<!-- 该模板无法编译 -->
<template>
  <MyComponent v-slot="{ message }">
    <p>{{ message }}</p>
    <template #footer>
      <!-- message 属于默认插槽,此处不可用 -->
      <p>{{ message }}</p>
    </template>
  </MyComponent>
</template>

为默认插槽使用显式的 <template> 标签有助于更清晰地指出 message 属性在其他插槽中不可用:

<template>
  <MyComponent>
    <!-- 使用显式的默认插槽 -->
    <template #default="{ message }">
      <p>{{ message }}</p>
    </template>

    <template #footer>
      <p>Here's some contact info</p>
    </template>
  </MyComponent>
</template>

欢迎关注,后面会有一些资源可以免费获取哟~

分享前后端编程经验,技术干货,技术方案,好用的开发工具和应用软件,人生经验感悟等

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

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

相关文章

版本管理工具git: 谨慎使用git中的撤回操作

文章目录 一、背景二、解决方案1、步骤一2、步骤二 三、参考 一、背景 昨天代码分支提交错了&#xff0c;idea中使用了如下操作&#xff0c;结果代码不见了 二、解决方案 1、步骤一 使用git reflog命令&#xff0c;查看提交记录&#xff0c;找到之前commit操作的哈希值 …

二叉树顺序结构堆实现

目录 Test.c测试代码 test1 test2 test3 &#x1f387;Test.c总代码 Heap.h头文件&函数声明 头文件 函数声明 &#x1f387;Heap.h总代码 Heap.c函数实现 ☁HeapInit初始化 ☁HeapDestroy销毁 ☁HeapPush插入数据 【1】插入数据 【2】向上调整Adjustup❗ …

Java JVM类加载阶段 双亲委派模式

类加载阶段 加载 将类的字节码载入方法区中&#xff0c;内部采用 C 的 instanceKlass 描述 java 类&#xff0c;它的重要 field 有&#xff1a; _java_mirror 即 java 的类镜像&#xff0c;例如对 String 来说&#xff0c;就是 String.class&#xff0c;作用是把 klass 暴露…

中国2023年土地利用现状遥感监测数据

中国2023年土地利用现状遥感监测数据是以2023年美国Landsat 8遥感影像为主要数据源&#xff0c;在2020年通过2020年土地利用数据基础上&#xff0c;通过2020年和2023年两期遥感影像对比分析&#xff0c;人工目视解译生成。 改革开放以来&#xff0c;中国经济的快速发展对土地利…

Docker进阶篇-reids集群

一、集群存储算法 分布式存储的常见算法&#xff1a; 哈希取余分区 一致性哈希算法分区 哈希槽分区 1、哈希取余分区 描述&#xff1a;每次读写操作都是根据公式&#xff1a;Hash(key) % N&#xff08;其中&#xff0c;key是要存入Redis的键名&#xff0c;N是 Redis集群的…

编程实例分享,配件进销存进出库管理系统软件

编程实例分享&#xff0c;配件进销存进出库管理系统软件 一、前言 以下教程以 佳易王配件进出库管理系统软件V16.0为例说明 如上图&#xff0c;左侧为导航栏&#xff0c;分为 系统设置&#xff0c;用户信息设置&#xff0c;出入库开单&#xff0c;统计报表&#xff0c;财务管…

BPF 管理器 bpfman 简介

1. 背景 Fedora 40 提案建议将 bpfman 作为默认的程序管理器 &#xff0c;开源项目 bpfman 可以实现对 eBPF 运行状态的深入了解&#xff0c;从而实现更轻松地管理 eBPF 程序&#xff08;包括加载、卸载、运行状态查看等&#xff09;。该提案还需要 Fedora 工程和指导委员会 (…

1.31学习总结

1.31 1.线段树 2.Bad Hair Day S&#xff08;单调栈&#xff09; 3.01迷宫(BFS连通块问题剪枝)&#xff08;连通性问题的并查集解法&#xff09; 4.健康的荷斯坦奶牛 Healthy Holsteins&#xff08;DFS&#xff09; 线段树与树状数组 线段树和树状数组的功能相似&#xff0c;但…

社交买量:归因统计的核心要素与工具

在当今的社交App推广领域&#xff0c;广告买量已成为企业获取用户的重要手段。然而&#xff0c;如何准确衡量这些买量活动的成效&#xff0c;即用户从广告访问到安装后行为的完整转化路径&#xff0c;一直是运营人员关注的焦点。归因统计是一种评估营销效果的关键技术方案&…

制造业实施QMS质量管理系统的作用是什么?

QMS质量管理系统是一个关键的组织管理工具&#xff0c;用于确保产品和服务的质量符合预期标准&#xff1b;通过有效地实施万界星空科技QMS&#xff0c;组织可以确保产品和服务的质量符合预期标准&#xff0c;提升客户满意度&#xff0c;增强市场竞争力。 一、QMS系统的特点&…

找出最可疑的嫌疑人 - 华为机试真题题解

考试平台&#xff1a; 时习知 分值&#xff1a; 100分&#xff08;第一题&#xff09; 考试时间&#xff1a; 2024-01-31 &#xff08;两小时&#xff09; 题目描述 民警侦办某商场店面盗窃案时&#xff0c;通过人脸识别针对嫌疑人进行编号1-100000。 现在民警在监控记录中发…

Prometheus---图形化界面grafana(二进制)

前言 Prometheus是一个开源的监控以及报警系统。整合zabbix的功能&#xff0c;系统&#xff0c;网络&#xff0c;设备。 proetheus可以兼容网络&#xff0c;设备。容器的监控。告警系统。因为他和k8s是一个项目基金开发的产品&#xff0c;天生匹配k8s的原生系统。容器化和云原…

运动编辑学习笔记

目录 跳舞重建&#xff1a; 深度运动重定向 Motion Preprocessing Tool anim_utils MotionBuilder 跳舞重建&#xff1a; https://github.com/Shimingyi/MotioNet 深度运动重定向 https://github.com/DeepMotionEditing/deep-motion-editin 游锋生/deep-motion-editin…

Three.js学习1:threejs简介及文档本地部署

开一个天坑&#xff0c;Three.js 我觉得未来3D页面一定是一个趋势。 -----------------------------华丽的分割线------------------------- github&#xff1a;https://github.com/mrdoob/three.js/ 官网&#xff1a;Three.js – JavaScript 3D Library Threejs官网中文文…

自学Java的第十八天

一&#xff0c;每日收获 1.数组拷贝 2.数组反转 3.数组添加/扩容 二&#xff0c;新名词与小技巧 三&#xff0c;今天学习中所遇到的困难 一&#xff0c;每日收获 1.数组拷贝 编写代码 实现数组拷贝 将 int[] arr1 {10,20,30}; 拷贝到 arr2 数组 , 要求数据空间是独…

LVGL部件4

一.列表部件 1.知识概览 2.函数接口 1.lv_list_add_btn lv_list_add_btn 是 LittlevGL&#xff08;LVGL&#xff09;图形库中的一个函数&#xff0c;用于向列表&#xff08;list&#xff09;对象中添加一个按钮&#xff08;button&#xff09;。 函数原型为&#xff1a;lv_ob…

DRV8301 踩坑记,Status1 D10 老是 Fault

波形如上&#xff1a; 看第一个时钟出来的数据&#xff08;Status1 读完自动清除&#xff1f;&#xff09;&#xff0c;因此数据是&#xff1a;0x20 输入结构体解析&#xff1a; 可以看到&#xff0c;FETHA_OC了也就是A桥上管过流了&#xff1b; 检查一下硬件看看&#xff1…

【git】git update-index --assume-unchanged(不改动.gitignore实现忽略文件)

文章目录 原因分析&#xff1a;添加忽略文件(取消跟踪)的命令&#xff1a;取消忽略文件(恢复跟踪)的命令&#xff1a;查看已经添加了忽略文件(取消跟踪)的命令&#xff1a; 原因分析&#xff1a; 已经维护的项目&#xff0c;文件已经被追踪&#xff0c;gitignore文件不方便修…

天梯算法Day1整理

Nanami and Arithmetic Sequence 题面 思路 炸鱼题 只有n1的时候&#xff0c;只有一个等差数列&#xff1b; 其余时候&#xff0c;都是都有无数个等差数列。 代码 #include <iostream> using namespace std;int main() {int t, n;cin >> t;while (t--) {cin…

如何使用淘宝客?

1.定义&#xff1a;是一种按成交计费的推广工具&#xff0c;由淘宝客帮助商家推广商品&#xff0c;买家通过推广链接进入完成交易后&#xff0c;商家按照设置佣金支付给淘宝客费用。 2.优势&#xff1a; &#xff08;1&#xff09;展示、点击全免费。 &#xff08;2&#xf…