vue3第十四节 Teleport 内置组件介绍

178 阅读2分钟
<Teleport></Teleport>  

作用目的:

用于将指定的组件或者元素传送到指定的位置; 通常是自定义的全局通用弹窗,绑定到 body 上,而不是在当前元素上面;

使用方法:

接收两个参数 to: 要将目标传到的位置; 可以是指定的元素、class、id disabled: 是否禁止将目标传送到指定位置;Boolean

比如:

<Teleport 
to="body"
disabled="true"
></Teleport>

而为什么要使用teleport 内置组件呢?

比如:有这样一个需求,我们需要一个盒子顺时针旋转 45度;而这个盒子同时是一个弹窗的父级组件,并且这个盒子可以打开改弹窗;

父组件:

<template>
<div class="my-built-in">
  <!-- 内置组件 -->
  <div class="other-place" @click="handleOpen">
    其他dom位置
    <TelDialog 
    :isShowTel="isShowTel"
    :telCon="telCon" 
    @onCloseDialog="handleClose"
    ></TelDialog>
  </div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import TelDialog from './components/telDialog.vue'
const isShowTel = ref(false)
const telCon = ref('This is a Teleport component.')
const handleClose = () => {
  isShowTel.value = false
}
const handleOpen = () => {
  isShowTel.value = true
}
</script>
<style lang='scss' scoped>
.my-built-in{
  position: relative;
  width: 100px;
  height: 100px;
  background-color: #00ff00;
  left: 200px;
  transform: rotate(45deg);
}
  
</style>

弹窗组件:

<template>
  <div class="my-tel-container" v-if="props.isShowTel">
    <div class="my-tel-title">Teleport 弹窗</div>
    <div class="my-tel-content">{{ props.telCon }}</div>
    <div class="my-tel-foot">
      <el-button type="primary" class="close-btn" @click="handleClose">关闭teleport 弹窗</el-button>
    </div>
  </div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
  isShowTel:{
    type: Boolean,
    default: false,
  },
  telCon: {
    type: String,
    default: ''
  }
})
const emits = defineEmits(['onCloseDialog'])
const handleClose = () => {
  emits('onCloseDialog')
}
</script>
<style lang='scss' scoped>
.my-tel-container{
  position: fixed;
  top:50%;
  left: 50%;
  width: 440px;
  height: auto;
  background-color: aqua;
  box-shadow: 0 2px 4px 0 rgba(0,0,0, .3);
  box-sizing: border-box;
  padding: 0 16px 16px;
  .my-tel-title{
    width: 100%;
    height: 46px;
    text-align: center;
    line-height: 46px;
    font-size: 16px;
    color: #333;
  }
  .my-tel-content{
    width: 100%;
    height: 200px;
  }
  .my-tel-foot{
    width: 100%;
    height: 46px;
    display: flex;
    justify-content: right;
    align-content: center;
  }
}
</style>

我们会发现写好之后在没有使用teleport 组件的情况下 弹窗也跟着旋转了45度,这并不是我们想要的;为什么会出现这种情况呢? 如图: 请添加图片描述

我们需要的是即使父组件发上了旋转 位移等,弹窗依然是位于浏览器的正中央; 此时我们就可以通过 <Teleport></Teleport> 组件来将弹窗组件实际渲染的位置更改到 body 上;但是这样并不影响 组件直接的通讯;

更改父组件为:

<template>
<div class="my-built-in">
  <!-- 内置组件 -->
  <div class="other-place" @click="handleOpen">
    其他dom位置
    <!-- **只需要添加 Teleport 组件即可,disabled 接收一个布尔值,默认是falsetrue代表不传送到指定位置 body上** -->
    <Teleport to="body" :disabled="false">
      <TelDialog 
      :isShowTel="isShowTel"
      :telCon="telCon" 
      @onCloseDialog="handleClose"
      ></TelDialog>
    </Teleport>
  </div>
</div>
</template>

请添加图片描述

注意事项:

a、在使用teleport 组件时,需要确保传送的位置dom已经渲染完成,即to的位置dom已完成渲染,否则将无法实现传送; b、同时可以通过给disabled 动态传入一个Boolean 值,来控制是否要将元素或dom传送到指定的位置;