【Vue.js 3.0源码】Teleport 组件:如何脱离当前组件渲染子组件?

一、前言

Vue.js 的核心思想之一是组件化,组件就是 DOM 的映射,我们通过嵌套的组件构成了一个组件应用程序的树。但是,有些时候组件模板的一部分在逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到应用程序之外的其他位置。一个常见的场景是创建一个包含全屏模式的对话框组件。在大多数情况下,我们希望对话框的逻辑存在于组件中,但是对话框的定位 CSS 是一个很大的问题,它非常容易受到外层父组件的 CSS 影响。假设我们有这样一个 dialog 组件,用按钮来管理一个 dialog:

<template>
  <div v-show="visible" class="dialog">
    <div class="dialog-body">
      <p>I'm a dialog!</p>
      <button @click="visible=false">Close</button>
    </div>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        visible: false
      }
    },
    methods: {
      show() {
        this.visible = true
      }
    }
  }
</script>
<style>
  .dialog {
    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;
  }
  .dialog .dialog-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: white;
    width: 300px;
    height: 300px;
    padding: 5px;
  }
</style>

<template>
  <button @click="showDialog">Show dialog</button>
  <Dialog ref="dialog"></Dialog>
</template>
<script>
  import Dialog from './components/dialog'
  export default {
    components: {
      Dialog
    },
    methods: {
      showDialog() {
        this.$refs.dialog.show()
      }
    }
  }
</script>

dialog 组件使用的是 position:absolute 绝对定位的方式,如果它的父级 DOM 有 position 不为 static 的布局方式,那么 dialog 的定位就受到了影响,不能按预期渲染了。所以一种好的解决方案是把 dialog 组件渲染的这部分 DOM 挂载到 body 下面,这样就不会受到父级样式的影响了。Vue.js 3.0 把这一能力内置到内核中,提供了一个内置组件 Teleport,它可以轻松帮助我们实现上述需求:

<template>
  <button @click="showDialog">Show dialog</button>
  <teleport to="body"&
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值