• 开始时间:2020-04-01
  • 目标主要版本:(2.x 或 3.x)
  • 引用 issue:Vue Router v3 and v4
  • 实现的 PR:

摘要

添加一个 route 属性,允许自定义 router-view 组件所显示的内容。这样允许用户显示一个不是连接到 URL 的视图。它可以实现像模版(https://github.com/vuejs/vue-router/issues/703#issuecomment-428123334)这样的模式。

基本范例

想象一下,一个 backgroundView 变量可以让我们知道是否在显示不同的 route。然后,我们可以计算出一个 route 的位置,这个位置将解析为与 url 上显示的位置不同:

  1. const App = {
  2. computed: {
  3. routeWithModal() {
  4. if (backgroundView) {
  5. return this.$router.resolve(backgroundView)
  6. } else {
  7. return this.$route
  8. }
  9. }
  10. }
  11. }

我们可以将这个变量传递给 router-view

  1. <router-view :route="routeWithModal"></router-view>

这将在大多数情况下显示与当前 url(this.$route)相关的组件,而在其他情况下显示一些不同的东西,同时仍然暴露出 this.$route 的解析位置。

动机

根据设计,Vue Router 将一个 URL 与一个组件联系起来。这有时是一种限制,就像 modals 一样,并且也允许摆脱这种限制。在不使用黑客手段的情况下很难实现在用户端解决方案(比如,在这个例子中修改 this.$route),因为它涉及到改变当前位置。从实现的角度来看,暴露出一种修改 router-view 所显示内容的方法是很直接的。

具体设计

Vue Router 以经暴露了解析位置的机制,所以用户可以使用一些全局状态(最好是保存在 window.history.state 中,这样在使用浏览器的后退和前进按钮进行导航时就可以恢复)来生成一个可以被 router-view 消耗的解析的位置。

在内部,router-view 必须确保它的子元素(嵌套视图)使用相同的位置以保持一致。在 v4 中,使用 inject/provide 应该会使这个问题变得很简单,在 v3 中,我们可能需要像 depth 那样进行查询。如果提供了一个 route 属性,它就会优先于接受该属性的 router-view 及其所有子视图上的任何提供的 route。

最终用户的 API 是一个属性:

  1. <router-view :route="routeWithModal"></router-view>

缺点

  • 为了使这种机制与懒加载一起工作,它需要之前已经导航已经解析的 route。这可以确保任何懒加载的视图已经被获取和捕获了。在 modals 的情况下,这是自动的,因为我们已经在我们想让 router-view 显示的视图上了。我们认为这个限制是有意义的,因为除了 Modals,我想不出其他案例,当涉及到显示一个与 URL 没有关联的视图时。

备选方案

  • 一个组合式函数 useView,返回一个响应式组件,与 一起使用。这个解决方案比一个属性要复杂得多。

采纳策略

N/A

没有解决的问题

N/A