广告
返回顶部
首页 > 资讯 > 前端开发 > VUE >Vue3中Teleport 组件的原理是什么
  • 412
分享到

Vue3中Teleport 组件的原理是什么

2024-04-02 19:04:59 412人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关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/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/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/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/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/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 组件的原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: Vue3中Teleport 组件的原理是什么

本文链接: https://www.lsjlt.com/news/72007.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • Vue3中Teleport 组件的原理是什么
    这篇文章将为大家详细讲解有关Vue3中Teleport 组件的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。使用场景业务开发的过程中,我们经常会封...
    99+
    2022-10-19
  • Vue3中内置组件Teleport的基本使用与典型案例
    目录1. 基本概念1.1 简单理解1.2 典型案例2. 基础使用2.1 传送 DOM 节点2.2 传送组件2.3 禁用传送功能2.4 多个元素传送给一个节点总结1. 基本概念 1.1...
    99+
    2023-05-18
    vue3内置组件 vue3 teleport vue3内置teleport
  • Vue3中Provide/Inject的实现原理是什么
    本文小编为大家详细介绍“Vue3中Provide/Inject的实现原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue3中Provide/Inject的实现原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
    99+
    2023-06-29
  • Vue3的响应式原理是什么
    ProxyProxy这个核心API被Vue3的响应式原理所依赖,利用Proxy可以拦截一些对象操作。const obj = { a: 1 }; const p = new Proxy(obj, { get(target, propert...
    99+
    2023-05-24
    Vue3
  • VueJs中怎么使用Teleport及组件嵌套层次结构是什么
    这篇文章主要讲解了“VueJs中怎么使用Teleport及组件嵌套层次结构是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“VueJs中怎么使用Teleport及组件嵌套层次结构是什么”吧...
    99+
    2023-07-05
  • Vue中动态组件和异步组件的原理是什么
    今天就跟大家聊聊有关Vue中动态组件和异步组件的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。前言在vue官方资料中,我们可以可以很学会如...
    99+
    2022-10-19
  • Vue3中Provide和Inject的实现原理是什么
    这篇文章主要介绍了Vue3中Provide和Inject的实现原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3中Provide和Inject的实现原理是什么文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-06-29
  • Vue2/Vue3的响应式原理是什么
    本篇内容主要讲解“Vue2/Vue3的响应式原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue2/Vue3的响应式原理是什么”吧!在讲解之前,我们先了解一下数据响应式是什么?所谓数据...
    99+
    2023-07-05
  • springcloud五大组件原理是什么
    springcloud五大组件原理分别是:1、Eureka用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持;2、Ribbon主要提供客户侧的软件负载均衡算法;3、Hystrix能够帮助快速地拒绝对一个操作,即很可能失败,...
    99+
    2023-07-17
  • Vue3组件传值方式是什么
    这篇文章主要介绍了Vue3组件传值方式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3组件传值方式是什么文章都会有所收获,下面我们一起来看看吧。父子组件传值 props和 vue2 一样,vue3 ...
    99+
    2023-07-02
  • Vue3 Reactive响应式原理是什么
    一、怎么实现变量变化怎么实现变量变化,相关依赖的结果也跟着变化 当原本price=5变为price=20后total应该变为40,但是实际total并不会改变。 解决办法可以这样,当变量改变了,重新计算一次,那么结果就会改变为最新的结果。如...
    99+
    2023-05-21
    Vue3 reactive
  • Vue3 effectScope API实现原理是什么
    本篇内容介绍了“Vue3 effectScope API实现原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!vue3新增e...
    99+
    2023-07-05
  • Angular中组件样式的工作原理是什么
    这篇文章给大家分享的是有关Angular中组件样式的工作原理是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 在开发 Angular 组件的过程中...
    99+
    2022-10-19
  • Vue3中key的作用和工作原理是什么
    这篇文章主要介绍“Vue3中key的作用和工作原理是什么”,在日常操作中,相信很多人在Vue3中key的作用和工作原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue3中key的作用和工作原理是什么...
    99+
    2023-06-20
  • android组件化开发的原理是什么
    Android组件化开发的原理是将一个大型的应用程序拆分成多个独立的组件,每个组件包含自己的功能模块和界面,然后通过定义清晰的接口和...
    99+
    2023-10-22
    android
  • Vue3侦听器的实现原理是什么
    侦听响应式对象前面我们聊到计算属性,它可以自动计算并缓存响应式数据的值。而如果我们仅需要在响应式数据变化时,执行一些预设的操作,就可以使用watch侦听器。我们还是先来实现一个最简单的例子,然后来一点一点扩充它。const data = {...
    99+
    2023-05-16
    Vue3
  • Vue3插槽Slot的实现原理是什么
    这篇文章主要介绍了Vue3插槽Slot的实现原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3插槽Slot的实现原理是什么文章都会有所收获,下面我们一起来看看吧。Vue官方对插槽的定义Vue 实现...
    99+
    2023-07-02
  • vue父子组件传值的原理是什么
    vue父子组件传值的原理是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。文件目录如下图,example.vue是父组件,exampleCh...
    99+
    2022-10-19
  • Spring Cloud原理及核心组件是什么
    本篇内容介绍了“Spring Cloud原理及核心组件是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!概述毫无疑问,Sprin...
    99+
    2023-07-05
  • Express中间件的原理是什么
    这篇文章主要介绍“Express中间件的原理是什么”,在日常操作中,相信很多人在Express中间件的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Express中...
    99+
    2022-10-19
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作