ALL / Coding代码堆 · 2020年12月22日

vue3 使用teleport(传送门)组件实现一个模态框

vue3 使用teleport(传送门)组件实现一个模态框

vue3teleport功能类似于reactPortalsportals提供了一种将子节点渲染到存在于父组件以外都dom节点解决方案,vue3teleportreactPortals功能类似,且更加好用。

在vue2下 要实现类似功能需要通过portal-vue库去实现。

我们为什么需要Teleport

teleport是一种能将我们的模板移动到DOM中Vue App之外的技术,有点类似多啦A梦的“传送门”

使用场景:像modalstoast等这样的元素,很多情况下我们将它完全和我们的Vue应用DOM完全剥离,管理起来相反会方便许多

原因在于如果我们嵌套在Vue某个组件内部,那么处理组件的定位、z-index和样式就会变得很困难

另外,像modals,toats等这样的元素需要使用到Vue组件状态的值我们可能需要将状态放入到Vuex中同一管理,而teleport可以直接使用组件的data或prpos。然后在Vue应用范围之外渲染它。

以上引用自Gopal1 Vue 3 任意传送门——Teleport

修改了“另外,想modals.....然后在Vue应用范围之外渲染它”

使用Teleport实现一个模态框Deom

新建一个模态框组件 ./src/components/modal.vue
注意 在Vue3中拥有Fragments特特性可以允许组件存在多个根,所以一下模板写法是合法的。

<template>
  <button @click="modalOpen = true">开启模态框</button>
  <teleport to="body">
    <div v-if="modalOpen" class="modal">
      <div>
        我是一个模态框
        <button @click="modalOpen = false">关闭模态框</button>
      </div>
    </div>
  </teleport>
</template>

<script>
export default {
  data() {
    return {
      modalOpen: false,
    };
  },
};
</script>

注意 teleportVue3中的一个全局组件你可以在任意地方使用

其中的to属性是要把组件下内容挂载到哪里去,参数是一个选择器 我这里就直接挂载到body标签下<teleport to="body"> teleport标签内是你要“传送的内容” 我们可以直接使用模板下的data状态对模态框的显示进行操作。

随后追加上css

<style scopde>
.modal {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: rgba(0, 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: white;
  width: 300px;
  height: 300px;
  padding: 5px;
}
</style>

然后你就可以在任意组件使用我们的模态框了但是注意

!如果你是使用Vite构建的项目在引入组件时必须携带组件后缀,让Vite知道该如何处理这个文件

import Modal from "./modal.vue";

然后就可以使用了。