跳至内容
本页内容

高级用法

切换目标和源

<portal>to 属性和 <portal-target>name 属性可以通过 v-bind 动态更改,允许您将一个 <portal> 的内容发送到不同的 <portal-target>,或者将一个 <portal-target> 的源从一个 <portal> 切换到另一个。

html
<portal v-bind:to="name">
  Content will be dynamically sent to the destination that `name` evaluates to
</portal>

<portal-target v-bind:name="name">
  by changing the 'name', you can define which portal's content should be shown.
</portal-target>

作用域插槽

PortalVue 也可以与 作用域插槽 一起使用!这允许您将作用域插槽发送到 PortalTarget,然后 PortalTarget 可以为插槽内容提供道具

html
<portal to="destination" v-slot="{ message }">
  <p>{{message}}</p>
</portal>

<portal-target
  name="destination"
  :slot-props="{message: 'Hello from the Target to You!'}"
/>

结果

html
<!-- rendered in the target location-->
<p>Hello from the Target to You!</p>

过渡

Portal 过渡

您可以将过渡传递给 <portal> 而不出现问题。当内容在 <portal-target> 中渲染时,它的行为将与之前一样。

html
<portal to="destination">
  <transition name="fade">
    <p v-if="hasMessages" key="1">You have {{messages.length}} new messages</p>
    <p v-else key="2">No unread messages</p>
  </transition>
</portal>

但是,如果您将 <portal-target> 用于多个 <portal>,您可能希望在目标端定义过渡。这也是受支持的。

PortalTarget 过渡

html
<portal-target name="target">
  <template v-slot:default="nodes">
    <transition name="fade" mode="out-in">
      <component :is="nodes[0]" />
    </transition>
  </template>
</portal-target>

针对目标的过渡在 PortalVue 3.0 中经历了重新设计。新的语法 admittedly 稍微冗长了一些,并且带有 hack-ish 的感觉,但它是 Vue 的 v-slot 语法的有效使用,并且需要消除我们在 PortalVue 2.* 中针对目标过渡的一些 nasty 边缘情况。

基本上,您将过渡传递给名为 wrapper 的插槽,并从其插槽道具中获取名为 nodes 的数组。

然后您可以使用 Vue 的 <component :is=""> 将它们变成过渡的内容。

这是一个第二个示例,使用 <transition-group> 代替

html
<portal-target name="target">
  <template #default="nodes">
    <transition-group name="fade">
      <component :is="node" v-for="node in nodes" :key="node" />
    </transition-group>
  </template>
  </portal-target>

正确的命名空间

为了将内容从 Portals 移动到 PortalTargets,需要一些中间状态管理来协调两者。我们称之为“虫洞”。

在 PortalVue <=2.* 中,这个虫洞是一个单例实例,因此 toname 属性的命名空间也是全局的。

在 PortalVue 3.0 中,我们仍然使用默认的虫洞,但现在也支持创建您自己的虫洞实例并将其提供给您应用程序中不同区域的 portal 组件 - 或者同一页面上的不同应用程序。

这使得使用名称的工作更不容易发生冲突,尤其是在您在项目中使用的第三方库也使用 portal-vue 来移动东西而您甚至不知道的情况下。

那么它是如何工作的呢?

TODO: 正确记录使用 createWormhole()

在 Vue-App 之外渲染

TODO: 介绍 createPortalTarget 并解释有限的使用场景