跳至内容
本页内容

从 PortalVue 2 迁移

PortalVue 3 是一个完全重写的版本,旨在使用 Vue 3 提供的新功能优化代码库,并在过程中对 API 和功能进行一些调整,清理一些冗余代码。

从用户的角度来看,并没有太多变化,因此大多数用例应该继续工作,或者只需要稍微调整一下就可以再次工作。

一个值得注意的例外是 <MountingPortal>,它在本次发布中被删除,并被一个小的实用程序函数取代,用于为普通 Portal 安装 PortalTarget(参见下面的“更改”)。

旁注:Vue 3 & Teleport

熟悉 Vue 3 的开发者可能会问

"我们真的还需要这个库吗?Vue 3 现在有 <Teleport> 了!"

坦诚地说:对于典型的用例,比如将模态框移动到 <body> 等,你可能不再需要这个库。但是,如果你要将内容你的应用程序从一个组件移动到另一个组件,那么<Teleport> 本身并不是一个好的选择,你很可能仍然会从使用这个库中获益。

需要注意的是,PortalVue 仍然没有在幕后使用 <Teleport>。做出这个决定的主要原因是,如果我们在 Teleport 之上重新构建 PortalVue 3,将会有更多行为差异,可能会使迁移变得更加困难。

所以,将 PortalVue 3 视为一种迁移版本,它应该在你的 Vue 2 应用程序中为你提供与 PortalVue 2 相差无几的行为,但也包含了以前版本的大多数注意事项。

我们确实计划在稍后发布另一个主要版本(甚至可能作为新的独立库),该版本建立在 Teleport 之上,届时你可以在你的 Vue 3 应用程序中按照自己的节奏迁移到新版本。

迁移策略

最常用的用例应该相当容易迁移,因为 PortalPortalTarget 组件只丢失了几个在 Vue 3 中不再需要的 prop,比如 slim(见下文)。

需要进行一些改进的重大更改会影响两个用例

  1. PortalTarget 端定义的过渡
  2. 删除 MountingPortal,现在可以通过 Teleport 更好地解决这个问题,除了一个边缘情况(multiple prop),我们将在下面介绍迁移路径。

更改列表

安装

由于创建 Vue 应用程序和注册插件的全局 API 有所改变,因此你还需要调整插件安装方式。

有关更多说明,请参阅有关 安装 的章节。

Portal 组件

删除 slim prop

在 Vue 3 中,组件不再需要根元素,因此 slim 不再需要。Portal 将不再渲染根元素,与插槽内容中的元素数量无关。

如果你需要一个包装元素,请自己将 <portal> 包装在一个元素中

html
<!-- Renders no element -->
<portal to="someTarget"></portal>

<!-- Wrap it in an element if you need it encapsulated i.e. for styling -->
<div>
  <portal to="someTarget"></portal>
</div>

PortalTarget 组件

删除 slim prop

在 Vue 3 中,组件不再需要根元素,因此 slim 不再需要。Portal 将不再渲染根元素,与插槽内容中的元素数量无关。

如果你需要一个包装元素,请自己将 <portal> 包装在一个元素中

html
<!-- will not render its content in a root element -->
<portal-target name="someTarget" />

<!-- Wrap it in an element if you need it encapsulated i.e. for styling -->
<div>
  <portal-target name="someTarget" />
</div>

新增:v-slot:wrapper

你现在可以向 PortalTarget 传递一个额外的命名插槽,该插槽可以用来在标记中分别包装来自多个 Portal 的内容。

html
<portal-target>
<portal-target name="target">
  <template v-slot:wrapper="nodes">
    <div class="some fancy box styles">
      <component :is="node" v-for="node in nodes" />
    </div>
  </template>
</portal-target>

参见:PortalTarget API:Wrapper 插槽

删除 transitiontransition-events prop。

现在,你可以在 <transition><transition-group> 组件中使用新的 v-slot:wrapper 来包装内容,而不是这些 prop。 在此处查看文档以了解更多信息

删除:MountingPortal

这个组件被删除了。根据你的用例,你有两种替代的迁移路径

  1. 你只从一个 Portal 中移动内容:使用 Vue 自身的 Teleport 代替(Teleport 文档
  2. 你想要将内容从多个地方移动到同一个已安装的 Portal:使用 createPortalTarget() 实用程序函数
html
<template>
  <portal to="target-name">
    <p>This is the content to move</p>
  </portal>
</template>

<script>
import { createPortalTarget } from 'portal-vue'

export default {

  created() {
    createPortalTarget('#id-of-target-element', {
      name: 'target-name'
      // portal props
    })
  }
}
</script>

在实践中,你可能会在更全局的位置调用一次这个函数,以便所有其他 Portal 组件都可以将内容移动到这个单独的 PortalTarget

Wormhole

Wormhole 是 PortalPortalTarget 组件之间的连接“存储”。在 PortalVue 2 中,它是一个单例,这意味着同一页面上的所有应用程序和库共享 to="" 名称的相同命名空间。

PortalVue 3 在安装插件时仍然向应用程序中的所有组件提供一个默认实例,但现在你可以选择创建自己的实例,并使用它代替默认实例。

在此处了解更多信息

测试