从 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 应用程序中按照自己的节奏迁移到新版本。
迁移策略
最常用的用例应该相当容易迁移,因为 Portal
和 PortalTarget
组件只丢失了几个在 Vue 3 中不再需要的 prop,比如 slim
(见下文)。
需要进行一些改进的重大更改会影响两个用例
- 在
PortalTarget
端定义的过渡 - 删除
MountingPortal
,现在可以通过Teleport
更好地解决这个问题,除了一个边缘情况(multiple
prop),我们将在下面介绍迁移路径。
更改列表
安装
由于创建 Vue 应用程序和注册插件的全局 API 有所改变,因此你还需要调整插件安装方式。
有关更多说明,请参阅有关 安装 的章节。
Portal 组件
删除 slim
prop
在 Vue 3 中,组件不再需要根元素,因此 slim
不再需要。Portal
将不再渲染根元素,与插槽内容中的元素数量无关。
如果你需要一个包装元素,请自己将 <portal>
包装在一个元素中
<!-- 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>
包装在一个元素中
<!-- 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
的内容。
<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 插槽
删除 transition
、transition-events
prop。
现在,你可以在 <transition>
或 <transition-group>
组件中使用新的 v-slot:wrapper
来包装内容,而不是这些 prop。 在此处查看文档以了解更多信息
删除:MountingPortal
这个组件被删除了。根据你的用例,你有两种替代的迁移路径
- 你只从一个
Portal
中移动内容:使用 Vue 自身的Teleport
代替(Teleport 文档) - 你想要将内容从多个地方移动到同一个已安装的 Portal:使用
createPortalTarget()
实用程序函数
<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 是 Portal
和 PortalTarget
组件之间的连接“存储”。在 PortalVue 2 中,它是一个单例,这意味着同一页面上的所有应用程序和库共享 to=""
名称的相同命名空间。
PortalVue 3 在安装插件时仍然向应用程序中的所有组件提供一个默认实例,但现在你可以选择创建自己的实例,并使用它代替默认实例。