基于Vue3内置组件Teleport详解

Teleport简介

<Teleport> 是一个内置的 Vue 组件,它具备将组件内部特定的模板内容“投射”或“传输”至该组件 DOM 结构外部指定位置的功能。这一特性使得开发者能够灵活地调整页面元素的布局和嵌套关系,从而实现更高级的界面设计和交互效果。<简单地来说就像游戏中的传送门>

使用场景

有时我们需要一个组件的部分内容(如全屏模态框)在逻辑上属于该组件,但在 DOM 结构上却需要被渲染到整个 Vue 应用的其他地方,甚至是应用的根节点之外。

这种情况通常出现在需要全屏覆盖的模态框(Modal)或对话框(Dialog)等组件中。从逻辑上看,模态框的触发按钮和模态框本身都是同一个组件的一部分,因为它们的状态(如显示或隐藏)通常是相互关联的。但是,如果我们将整个组件(包括触发按钮和模态框)一起渲染,那么模态框很可能会被嵌套在 DOM 结构的深层位置。

这样的嵌套位置可能会给 CSS 布局带来困难。例如,全屏模态框通常需要覆盖整个页面,包括页面的头部和底部。如果模态框被嵌套在深层 DOM 结构中,那么使用 CSS 来实现全屏覆盖可能会变得非常棘手,甚至需要用到一些复杂的选择器或 CSS 技巧。

因此,Vue 的 <Teleport> 组件提供了一种解决方案。通过 <Teleport>,我们可以将组件内部的模板内容“传送”到 DOM 结构的其他位置,甚至是根节点之外。这样,我们就可以保持组件的逻辑完整性,同时实现更好的 CSS 布局和用户体验。

未使用<Teleport> 组件的代码:

<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>

使用<Teleport> 组件后:

<template>
<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>
</template>

<Teleport> 它允许你将组件内部的模板内容“传送”到组件 DOM 结构外部的一个特定位置。这是通过  to 属性来实现的。

to 属性有两个可能的值:

  1. CSS 选择器字符串:你可以提供一个 CSS 选择器字符串,用来匹配 DOM 树中的某个元素。<Teleport> 会将内容传送到第一个匹配该选择器的元素内部。

  2. DOM 元素对象:你也可以直接提供一个 DOM 元素对象,<Teleport> 会直接将内容传送到这个元素内部。

    这段代码的作用就是告诉 Vue把以下模板片段传送到 body 标签下。

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

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值