Teleport 传送门

功能

将组件或者组件中的内容挂载到其他DOM的位置上

实现一个需求

给绝对定位的元素加上覆盖整个页面的蒙层mask,由于绝对定位的元素只能相对于其父元素,如果父元素的面积很小,就做不到全屏的mask,因此需要将这个绝对定位的元素挂到body或者其他div上

1. 使用Teleport 传送门之前

敲代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Teleport 传送门</title>
    <style>
        .area {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%,-50%);
            width: 200px;
            height: 300px;
            background: green;
        }
        .mask{
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, .5);
        }
    </style>
    <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
    <div id="root"></div>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    show: false
                }
            },
            methods:{
                handleBtnClick(){
                    this.show = !this.show
                }
            },
            template: `
                <div class="area">
                  <button @click="handleBtnClick">按钮</button>
                  <div class="mask" v-show="show"></div>
                </div>
            `
        })
        const vm = app.mount('#root')
    </script>
</body>

</html>

运行结果

动画.gif

结果:由于绝对定位的mask的父元素为绿色背景的area,mask中的样式top left right bottom只能作用于父元素上,因此mask的范围就只能限定于它的父元素area中,但是实际是想让mask作用于整个页面

因此如果mask可以放到body中或者其他div上就好了

难道要操作DOM吗?

不用!Vue为我们提供了Teleport 传送门功能

2. 使用Teleport 传送门之后

敲代码

// 相同代码已省略

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods:{
        handleBtnClick(){
            this.show = !this.show
        }
    },
    template: `
        <div class="area">
          <button @click="handleBtnClick">按钮</button>
          <teleport to="body">
            <div class="mask" v-show="show"></div>
          </teloport>
        </div>
    `
})
const vm = app.mount('#root')

运行结果

1.gif

image.png

我们可以发现,mask已经放到body中了

备注

<div class="area">
  <button @click="handleBtnClick">按钮</button>
  <teleport to="body">
    <div class="mask" v-show="show"></div>
  </teloport>
</div>
  • 这段代码的意思是渲染的时候就不放在class为area的标签里,而是传送到body标签中

  • 当然不仅仅可以传到body中,可以传到任何的div中,如:

<teleport to="#wrapper">
    <div class="mask" v-show="show"></div>
</teloport>
  • 传送门除了可以将页面中的元素放到指定的DOM元素中外,其他的逻辑和写组件是一样的,作用域还是在当前的组件中

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYpHLH66' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片