vue3-内置组件-Teleport

news2025/1/18 16:58:55

Teleport

<Teleport> 是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。

基本用法

有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在 DOM 中应该被渲染在整个 Vue 应用外部的其他地方。

这类场景最常见的例子就是全屏的模态框。理想情况下,我们希望触发模态框的按钮和模态框本身是在同一个组件中,因为它们都与组件的开关状态有关。但这意味着该模态框将与按钮一起渲染在应用 DOM 结构里很深的地方。这会导致该模态框的 CSS 布局代码很难写。

试想下面这样的 HTML 结构:

<div class="outer">
  <h3>Tooltips with Vue 3 Teleport</h3>
  <div>
    <MyModal />
  </div>
</div>

接下来我们来看看 <MyModal> 的实现:

<script setup>
import { ref } from 'vue'

const open = ref(false)
</script>

<template>
  <button @click="open = true">Open Modal</button>

  <div v-if="open" class="modal">
    <p>Hello from the modal!</p>
    <button @click="open = false">Close</button>
  </div>
</template>

<style scoped>
.modal {
  position: fixed;
  z-index: 999;
  top: 20%;
  left: 50%;
  width: 300px;
  margin-left: -150px;
}
</style>

这个组件中有一个 <button> 按钮来触发打开模态框,和一个 class 名为 .modal 的 <div>,它包含了模态框的内容和一个用来关闭的按钮。

当在初始 HTML 结构中使用这个组件时,会有一些潜在的问题:

position: fixed 能够相对于浏览器窗口放置有一个条件,那就是不能有任何祖先元素设置了 transform、perspective 或者 filter 样式属性。也就是说如果我们想要用 CSS transform 为祖先节点 <div class="outer"> 设置动画,就会不小心破坏模态框的布局!

这个模态框的 z-index 受限于它的容器元素。如果有其他元素与 <div class="outer"> 重叠并有更高的 z-index,则它会覆盖住我们的模态框。

<Teleport> 提供了一个更简单的方式来解决此类问题,让我们不需要再顾虑 DOM 结构的问题。让我们用 <Teleport> 改写一下 <MyModal>:

<button @click="open = true">Open Modal</button>

<Teleport to="body">
  <div v-if="open" class="modal">
    <p>Hello from the modal!</p>
    <button @click="open = false">Close</button>
  </div>
</Teleport>

<Teleport> 接收一个 to prop 来指定传送的目标。to 的值可以是一个 CSS 选择器字符串,也可以是一个 DOM 元素对象。这段代码的作用就是告诉 Vue“把以下模板片段传送到 body 标签下”。

我们也可以将 <Teleport> 和 <Transition> 结合使用来创建一个带动画的模态框。

<Teleport> 挂载时,传送的 to 目标必须已经存在于 DOM 中。理想情况下,这应该是整个 Vue 应用 DOM 树外部的一个元素。如果目标元素也是由 Vue 渲染的,你需要确保在挂载 <Teleport> 之前先挂载该元素。

我们也可以将 <Teleport> 和 <Transition> 结合使用来创建一个带动画的模态框。

// 模态组件
<script setup>
const props = defineProps({
  show: Boolean
})
</script>

<template>
  <Transition name="modal">
    <div v-if="show" class="modal-mask">
      <div class="modal-container">
        <div class="modal-header">
          <slot name="header">默认头部</slot>
        </div>

        <div class="modal-body">
          <slot name="body">默认内容</slot>
        </div>

        <div class="modal-footer">
          <slot name="footer">默认底部</slot>
        </div>
        <button class="modal-default-button" @click="$emit('close')">OK</button>
      </div>
    </div>
  </Transition>
</template>

<style>
....
....
....
样式太多省略了 看效果图即可
...
...
...
</style>



// 父级页面
<script lang="ts" setup>
import { ref } from 'vue'

import Com24 from '@/components/demo/Com24.vue'
const showModal = ref(false)
</script>

<template>
  <div class="container">
    <button id="show-modal" @click="showModal = true">开启模态窗</button>

    <Teleport to="body">
      <!-- 使用这个 modal 组件,传入 prop -->
      <Com24 :show="showModal" @close="showModal = false">
        <template #header>
          <h3>自定义标题</h3>
        </template>
      </Com24>
    </Teleport>
  </div>
</template>

<style lang="scss" scoped>
.container {
}
</style>

搭配组件使用

<Teleport> 只改变了渲染的 DOM 结构,它不会影响组件间的逻辑关系。也就是说,如果 <Teleport> 包含了一个组件,那么该组件始终和这个使用了 <teleport> 的组件保持逻辑上的父子关系。传入的 props 和触发的事件也会照常工作。

这也意味着来自父组件的注入也会按预期工作,子组件将在 Vue Devtools 中嵌套在父级组件下面,而不是放在实际内容移动到的地方。

禁用 Teleport

在某些场景下可能需要视情况禁用 <Teleport>。举例来说,我们想要在桌面端将一个组件当做浮层来渲染,但在移动端则当作行内组件。我们可以通过对 <Teleport> 动态地传入一个 disabled prop 来处理这两种不同情况。

<Teleport :disabled="isMobile">
  ...
</Teleport>

这里的 isMobile 状态可以根据 CSS media query 的不同结果动态地更新。

多个 Teleport 共享目标

一个可重用的模态框组件可能同时存在多个实例。对于此类场景,多个 <Teleport> 组件可以将其内容挂载在同一个目标元素上,而顺序就是简单的顺次追加,后挂载的将排在目标元素下更后面的位置上。

<Teleport to="#modals">
  <div>A</div>
</Teleport>
<Teleport to="#modals">
  <div>B</div>
</Teleport>

渲染的结果为:

<div id="modals">
  <div>A</div>
  <div>B</div>
</div>

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

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

相关文章

如何通过ETL实现快速同步美团订单信息

一、美团外卖现状 美团作为中国领先的生活服务电子商务平台&#xff0c;其旗下的美团外卖每天承载着大量的订单信息。这些订单信息需要及时入库、清洗和同步&#xff0c;但由于数据量庞大且来源多样化&#xff0c;传统的手动处理方式效率低下&#xff0c;容易出错。比如&#…

盒子模型...

一&#xff0c;盒子模型 1.1网页布局的本质 1先准备好相关的网页元素&#xff0c;网页元素基本都是盒子BOX。 2利用CSS设置好盒子样式&#xff0c;然后摆放到相应位置。 3往盒子里面装内容。 1.2盒子模型 CSS盒子模型本质是一个盒子&#xff0c;封装周围的HTML元素&#xff…

结构体的大小以及内存对齐问题

结构体的大小怎么计算&#xff1f;什么是结构体的对齐&#xff1f; 首先想要直到结构体的大小需要先了解结构体的内存对齐。那么&#xff0c;什么是结构体的内存对齐&#xff1a; 什么是结构体内存对齐 结构体的对齐 就是 结构体类型数据在内存中按照一定的对齐规律储存。结…

【开源】SpringBoot框架开发校园电商物流云平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 商品数据模块2.3 快递公司模块2.4 物流订单模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 商品表3.2.2 快递公司表3.2.3 物流订单表 四、系统展示五、核心代码5.1 查询商品5.2 查询快递公司5.3 查…

Go语言每日一练——链表篇(四)

传送门 牛客面试笔试必刷101题 ----------------合并两个排序的链表 题目以及解析 题目 解题代码及解析 package main import _"fmt" import . "nc_tools" /** type ListNode struct{* Val int* Next *ListNode* }*//*** 代码中的类名、方法名、参…

unity——ScriptableObject相关知识点【学习笔记/不足之处欢迎斧正/个人复习向/侵删】

一、相关简介 1.ScriptableObject是什么&#xff1a;Unity提供的一个数据存储基类 2.ScriptableObject的好处有哪些&#xff1a;文件配置、数据复用、更好的处理数据带来的多态性为 二、ScriptableObject的创建 1.自定义ScriptableOject数据容器 继承ScriptableObject类 在…

[BeginCTF]真龙之力

安装程序 双击安装 出现了安装失败的标签&#xff0c;开发者不允许测试。 查看Mainfest入口文件 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android" android:versionCo…

Blender_pmx导出fbx

Blender_pmx导出fbx 学无止境&#xff1f; 相关链接&#xff1a; Blender教程&#xff1a; Blender中文手册介绍 — Blender Manualhttps://docs.blender.org/manual/zh-hans/2.79/about/introduction.htmlhttps://www.blendercn.org/https://www.blendercn.org/Blender下载…

dddddddddddddddddddd

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 磁盘满的本质分析 专栏&#xff1a;《Linux从小白到大神》 | 系统学习Linux开发、VIM/GCC/GDB/Make工具…

深度学习(13)--PyTorch搭建神经网络进行气温预测

一.搭建神经网络进行气温预测流程详解 1.1.导入所需的工具包 import numpy as np # 矩阵计算 import pandas as pd # 数据读取 import matplotlib.pyplot as plt # 画图处理 import torch # 构建神经网络 import torch.optim as optim # 设置优化器 1.2.读取并处理数据…

PWM输入输出

PWM&#xff08;Pulse Width Modulation&#xff09;即脉冲宽度调制&#xff0c;在具有惯性的系统中&#xff0c;可以通过对一系列脉冲的宽度进行制&#xff0c;来等效地获得所需要的模拟参量&#xff0c;常应用于电机控速、开关电源等领域。 PWM参数 PWM 中有三个重要参数&…

代码随想录算法训练营第四十七天(动态规划篇)| 416. 分割等和子集

416. 分割等和子集 题目链接&#xff1a;416. 分割等和子集 - 力扣&#xff08;LeetCode&#xff09; 思路 回溯——超时 首先想到之前的回溯算法&#xff0c;寻找数组中加和等于sum(nums)/2的子集&#xff0c;但对于大数组超时了&#xff1a; class Solution(object):def…

nodejs+vue高校实验室耗材管理系统_m20vy

用户功能&#xff1a; 登录后要有一个首页 比如:可以看见目前的耗材消耗记录&#xff0c;可做成图表菜单栏在左侧显示 1.个人信息管理 可以对基本信息进行修改&#xff0c;(修改密码时需要验证) 2.耗材管理&#xff08;耗材信息&#xff09; 普通用户可以查询当前相关耗材信息[…

[Java][算法 哈希]Day 01---LeetCode 热题 100---01~03

LeetCode 热题 100---01~03 ------->哈希 第一题 两数之和 思路 最直接的理解就是 找出两个数的和等于目标数 这两个数可以相同 但是不能是同一个数字&#xff08;从数组上理解就是内存上不是同一位置&#xff09; 解法一&#xff1a;暴力法 暴力解万物 按照需求 …

C++类型转化cast from pointer to smaller type ‘int‘ loses information

代码如下 #include <iostream>int main() {int a 10;std::cout << (int)&a << std::endl;return 0; }编译 这段代码是要将地址转化成整数类型&#xff0c;但是在编译时编译器告诉我们这是错的&#xff0c;因为在C中&#xff0c;将指针转换为int类型的…

Codeforces Edu 74 E. Keyboard Purchase 【状压DP +贡献】

E. Keyboard Purchase 题意 给定一个长度为 n n n 的字符串 s s s 仅由前 m m m 个小写字母组成 现在要求求出包含前 m m m 个小写字母的键盘&#xff0c;使得在键盘上敲出 s s s 要移动的距离最短 移动总距离为&#xff1a; ∑ i 2 n ∣ p o s s i − 1 − p o s s i…

LabVIEW热电偶自动校准系统

设计并实现一套基于LabVIEW平台的工业热电偶自动校准系统&#xff0c;通过自动化技术提高校准效率和精度&#xff0c;降低人力成本&#xff0c;确保温度测量的准确性和可靠性。 工业生产过程中&#xff0c;温度的准确测量对产品质量控制至关重要。传统的热电偶校准方式依赖人工…

昆仑万维发布天工 2.0 大语言模型及AI助手App;AI成功破解2000年前碳化古卷轴

&#x1f989; AI新闻 &#x1f680; 昆仑万维发布天工 2.0 大语言模型及AI助手App 摘要&#xff1a;昆仑万维近日推出了新版MoE大语言模型“天工 2.0”和相应的“天工 AI 智能助手”App&#xff0c;宣称为国内首个面向C端用户免费的基于MoE架构的千亿级参数大模型应用。天工…

MacOS上怎么把格式化成APFS的U盘或者硬盘格式化回ExFAT?

一、问题 MacOS在更新MacOS Monterey后或者更高系统后发现&#xff0c;格式U盘或者硬盘只有4个APFS选项&#xff0c;那么我们该如何将APFS格式成ExFAT&#xff1f; 二、解答 将APFS的U盘或者硬盘拓展成MacOS的拓展格式即可&#xff0c;操作步骤如下 1、电脑接入U盘或者硬盘 2…

从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder [9,15,7,20,3] 输出&#xff1a;[3…