首页 > 其他分享 >Vue3 - Teleport 传送门

Vue3 - Teleport 传送门

时间:2023-11-25 21:13:47浏览次数:33  
标签:Teleport center flex 传送门 弹框 modal Vue3 组件

前言

对比 Vue2 ,引出并展开 Vue3 。

本文讲述了 Teleport 传送门是什么,以及使用方法和代码示例。

介绍

学过 React 的同学可能知道, Portal 也提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀方案,当然咱们大名鼎鼎的 Vue3 也做到了,关于这方面的功能需求,第三方库也是有很多的,这里就不详谈了,感兴趣的可以自己去了解。

Teleport 传送门是 Vue3 内置的组件,它是一种能够将我们的模板移动到 DOM 中 Vue app 之外其他位置的技术。

 

 

Vue2 示例

先拿 Vue2 举例,上来讲概念直接上 Vue3 代码有些朋友肯定不太懂。

我们市场上很多项目,大部分都包含弹框,提示用户一些信息,比如 ElementUI 的弹框组件。

这样的弹框,我们在开发的时候都会选择创建一个组件,将来有页面需要用的时候,直接引入,再传入相应的配置即可。


咱们先来看一下 Vue2 中如何实现弹框。

在 components 目录下,新建 modal.vue ,这个文件咱们用作弹框组件。

<template>
    <div>
        <button @click="flag = true">打开弹框</button>
        <div v-if="flag" class="modal">
            <div>
            <h1>Hello</h1>
            <button @click="flag = false">
                关闭
            </button>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            flag: false
        }
    }
}
</script>

<style>
.modal {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background-color: rgba(0,0,0,.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.modal div {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: white;
  width: 600px;
  height: 300px;
  padding: 5px;
  border-radius: 15px;
}
</style>
  然后引入该组件:
<template>
  <div>
     <Modal />
  </div>
</template>

<script>
import Modal from './components/modal.vue'
export default {
  components: { Modal },
}
</script>

然后咱们打开控制台,看一下 DOM 结构,可以发现咱们的页面内容全部被套在 #app 这个元素下,而我们的弹框组件则是被套在父组件的中,也就是说哪个页面引用了弹框组件,弹框组件就被嵌套在此。

由此我们知道,弹框是被深度嵌套的 div 中渲染的,那么问题来了,此时处理嵌套组件的定位与 z-index 样式都会变得很困难,也就是由于你弹框组件受父组件影响,所以你在写样式的时候都需要考虑到父组件,比如 z-index 不能太高,定位不能使用绝对定位等,非常恶心。  

 

Vue3 示例

那么有没有一种办法,既能享受到 Vue 带来的功能,又不受父组件影响呢?答案是有,有请我们的主角登场,废话不多说,马上用 Vue3 重构一把。

首先打开项目根目录下 index.html 文件,在 <div id="app"></div> 下加入一段代码:


 

为什么要加入这一行呢,一会你就知道了。

加完之后呢,我们打开刚才用 Vue2 编写的弹框组件,咱们做一些修改:

<template>
    <button @click="flag = true">打开弹框</button>
    <!-- 注意这里,把刚才在 index.html 加入的节点,放到这里 ↓↓↓ -->
    <!-- 然后被teleport包裹的内容,就会传送到#modal节点上(也就是成功跑到了#app节点之外) -->
    <!-- 虽然跑到了#app节点之外,但依然可以享有vue带来的功能 -->
    <teleport to="#modal">
        <div v-if="flag" class="modal">
            <div>
            <h1>Hello</h1>
            <button @click="flag = false">
                关闭
            </button>
            </div>
        </div>
    </teleport>
</template>

<script>
export default {
    data() {
        return {
            flag: false
        }
    }
}
</script>

<style>
.modal {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background-color: rgba(0,0,0,.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.modal div {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: white;
  width: 600px;
  height: 300px;
  padding: 5px;
  border-radius: 15px;
}
</style>

 

再比如,我们直接把弹框传送到 body 节点上,直接改 to="body" 属性即可。

非常的简单,省时省力。

写在后面

这些示例代码都是可以运行的,如果你还是不懂,可以自己亲自复制代码跑起来。

 

参考

https://juejin.cn/post/7195391026956075069

标签:Teleport,center,flex,传送门,弹框,modal,Vue3,组件
From: https://www.cnblogs.com/miangao/p/17856087.html

相关文章

  • Vue3实现九宫格抽奖效果
    需求与效果需求:1、礼品根据后台配置生成2、跑马灯转动效果3、结果后台生成并且每个礼物概率不一样(概率这里不讨论)注意点:1、布局如何排列,是按照跑动排列还是从左至右自上而下排列2、点击按钮如何插入,DOM结构如何生成3、跑马效果如何实现,速度如何控制4、接口如何处理,包括接......
  • Vue3实现转盘抽奖效果
    1、实现转盘数据动态配置(可通过接口获取)2、背景色通过分隔配置3、转动速度慢慢减速,最后停留在每一项的中间,下一次开始从本次开始4、当动画停止后在对应事件中自定义生成中奖提示。5、本次中奖概率随机生成,也可自定义配置实现代码html<template><divclass="graph-page">......
  • 遇到了vue3 刷新问题
     index.d762f427.js:3[Vuewarn]:Unhandlederrorduringexecutionofschedulerflush.ThisislikelyaVueinternalsbug.Pleaseopenanissueathttps://new-issue.vuejs.org/?repo=vuejs/coreat<Tags>at<HomeonVnodeUnmounted=fn<onVnodeU......
  • java实现大文件的分片上传与下载(springboot+vue3)
    1.1项目背景对于超大文件上传我们可能遇到以下问题•大文件直接上传,占用过多内存,可能导致内存溢出甚至系统崩溃•受网络环境影响,可能导致传输中断,只能重新传输•传输时间长,用户无法知道传输进度,用户体验不佳1.2项目目标对于上述问题,我们需要对文件做分片传输。分片传输就是......
  • uniapp+vue3中使用swiper和自定义header实现左右滑动的Tabs功能
    首先创建一个Tabs的Header,包含有一个下划线的指示器,在点击tabs的标题时候下划线会跟着动态的滑动下面是完整的Tabs的代码,可以看到定义了Tabs的background颜色样式,包含tab的宽度indicatorWidth,以及下划线的颜色indicatorColor主要的是tabList属性,通过tabList传入对应的tab数组得......
  • 全屏API及vue3 hook封装
    最近在一个大屏项目遇到一个需求:用户可以通过一个按钮,触发页面部分模块全屏。通过以下API可以实现:Element.requestFullscreen()方法用于发出异步请求使元素进入全屏模式。且全屏状态变化会触发以下事件:fullscreenchange事件会在浏览器进入或退出全屏模式后立即触发。基于......
  • 关于FastAPI与Vue3的通信
    学习一下前后端分离技术,前端采用三大框架之一的Vue.js,后端则采用Python的FastAPI框架。一、前端设计1.建目录mydemo2.在mydemo目录下打开命令行,运行:npminitvue@latest(这里如果cmd卡死了,就ctrl+C结束,再次运行npminitvue@latest)3.工程名设置为 frontend ,其余按默......
  • vue3 watch
    constfilterCommandList=computed(()=>{timerList.value.forEach((item)=>clearInterval(item));timerList.value=[];letdata=repeatReminderList.value;returndata.map((row)=>{row.close=false;row.lastT......
  • vue3所遇问题
    1. table表格无边框数据乱飞 解决方法:将import{}from'Elementplus'  删去  2.表单无法输入内容 解决方法 :   ref="form"     :model="form333"   ref与:modle 不可重名......
  • vue面试题_vue2和vue3的区别
    1、数据绑定原理不同vue2:vue2的数据绑定是利用ES5的一个API:Object.definePropert()对数据进行劫持,结合发布订阅模式的方式来实现的。vue3:vue3中使用了ES6的ProxyAPI对数据代理。相比vue2.x,使用proxy的优势如下:defineProperty只能监听某个属性,不能对全对象监听可以省去fori......