12

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 中不是问题,而且非常令人沮丧,因为它使整个概念变得不那么可用。

4

2 回答 2

16

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>

于 2020-08-31T06:27:20.370 回答
-1

在这个关于 GH的问题中包含问题解决。一定是这样的

   //Root template in App.vue(it doesn't need to wrap in a div or smth else)
<template>
    <div class="modal" :style="style">
        <div class="modal-background"></div>
        <div class="modal-content">
            <div id="modal"></div>
        </div>
        <button class="modal-close is-large" aria-label="close" 
        @click="modal.hideModal"></button>
    </div>

    // App instance
    <section class="section">
            <div class="container">
                <Navbar/>
                <router-view/>
            </div>
        </section>
</template>
于 2021-02-07T07:33:42.727 回答