vue3.0 传送门teleport

咱们先看一段代码,功能很简单,模板里有一个按钮,点击按钮,展现一个模态窗口。javascript

const app = Vue.createApp({
  data() {
    return {
      show: false,
    };
  },
  methods: {
    handleShowModal() {
      this.show = true;
    },
  },
  template: `
    <div class="box" id="box">
      <button @click="handleShowModal">显示模态窗口</button>
      <div class="modal" v-if="show">模态窗口</div>
    </div>
  `
}

模态窗口样式以下:css

.box {
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: cadetblue;
}
.modal {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
}

整个模态窗口呈绝对定位,left、right、top、bottom 所有给0,背景色为黑色半透明。咱们指望的效果,应该点击按钮,模态窗口覆盖整个页面。html

如今咱们来运行下,咱们会发现,其实模态窗口只覆盖了 #box 元素,由于 #box 自己就是绝对定位, 模态窗口元素是他的子节点,因此模态窗口只覆盖了 #box 元素。vue

若是在没有学习 teleport 以前,咱们会在根节点定义一个模态窗口,在业务组件里去作调用。可是这样的话,组件与模态窗口的逻辑就会产生割裂感。那有没有什么方法,可让我模态窗口就写在这个组件内,但真正呈如今页面时,能够动态插入到 元素上的,实际上是有的,咱们只要简单的修改下 template模板,就能够实现这个要求了。java

template: `
    <div class="box">
        <button @click="handleShowModal">显示模态窗口</button>
        <teleport to="body">
            <div class="modal">模态窗口</div>
        </teleport>        
    </div>
`

咱们用 teleport 元素将 modal 包裹起来,并定义属性 to="body" ,运行页面,咱们查看 dom 节点,就会发现 modal 元素已经追加到 body 底部了,效果以下。app

--body
  --#root vue根节点
  --.modal 模态窗口

传送到其余位置

若是咱们想将 modal 节点传送到其余位置,也能够这么作。dom

<teleport to="#app">
    <div class="modal">模态窗口</div>
</teleport>

这段代码就是将 modal 元素追加到 id=app 的元素内,有一点须要注意,我一直说的是追加元素,假如说,原来 #app 内部已经存在其余节点,那么 modal 元素将追加到这些节点以后,有兴趣能够本身试一下。学习

与组件一块儿使用

其实使用在组件上和普通的 dom 元素并无什么区别,组件中的节点将被渲染到指定的dom节点中(body或者指定ID)this

const app = Vue.createApp({
  ...
  template: `
    <div class="box" id="box">
      <button @click="handleShowModal">显示模态窗口</button>
      <teleport to="body">
         <child-component :name="name"/>
       </teleport>
    </div>
  `
}
app.component('child-component',{
    props:['name']
    template: `<div class='modal'>{{name}}</div>`
})

即便被渲染到不一样的节点,它仍和普通子组件同样,接收父组件传输的数据,并无由于渲染节点改变而改变。code

对同一目标使用多个 teleport

<teleport to="#modals">
  <div>A</div>
</teleport>
<teleport to="#modals">
  <div>B</div>
</teleport>

结果以下:

-- #modal
    -- A
    -- B

因此上面我一直强调,使用 teleport 是将包裹元素追加到指定节点,因此上面两个 teleport 将依次追加到 #modal 上。

总结

teleport多应用于逻辑属于该组件,而从技术角度讲,却要把它移动到其余节点(body或者指定ID的元素) 里。最多见的场景就是建立一个包含全屏模式的组件,逻辑存在于组件内,可是基于css样式,却要把他移动到 body 元素上。

相关文章
相关标签/搜索