vue3 基础-传送门 teleport

之前介绍了一波混入 mixin 和 自定义指令 directive 其基本作用就是为了在 vue 中实现代码的复用. 而本篇介绍的是 vue3 的一个新特性叫做传送门.

一听这个名字是不是就感觉特别科幻呢? 小时候看哆啦A梦的就经常使用传送门, 只要心里想着那个地方, 就能直接穿越过去. 然后就是在漫威宇宙中奇异博士的传送门啦, 想去哪就画个圈圈传送过去哦.

在 vue 中就表现为对一个 dom 进行有目的的直接传送啦, 这里我们以一个局部的蒙层来做演示:

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

<head>
  <title>蒙层</title>
  <script src="https://unpkg.com/vue@3"></script>
  <style>
    .box {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);

      width: 200px;
      height: 300px;
      background: skyblue;
    }

    .mask {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background-color: rgba(0, 0, 0, .25);
    }
  </style>
</head>
<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      data () {
        return {
          show: false
        }
      },
      methods: {
        handleClick () {
          this.show = !this.show
        }
      },
      template: `
      <div class="box">
        <button @click="handleClick">点我变蒙层</button>
        <div class="mask" v-show="show"></div>
      </div>
      `
    })

    const vm = app.mount('#root')

  </script>
</body>

</html>

可以发现在这个200 x 300px 的浅蓝色 box 中, 当我们点击 "点我变蒙层" 的按钮时, 只会作用于这个内部盒子而不会作用整个页面, 因为咱这个 mask 就是写在 box 中的嘛.

template: `
    <div class="box">
        <button @click="handleClick">点我变蒙层</button>
        <div class="mask" v-show="show"></div>
    </div>
    `

而要实现整个页面的效果, 则咱需要将这个 mask 作用到 body 中去, 或者说将其直接"传送"到 body 下面哦.

传送门演示

来了老铁, 直接将这个 mask 传递到 body 哦, 即通过 teleport 这个标签来安排.

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

<head>
  <title>传送门 teleport </title>
  <script src="https://unpkg.com/vue@3"></script>
  <style>
    .box {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);

      width: 200px;
      height: 300px;
      background: skyblue;
      /* 让按钮的优先级增加以至于蒙层后不被覆盖掉 */
      z-index: 2;
    }

    .mask {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background-color: rgba(0, 0, 0, .25);
    }
  </style>
</head>
<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      data () {
        return {
          show: false
        }
      },
      methods: {
        handleClick () {
          this.show = !this.show
        }
      },
      template: `
      <div class="box">
        <button @click="handleClick">点我变蒙层</button>
        <teleport to="body">
          <div class="mask" v-show="show"></div>
        </teleport>
      </div>
      `
    })

    const vm = app.mount('#root')

  </script>
</body>

</html>

其核心就是这里的 teleplort 标签的包裹和 to 这个传送到哪啦.

template: `
    <div class="box">
        <button @click="handleClick">点我变蒙层</button>
        <teleport to="body">
            <div class="mask" v-show="show"></div>
        </teleport>
    </div>
    `

当然也可以传送到比如模板中有一个 ID 为 youge 的标签中:

<teleport to="#youge">
    <div class="mask" v-show="show"></div>
</teleport>

当然除了传蒙层, 对于其他的一些场景如 tab 块呀, 组件呀, dom 内容呀, 都是可以通过 teleport 进行传送的, 与我而言, 其好奇的科幻程度远大于应用程度啦. 那关于传送门的基本认知就先到这里啦.

小结

  • 传送门就是将某个 dom 或组件等能够传递到该模板的任意位置中, 类似奇异博士的传送门
  • 实现上就在 dom / 组件 外包裹一层 teleport 标签, to="选送的位置, 选择器" 即可
  • 好奇和科幻的程度远大于对它的实际应用程度啦
posted @ 2022-09-25 17:55  致于数据科学家的小陈  阅读(266)  评论(0编辑  收藏  举报