我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Vue3中Teleport 组件的原理是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Vue3中Teleport 组件的原理是什么

这篇文章将为大家详细讲解有关Vue3中Teleport 组件的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

使用场景

业务开发的过程中,我们经常会封装一些常用的组件,例如 Modal 组件。相信大家在使用 Modal 组件的过程中,经常会遇到一个问题,那就是 Modal  的定位问题。

话不多说,我们先写一个简单的 Modal 组件。

<!-- Modal.vue --> <style lang="scss"> .modal {   &__mask {     position: fixed;     top: 0;     left: 0;     width: 100vw;     height: 100vh;     background: rgba(0, 0, 0, 0.5);   }   &__main {     margin: 0 auto;     margin-bottom: 5%;     margin-top: 20%;     width: 500px;     background: #fff;     border-radius: 8px;   }    } </style> <template>   <div class="modal__mask">     <div class="modal__main">       <div class="modal__header">         <h4 class="modal__title">弹窗标题</h4>         <span class="modal__close">x</span>       </div>       <div class="modal__content">         弹窗文本内容       </div>       <div class="modal__footer">         <button>取消</button>         <button>确认</button>       </div>     </div>   </div> </template>  <script> export default {   setup() {     return {};   }, }; </script>

然后我们在页面中引入 Modal 组件。

<!-- App.vue --> <style lang="scss"> .container {   height: 80vh;   margin: 50px;   overflow: hidden; } </style> <template>   <div class="container">     <Modal />   </div> </template>  <script> export default {   components: {     Modal,   },   setup() {     return {};   } }; </script>

Vue3中Teleport 组件的原理是什么

Modal

如上图所示, div.container 下弹窗组件正常展示。使用 fixed 进行布局的元素,在一般情况下会相对于屏幕视窗来进行定位,但是如果父元素的  transform, perspective 或 filter 属性不为 none 时,fixed 元素就会相对于父元素来进行定位。

我们只需要把 .container 类的 transform 稍作修改,弹窗组件的定位就会错乱。

<style lang="scss"> .container {   height: 80vh;   margin: 50px;   overflow: hidden;   transform: translateZ(0); } </style>

Vue3中Teleport 组件的原理是什么

Modal

这个时候,使用 Teleport 组件就能解决这个问题了。

“Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件。-- Vue  官方文档

我们只需要将弹窗内容放入 Teleport 内,并设置 to 属性为 body,表示弹窗组件每次渲染都会做为 body  的子级,这样之前的问题就能得到解决。

<template>   <teleport to="body">     <div class="modal__mask">       <div class="modal__main">         ...       </div>     </div>   </teleport> </template>

可以在 https://codesandbox.io/embed/vue-modal-h6g8y 查看代码。

Vue3中Teleport 组件的原理是什么

使用 Teleport 的 Modal

源码解析

我们可以先写一个简单的模板,然后看看 Teleport 组件经过模板编译后,生成的代码。

Vue.createApp({   template: `     <Teleport to="body">       <div> teleport to body </div>       </Teleport>   ` })

Vue3中Teleport 组件的原理是什么

模板编译后的代码

简化后代码:

function render(_ctx, _cache) {   with (_ctx) {     const { createVNode, openBlock, createBlock, Teleport } = Vue     return (openBlock(), createBlock(Teleport, { to: "body" }, [       createVNode("div", null, " teleport to body ", -1 )     ]))   } }

可以看到 Teleport 组件通过 createBlock 进行创建。

// packages/runtime-core/class="lazy" data-src/renderer.ts export function createBlock(  type, props, children, patchFlag ) {   const vnode = createVNode(     type,     props,     children,     patchFlag   )   // ... 省略部分逻辑   return vnode }  export function createVNode(   type, props, children, patchFlag ) {   // class & style normalization.   if (props) {     // ...   }    // encode the vnode type information into a bitmap   const shapeFlag = isString(type)     ? ShapeFlags.ELEMENT     : __FEATURE_SUSPENSE__ && isSuspense(type)       ? ShapeFlags.SUSPENSE       : isTeleport(type)         ? ShapeFlags.TELEPORT         : isObject(type)           ? ShapeFlags.STATEFUL_COMPONENT           : isFunction(type)             ? ShapeFlags.FUNCTIONAL_COMPONENT             : 0    const vnode: VNode = {     type,     props,     shapeFlag,     patchFlag,     key: props && normalizeKey(props),     ref: props && normalizeRef(props),   }    return vnode }  // packages/runtime-core/class="lazy" data-src/components/Teleport.ts export const isTeleport = type => type.__isTeleport export const Teleport = {   __isTeleport: true,   process() {} }

传入 createBlock 的第一个参数为 Teleport,最后得到的 vnode 中会有一个 shapeFlag 属性,该属性用来表示 vnode  的类型。isTeleport(type) 得到的结果为 true,所以 shapeFlag 属性最后的值为 ShapeFlags.TELEPORT(1  << 6)。

// packages/shared/class="lazy" data-src/shapeFlags.ts export const enum ShapeFlags {   ELEMENT = 1,   FUNCTIONAL_COMPONENT = 1 << 1,   STATEFUL_COMPONENT = 1 << 2,   TEXT_CHILDREN = 1 << 3,   ARRAY_CHILDREN = 1 << 4,   SLOTS_CHILDREN = 1 << 5,   TELEPORT = 1 << 6,   SUSPENSE = 1 << 7,   COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,   COMPONENT_KEPT_ALIVE = 1 << 9 }

在组件的 render 节点,会依据 type 和 shapeFlag 走不同的逻辑。

// packages/runtime-core/class="lazy" data-src/renderer.ts const render = (vnode, container) => {   if (vnode == null) {     // 当前组件为空,则将组件销毁     if (container._vnode) {       unmount(container._vnode, null, null, true)     }   } else {     // 新建或者更新组件     // container._vnode 是之前已创建组件的缓存     patch(container._vnode || null, vnode, container)   }   container._vnode = vnode }  // patch 是表示补丁,用于 vnode 的创建、更新、销毁 const patch = (n1, n2, container) => {   // 如果新旧节点的类型不一致,则将旧节点销毁   if (n1 && !isSameVNodeType(n1, n2)) {     unmount(n1)   }   const { type, ref, shapeFlag } = n2   switch (type) {     case Text:       // 处理文本       break     case Comment:       // 处理注释       break     // case ...     default:       if (shapeFlag & ShapeFlags.ELEMENT) {         // 处理 DOM 元素       } else if (shapeFlag & ShapeFlags.COMPONENT) {         // 处理自定义组件       } else if (shapeFlag & ShapeFlags.TELEPORT) {         // 处理 Teleport 组件         // 调用 Teleport.process 方法         type.process(n1, n2, container...);       } // else if ...   } }

可以看到,在处理 Teleport 时,最后会调用 Teleport.process 方法,Vue3 中很多地方都是通过 process 的方式来处理  vnode 相关逻辑的,下面我们重点看看 Teleport.process 方法做了些什么。

// packages/runtime-core/class="lazy" data-src/components/Teleport.ts const isTeleportDisabled = props => props.disabled export const Teleport = {   __isTeleport: true,   process(n1, n2, container) {     const disabled = isTeleportDisabled(n2.props)     const { shapeFlag, children } = n2     if (n1 == null) {       const target = (n2.target = querySelector(n2.prop.to))             const mount = (container) => {         // compiler and vnode children normalization.         if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {           mountChildren(children, container)         }       }       if (disabled) {         // 开关关闭,挂载到原来的位置         mount(container)       } else if (target) {         // 将子节点,挂载到属性 `to` 对应的节点上         mount(target)       }     }     else {       // n1不存在,更新节点即可     }   } }

其实原理很简单,就是将 Teleport 的 children 挂载到属性 to 对应的 DOM  元素中。为了方便理解,这里只是展示了源码的九牛一毛,省略了很多其他的操作。

关于Vue3中Teleport 组件的原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Vue3中Teleport 组件的原理是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Vue3中Provide/Inject的实现原理是什么

本文小编为大家详细介绍“Vue3中Provide/Inject的实现原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue3中Provide/Inject的实现原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来
2023-06-29

Vue3中内置组件Teleport的基本使用与典型案例

Teleport是一种能够将我们的模板移动到DOM中Vueapp之外的其他位置的技术,下面这篇文章主要给大家介绍了关于Vue3中内置组件Teleport的基本使用与典型案例的相关资料,需要的朋友可以参考下
2023-05-18

Vue3的响应式原理是什么

ProxyVue3的响应式原理依赖了Proxy这个核心API,通过Proxy可以劫持对象的某些操作。constobj={a:1};constp=newProxy(obj,{get(target,property,receiver){console.log("get");returnReflect.get(target,property,receiver);},set(target,property,value,receiver){console.log("set&q
2023-05-24

Vue3中Provide和Inject的实现原理是什么

这篇文章主要介绍了Vue3中Provide和Inject的实现原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3中Provide和Inject的实现原理是什么文章都会有所收获,下面我们一起来看看吧
2023-06-29

Vue2/Vue3的响应式原理是什么

本篇内容主要讲解“Vue2/Vue3的响应式原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue2/Vue3的响应式原理是什么”吧!在讲解之前,我们先了解一下数据响应式是什么?所谓数据
2023-07-05

springcloud五大组件原理是什么

springcloud五大组件原理分别是:1、Eureka用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持;2、Ribbon主要提供客户侧的软件负载均衡算法;3、Hystrix能够帮助快速地拒绝对一个操作,即很可能失败,
2023-07-17

VueJs中怎么使用Teleport及组件嵌套层次结构是什么

这篇文章主要讲解了“VueJs中怎么使用Teleport及组件嵌套层次结构是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“VueJs中怎么使用Teleport及组件嵌套层次结构是什么”吧
2023-07-05

Vue3中key的作用和工作原理是什么

这篇文章主要介绍“Vue3中key的作用和工作原理是什么”,在日常操作中,相信很多人在Vue3中key的作用和工作原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue3中key的作用和工作原理是什么
2023-06-20

android组件化开发的原理是什么

Android组件化开发的原理是将一个大型的应用程序拆分成多个独立的组件,每个组件包含自己的功能模块和界面,然后通过定义清晰的接口和通信方式,将这些组件进行解耦和集成。这样做的目的是提高开发效率、降低维护成本、增加代码重用性和模块化程度。
2023-10-22

Vue3组件传值方式是什么

这篇文章主要介绍了Vue3组件传值方式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3组件传值方式是什么文章都会有所收获,下面我们一起来看看吧。父子组件传值 props和 vue2 一样,vue3
2023-07-02

Vue3 Reactive响应式原理是什么

一、怎么实现变量变化怎么实现变量变化,相关依赖的结果也跟着变化当原本price=5变为price=20后total应该变为40,但是实际total并不会改变。解决办法可以这样,当变量改变了,重新计算一次,那么结果就会改变为最新的结果。如果需要重新计算,我们需要将total语句存储为一个函数,才能实现依赖的变量改变就进行一次依赖项计算。这里就用effect表示函数名。来,试一下:实现了变量price改变,依赖变量pricequantity的变量total也发生改变。下一步,我们要解决的问题是:应该
2023-05-21

Vue3 effectScope API实现原理是什么

本篇内容介绍了“Vue3 effectScope API实现原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!vue3新增effect
2023-07-05

Vue3插槽Slot的实现原理是什么

这篇文章主要介绍了Vue3插槽Slot的实现原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3插槽Slot的实现原理是什么文章都会有所收获,下面我们一起来看看吧。Vue官方对插槽的定义Vue 实现
2023-07-02

Vue3侦听器的实现原理是什么

侦听响应式对象前面我们聊到计算属性,它可以自动计算并缓存响应式数据的值。而如果我们仅需要在响应式数据变化时,执行一些预设的操作,就可以使用watch侦听器。我们还是先来实现一个最简单的例子,然后来一点一点扩充它。constdata={foo:1}constobj=reactive(data)watch(obj,()=>{console.log(&#39;obj已改变&#39;)})在这个例子中,我们使用了watch侦听器,当obj的属性被改变时,控制台应该会打印出obj已改
2023-05-16

Spring Cloud原理及核心组件是什么

本篇内容介绍了“Spring Cloud原理及核心组件是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!概述毫无疑问,Spring Clo
2023-07-05

编程热搜

目录