这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

DOM结构相对比较复杂,层级嵌套比较深的组件内,需要根据相对应的模块业务处理一些逻辑,该逻辑属于当前组件

但是从整个页面应用的视图上看,它在DOM中应该被渲染在整个vue应用外部的其他地方,不能影响组件的结构

比较常见的应用场景:就是全屏的模态框,控制元素的位置,也是可以处理的,但是比较麻烦

在理想情况下,我们希望在具体的组件中,给元素绑定的事件,与具体要控制的DOM元素结构在同一个组件中,具体的位置处,保持一定的相关联性

而不用特意的把一些DOM结构给分离出去,然而,在同一组件中,触发模态框的按钮和模态框本身在同一组件中

因为他们都与组件的开关状态有相关联,模态框与按钮一起渲染在应用DOM结构很深的地方,会导致模态框的css布局位置非常难控制

鉴于这样的场景和困难,Vue官方提供了一个Teleport组件,很好的可以解决这个问题,让开发者不需要顾虑DOM结构的问题

01-组件套组件层次结构很深时

比如:现在有两个组件,父组件,子组件,在后代组件内,添加一个按钮,弹出一个模态框,让它在页面垂直水平居中显示

如下所示,父组件如下所示App.vue

<template>
<div class="App">
我是父组件
<Child />
</div>
</template>
<script setup>
import Child from "./Child.vue"
</script>
<style>
.App {
width: 400px;
height: 400px;
background:red;
}
</style>

如下是Child组件,示例代码如下所示Child.vue,我们需要在孙(后代)组件,添加一个按钮,点击按钮,弹出一个弹框,水平垂直居中显示在页面中央

<template>
<div class="child">
<p>我是子组件</p>
<button @click="isModel=true">打开模态框</button>
<div class="mask-dialog" v-if="isModel">
<div class="box">
<h2>我是标题</h2>
<div>我是弹框内容</div>
<div>
<button @click="isModel=false">关闭</button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
width: 300px;
height:300px;
background:green;
}
/**灰色遮罩层 */
.mask-dialog {
width: 100%;
height:100%;
position:absolute;
left:0;
top:0;
background:rgba(0,0,0,0.5)
} .box {
width: 200px;
height:200px;
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
background:pink;
text-align:center;
}
</style>

上面的子组件中有一个button按钮来触发打开当前组件的模态框,里面存在着控制弹框的显示和隐藏的逻辑,当嵌套的组件比较深,复杂时

如果父级元素存在定位,那在控制子元素的位置时,用csstransform或者position:absolute,参照对象的变更,会破坏布局结构,会出现一些css样式

控制的问题,解决起来会非常的痛苦

那这个Teleport组件就是为了解决这类问题,可以将指定的DOM结构片段,独立于到组件外面去,不受当前组件布局结构的影响

经过Teleport的修改后

<template>
<div class="child">
<p>我是子组件</p>
<button @click="isModel=true">打开模态框</button>
<Teleport to="body">
<div class="mask-dialog" v-if="isModel">
<div class="box">
<h2>我是标题1</h2>
<div>我是弹框内容</div>
<div>
<button @click="isModel=false">关闭</button>
</div>
</div>
</div>
</Teleport>
</div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
width: 300px;
height:300px;
background:green;
}
/**灰色遮罩层 */
.mask-dialog {
width: 100%;
height:100%;
position:absolute;
left:0;
top:0;
background:rgba(0,0,0,0.5)
} .box {
width: 200px;
height:200px;
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
background:pink;
text-align:center;
}
</style>

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

<Teleport to="#some-id">html结构代码</Teleport>
<Teleport to=".some-class">html结构代码</Teleport>
<Teleport to="body">html结构代码</Teleport>
<Teleport to="html">html结构代码</Teleport>

02-Teleport组件

它是Vue官方提供的一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去 也就是一种能够将我们的组件html结构移动到指定位置的技术

<teleport to="移动到指定的位置,可以是html,body,或id,class">
里面是Html结构模板内容
</teleport>

注意

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

这个teleport将指定的模板html,放置到页面当中指定的位置处,它是有条件的,不是可以任意传送的

在安装组件之前,目标元素必须存在,即,目标不能由组件本身呈现,理想情况下应该位于整个Vue组件树之外。

如下代码是不行的

<template>
<div class="header">
<Teleport to=".content">
<div>我是头部的内容</div>
</Teleport> </div>
<div class="footer">
底部内容
<div class="content"></div>
</div>
</template>
<script setup>
</script>
<style lang="less">
h1 {
color: red;
}
</style>

03-需要知道的

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

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

位置移动了,提现在结构模板上,但是数据逻辑依旧存在关联的

04-如何禁用 Teleport

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

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

05-多个 Teleport 共享目标时

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

比如下面这样的用例

<Teleport to=".content">
<div>A</div>
</Teleport>
<Teleport to=".content">
<div>B</div>
</Teleport>

渲染的结果为

<div class="content">
<div>A</div>
<div>B</div>
</div>

总结

这个teleport组件在实际开发中还是很实用的,能够解决当组件嵌套层级很深,而后代组件中的模板,想要脱离当前组件结构,解决css布局层面的干扰,那就可以用这个teleport组件

本文转载于:

https://juejin.cn/post/7217731723509547069

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录-VueJs中如何使用Teleport组件的更多相关文章

  1. Vuejs中slot实现自定义组件header、footer等

    Vuejs中slot实现自定义组件header.footer等 vue中的slot主要负责内容分发,之前有介绍过slot的内容,具体链接:http://www.cnblogs.com/vipzhou/ ...

  2. 记录vue中一些有意思的坑

    记录vue中一些有意思的坑 'message' handler took 401ms 在出现这个之前,我一直纠结于 是如何使用vue-router或者不使用它,通过类似的v-if来实现.结果却出现这个 ...

  3. 深入解析VueJs中的V-bind指令

    v-bind 主要用于属性绑定,比方你的class属性,style属性,value属性,href属性等等,只要是属性,就可以用v-bind指令进行绑定.这次主要介绍了VueJs中的V-bind指令,需 ...

  4. 如何在个人博客引擎 Hexo 中添加 Swiftype 搜索组件

    在您现在看到的我的博客站点,后台使用的是 Hexo 作为博客引擎,但是默认集成的搜索组件是进行 form 提交到 Google 进行搜索的,为了更好地体验,本文介绍如何在 Hexo 博客中集成 Swi ...

  5. 一个Angular模块中可以声明哪些组件?

    一个Angular模块中可以声明哪些组件? (1) controller        控制器 (2) directive                指令 (3) function         ...

  6. C#操作word或excel及水晶报表,检索 COM 类工厂中 CLSID 为 {} 的组件时失败,原因是出现以下错误: 80070005

    解决办法一:<转自http://www.cnblogs.com/Sue_/articles/2123372.html> 具体解决方法如下: 1:在服务器上安装office的Excel软件. ...

  7. .net开发中常用的第三方组件

    .net开发中常用的第三方组件 2013-05-09 09:33:32|  分类: dotnet |举报 |字号 订阅     下载LOFTER 我的照片书  |   RSS.NET.dll RSS. ...

  8. HTML5 UI框架Kendo UI Web中如何创建自定义组件(二)

    在前面的文章<HTML5 UI框架Kendo UI Web自定义组件(一)>中,对在Kendo UI Web中如何创建自定义组件作出了一些基础讲解,下面将继续前面的内容. 使用一个数据源 ...

  9. Delphi 在线程中如何使用TClientSocket组件并自动检测该组件

    在线程中如何使用TClientSocket组件并自动检测该组件的事件?我想在一个线程中动态创建一个TClientSocket组件,并要求该组件能够自动检测Socket事件(例如OnRead.OnErr ...

  10. Oracle生成查询包括对应于所有数据表记录语句中指定的字段名

    应用:已知的字段名,表中的所有数据的查询数据库中包含的所有数据表的字段名 操作方法:指定字段名,用户数据库表,它可以执行以下查询 --Oracle生成查询包括对应于所有数据表记录语句中指定的字段名 d ...

随机推荐

  1. [Java][Spring]spring profile与maven profile多环境管理

    spring profile 与 maven profile 多环境管理 spring profile Spring profile是Spring提供的多环境管理方案. 如下图: 每种环境都对应一个y ...

  2. NC23047 华华给月月出题

    题目链接 题目 题目描述 华华刚刚帮月月完成了作业.为了展示自己的学习水平之高超,华华还给月月出了一道类似的题: \(Ans=\oplus_{i=1}^N(i^N\mod(10^9+7))\) \(\ ...

  3. Linux下磁盘管理工具:hdparm/iostat/parted/fdiisk/badblocks/smartctl/losetup/sg3_utils/sqinfo/smp_utils/udevadm

    一.hdparm:       hdparm可以检测,显示与设定IDE,SCSI,SATA,SAS硬盘的硬件参数,       如: hdparm -I /dev/sdc 可以获取sdc的硬件信息  ...

  4. 使用 MSYS2 编译 exe 可执行程序

    MSYS2 是一个在 Windows上 运行的软件环境,它提供了一种在 Windows 上使用 GNU 工具链的方式,包括 GCC 编译器和 GNU Make 构建系统. 在 MSYS2 中,你可以使 ...

  5. Direct2D 几何篇

    微软文档:Geometries overview 本篇通过官方文档学习,整理出来的demo,初始样本请先创建一个普通的desktop app. // Test_Direct2D_Brush.cpp : ...

  6. nuxt调用weixin-js-sdk

    在nuxt中调用weixin-js-sdk与在vue中有所不同. 通常在vue中用 import wx from 'weixin-js-sdk' 调用weixin-js-sdk,但在nuxt中会出现w ...

  7. contextmanager装饰器

    虽然上下文管理器很好用,但定义一个符合协议的管理器对象其实挺麻烦的 得首先创建一个类,然后实现好几个魔法方法.为了简化这部分工作,python 提供了一个非常好用的工具:@contextmanager ...

  8. mysql安装及增删改查操作---day35

    # ### mysql ''' 命令可以用tab来补全 d: D:\>cd MySQL5.7 D:\>cd D:\MySQL5.7\mysql-5.7.25-winx64\bin 直接切换 ...

  9. linux下python3环境安装(源码编译的方式安装)

    1.将压缩包上传到/usr/local/ 2.解压压缩包 tar -xzvf Python-3.6.6.tgz 3.装一些编译源码需要的依赖文件 yum -y install gcc make cma ...

  10. django中的Case,When,then用法

    # 参考文档 https://docs.djangoproject.com/en/2.2/ref/models/conditional-expressions/ # Case()接受任意数量的When ...