首页 > 解决方案 > Vue 3 Teleport 是否仅适用于移植到 Vue 外部?

问题描述

Vue 3 有一个新的 Teleport 功能,它取代了 vue 2 中的 portal-vue 插件。但是,我发现不可能将组件移植到由 vue 控制的地方(=在 vue 应用程序中)。它仅在移植到外部(身体,其他元素......)时才有效。

const app = {
  template: `
  <div>
    <h1>App</h1>
    <div id="dest"></div>
    <comp />
  </div>`
}


Vue.createApp(app).component('comp', {
  template: `
  <div>
    A component
    <Teleport to="#dest">
      Hello From Portal
    </Teleport>
  </div>`
}).mount('#app')
<script src="https://unpkg.com/vue@3.0.0-rc.9/dist/vue.global.js"></script>

<div id="app"></div>

如您所见,控制台甚至报告说需要已经渲染传送目标。但是如何告诉 vue 先渲染哪个组件呢?在我的示例中,目标位于传送之前的 dom 中。

这在portal-vue 中不是问题,而且非常令人沮丧,因为它使整个概念变得不那么可用。

标签: vue.jsvuejs3vue-teleport

解决方案


Vue 错误消息类型指出了问题。它说Invalid Teleport target on mount: null

问题是目标尚不存在

这可以通过仅在安装组件后仅渲染传送部分来轻松解决。

看起来这是 Vue 应该在没有明确检查的情况下处理的事情。当您将 id 作为字符串传递时,很难判断目标是否是 Vue 组件,尤其是在尚未渲染的情况下。但我只是在这里猜测团队的意图。

const app = {
  template: `
  <div>
    <h1>App</h1>
    <div id="dest"></div>
    <comp />
  </div>`
}

Vue.createApp(app).component('comp', {
  template: `
  <div>
    A component
    <Teleport to="#dest" v-if="isMounted">
      Hello From Portal
    </Teleport>
  </div>`,
  data: function(){
    return { 
        isMounted: false
    }
  },
  mounted(){
    this.isMounted = true
  }
}).mount('#app')
<script src="https://unpkg.com/vue@3.0.0-rc.9/dist/vue.global.js"></script>

<div id="app"></div>


推荐阅读