Vue3中 内置组件 Teleport 详解

02-27 1230阅读 0评论

1. 基本概念

1.1 简单理解

不管是 Vue2 还是 Vue3 中都有内置组件的存在,如 component 内置组件、transition 内置组件等等。内置组件就是官方给我们封装的全局组件,我们直接拿来用就可以了。

Vue3中 内置组件 Teleport 详解,Vue3中 内置组件 Teleport 详解,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,管理,第1张
(图片来源网络,侵删)

在 Vue3 中新增了 Teleport 内置组件,先来看下官方文档是怎么解释的。

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

通俗解释:

teleport 是一个内置组件,我们都知道 HTML 是由层级关系的,Vue3 中的组件也是有层级关系的。

假如在父组件中引用了一个子组件,那么渲染成页面后这个子组件 HTML 也是必然被父组件 HTML 包含的。

但是如果把子组件放置到了 teleport 组件中,那么我们就可以指定该子组件渲染到父组件之外的其它 DOM 节点下,比如 body 或者其它的 DOM 等等。这就有点类似与“传送”了。

1.2 典型案例

我们使用 Vue 的 UI 组件库的时候,经常会用到模态框这个组件。如:使用 Element-plus 的模态框。

Vue3中 内置组件 Teleport 详解,Vue3中 内置组件 Teleport 详解,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,管理,第2张
(图片来源网络,侵删)
  打开弹窗
  
  


import { ref } from 'vue';
export default {
  setup(){
    const dialogVisible = ref(false);
    return {
      dialogVisible
    }
  } 
}

上段代码中在 App.vue 组件里面引用了 Element-plus 的弹窗组件,并且添加了一个 append-to-body 属性。

Vue3中 内置组件 Teleport 详解

可以看到虽然弹窗组件是写在 App.vue 组件里面的,但是渲染出来的结果却是弹窗组件属于 body 节点,这是因为利用了 Element-plus 中弹窗的 append-to-body 属性,我们把该属性去掉再看看什么结果:

Vue3中 内置组件 Teleport 详解

可以看到弹窗组件又乖乖的跑到了 App.vue 组件下面。

为何要这样做?

Vue3中 内置组件 Teleport 详解,Vue3中 内置组件 Teleport 详解,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,管理,第5张
(图片来源网络,侵删)

很简单,假如有非常多的弹窗,那么如何管理它们的 z-index 呢,也就是同时弹窗时的层级关系,如果每个弹窗都在各自的父组件中,那么我们是没法控制的,所有有必要把它们都拧出来,放在同一个父元素下面,这样就可以方便的设置层级关系了。

这和 teleport 组件有什么关系吗?有很大的关系,上面弹窗的 append-to-body 属性效果是 Element 给我们做的,要是我们想自己实现这样的效果,该怎么办呢?我们就可以使用内置组件 teleport 了。

2. 基础使用

2.1 传送 DOM 节点
  
App组件
我是被 teleport 包裹的元素

Vue3中 内置组件 Teleport 详解

从上图可以看出,Teleport 包裹的元素虽然是属于 app.vue 组件,但是渲染过后它却被渲染在了 body 这个 dom 元素下面了。

这都得归功于 Teleport 得传送功能,它的用法很简单,语法代码如下:

其中 to 就是“传送”的目的地了,即需要把包裹的内容传送到何处去。


to 允许接收值:
期望接收一个 CSS 选择器字符串或者一个真实的 DOM 节点。
提示:
 挂载时,传送的 to 目标必须已经存在于 DOM 中。理想情况下,这应该是整个 Vue 应用 DOM 树外部的一个元素。
如果目标元素也是由 Vue 渲染的,你需要确保在挂载  之前先挂载该元素。
2.2 传送组件

只改变了渲染的 DOM 结构,它不会影响组件间的逻辑关系。

也就是说,如果 包含了一个组件,那么该组件始终和这个使用了 的组件保持逻辑上的父子关系。传入的 props 和触发的事件也会照常工作。

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

// 父组件

  
被 teleport 包裹的组件-- {{count}}
import { ref } from 'vue'; import ChildComponent from '@/components/childComponent'; export default { components:{ ChildComponent }, setup(){ const count = ref(100); return { count, } } }
// 子组件

  子组件:


import { ref, watch } from 'vue';
export default {
  props:{
    modelValue:{
      default:0,
    }
  },
  setup(props,{emit}) {
    const inputVal = ref(null);
    const userInput = () => {
      emit('update:modelValue', inputVal.value)
    };
    watch(props,(newVal,oldVal) => {
      inputVal.value = props.modelValue;
    },{immediate:true})
    return {
      userInput,
      inputVal,
    }
  },
}

Vue3中 内置组件 Teleport 详解

2.3 禁用传送功能

在某些场景下可能需要视情况禁用 ,我们可以通过对 动态地传入一个 disabled prop 来处理这两种不同情况( disabled 属性接收一个 Boolean 值,true 代表不允许传送,false 代表传送)。

  
app组件

我是被 teleport 包裹的元素

{{ message }}

import { ref } from 'vue'; export default { setup(){ const message = ref('我是在 App 组件内部'); return { message, } } }

Vue3中 内置组件 Teleport 详解

2.4 多个元素传送给一个节点

多个 组件可以将其内容挂载在同一个目标元素上,而顺序就是简单的顺次追加,后挂载的将排在目标元素下更后面的位置上。


  
  app组件
  
    

我是被 teleport 包裹的一号元素

我是被 teleport 包裹的二号元素

Vue3中 内置组件 Teleport 详解


免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,1230人围观)

还没有评论,来说两句吧...

目录[+]