- 开始时间:2020-02-20
- 目标主要版本:Vue Router 4.x
- 引用 issue:N/A
- 实现的 PR:N/A
摘要
鉴于 Vue3 中函数式组件的变化,KeepAlive 和 Transition 的使用与 RouterView 的结合不再是简单的用 KeepAlive/Transition 来包装 RouterView 就可以实现的。相反,我们需要一种方法来直接向这些组件提供由 RouterView 渲染的组件:
<router-view v-slot="{ Component }"><transition :name="transitionName" mode="out-in"><component :is="Component"></component></transition></router-view>
基本范例
N/A
动机
正如在 https://github.com/vuejs/vue-next/issues/906#issuecomment-611080663,我们需要一个新的 API 来允许 KeepAlive 和其他接受插槽的 RouterView 的组件。为了实现这样的行为,我们需要能够直接包装 RouterView 所渲染的组件和传递给它的属性。
具体设计
我们可以通过一个插槽实现这种控制的水平:
<router-view v-slot="{ Component, route }"><component :is="Component" v-bind="route.params"></component></router-view>
在这个例子中,Component 是组件的定义,可以传递给函数 h 或组件的 is 属性。
当在路由定义中定义一个 props: true 选项时:
没有匹配的例子
当当前的位置没有被 Router 注册的任何记录所匹配时,RouterLocation 的 matched 数组是空的,默认情况下,当没有插槽时,它不会渲染任何内容。当我们提供一个插槽时,我们可以决定显示什么,无论我们想显示一个未找到的页面,还是我们想要的默认行为,我们都可以做到这一点。如果没有组件需要渲染,Component 将是假的:
<router-view v-slot="{ Component, route }"><component v-if="route.matched.length > 0" :is="Component"/><div v-else>Not Found</div></router-view>
请注意,在显示未找到的页面时,这种行为与 catch all 路由(path: '/:pathMatch(.*)‘)是多余的。
v-slot 属性
Component:可以传递给函数h或component的is属性的组件route:由RouterView渲染的规范化 Route 位置。与$route相同,但允许在 JSX 中简单和类型化的访问。
用 Transition 或 KeepAlive 包装 RouterView
如果用户不小心用 Transition 包装了 RouterView,或者正在将他们的应用程序迁移到 Vue3,我们可以发出一个警告,志向文档(同时时这个 RFC)并提示他们使用 v-slot api。
同时使用 KeepAlive 和 Transition
当同时使用 KeepAlive 和 Transition 时,我们需要先用 Transition 再用 KeepAlive:
<router-view v-slot="{ Component }"><transition name="fade" mode="out-in"><keep-alive><component :is="Component"></component></keep-alive></transition></router-view>
缺点
N/A
备选方案
- 使用像
useView这样的函数,将返回Component和attrs,删除v-slot的使用。
采纳策略
- codemod 可以将 v3 重写成 v4
没有解决的问题
N/A
