不只懂 Vue 语法:试解释嵌套路由与嵌套命名视图的概念?

问题回答

嵌套路由是指在一个 router-view 里包 router-view,像是在一个画框里,再加上一个画框。例如 /products/tshirt/products/shoes,做法可以是在 Product.vue 此页面元件里再加一个 router-view,用来切换显示 Tshirt 与 Shoes 元件。

至於嵌套命名视图,其实是结合「嵌套路由」和「命名视图」这两个概念。前者就是以上提到的意思。後者就是指,当一个画面要同时显示多於一 router-view 时,就必须要使用命名视图(named view)。

结合两者概念的话,就是指在一个 router-view 里包 router-view,并在内层的 router-view 里,再包多於一个的 router-view(需使用命名视图)。

虽然这题不是常见面试题,但实作时这两个概念出现的机会挺高。而且作为新手,自己也曾试过搞混了两者的意思,因此想写一篇文章来整理概念。

嵌套路由(Nested Routes)是什麽?

嵌套路由较易理解,先看看官方解说图:

截图自官方文件

简单说,就是在一个元件里放一个 router-view,在这里可以切换显示不同的元件。以上例子就是切换 Profile 与 Posts。

为什麽叫嵌套?因为如果你使用 Vue CLI,别忘了最顶层预设已经放了一个 router-view。示范一下,你刚建立 Vue CLI 专案时,会有以下预设程序码:

App.vue

<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
  <router-view/>
</template>

你可以把 nav 删除,这样看就更清晰:

<template>
  <router-view/>
</template>

预设路由设定是:

router/ index.js

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  }
]

用 Vue 检查工具看,一目了然:

所以,初始化时,最顶层一定会有一个 router-view,不然没法显示元件。这个 router-view 的作用就像一个画框一样,你可以随时切换显示不同元件,也就是 SPA 的概念:

回到重点,如果在元件里,再加一个 router-view,并可以切换显示不同元件,这就是嵌套路由的意思了。白话讲,就是在一个画框里的元件上,再放一个画框,切换显示不同元件。

/about 页面为例,在 about 页面加上一个 router-view,切换显示 SkillsGreetingContact 这三个元件。

About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <router-link to="/about/greeting"> Greeting</router-link>
    <router-link to="/about/skills"> Skills </router-link>
    <router-link to="/about/contact"> Contact </router-link>
    <router-view></router-view>
  </div>
</template>

使用 children 设定嵌套路由:
router/ index.js

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
    children: [
      {
        path: 'skills',
        component: Skills
      },
      {
        path: 'greeting',
        component: Greeting
      },
      {
        path: 'contact',
        component: Contact
      }
    ]
  }
]

然後各自建立 Skills.vue、Greeting.vue、Contact.vue 的档案,这里就不示范了。目前 About 里的的概念如下:

结果就是在 About 元件里的 Router view 内,可以不断切换元件:

预设显示指定嵌套路由

注意,当你进入 /about 页面,结果会是空的,因为目前是路由是 /about ,并不是 /about/skills/about/greeting 或者 /about/contact。如果想预设显示某个嵌套路由的元件,举例说是 Skills,就要把 path 设定为 ''

router/ index.js

  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
    children: [
      {
        path: '',
        component: Skills
      },
      ...
    ]
  }

结果访问 /about 时,就会渲染 Skill 元件。

嵌套命名视图(nested named view)是什麽?

了解过嵌套路由,就很快会理解嵌套命名视图。在这之前,要先知道什麽是命名视图。当一个画面里,我们想设置多於一个 router-view 时,其他 router-view 就需要具名,不然 Vue 不知道这些视图要放什麽元件。因此,命名视图就是当画面上有多於一个 router-view 时,所需要的元素。

以後台 dashboard 为例,在同一个画面里,左边 Sidebar,右边有 Banner 和 Content。我们在同一个画面放置 3 个 router-view,其中一个可以不用命名,即是预设 router-view,其余两个就要命名。

以上例子就是在 App.vue 放置 3 个 router-view,以下先省略 CSS 部分。

<template>
      <router-view name="Sidebar" />
      <router-view name="Banner" />
      <router-view/>
</template>

router/ index.js

const routes = [
  {
    path: '/',
    components: {
      default: Content,
      Banner,
      Sidebar
    }
  }
]

嵌套命名视图 = 嵌套路由 + 命名视图

嵌套命名视图就是结合以上提到「嵌套路由」、「命名视图」的概念。再以後台 dashboard 作例子。

假设现在有首页、产品页。在产品页里,有分 T-shirt 和 Shoes 产品。在 T-shirt 页里,用 2 个 router-view 显示男女装 T-shirt。而在 Shoes 页里,也用 2 个 router-view 显示 Sneakers 和 Boots。

所以,Product 页的结构如下:

  • Products.vue 是页面元件。
  • Sidebar 是在 Product.vue 里的元件。里面有 2 个 route-link,分别会连到 products/tshirtproducts/shoes
  • 用预设 router-view(即是匿名 router-view)来显示 WomenShirt。

详细程序码最後才分享,以下先看重点部分。

最外层 App.vue,放置 router-link 以及 router-view,让使用者切换浏览主页以及产品页:

<template>
  <router-link to="/"> Homepage </router-link>
  <router-link to="/products"> Products </router-link>
  <router-view />
</template>

点击 Products 後,进入 Products 页:

Products.vue

<template>
  <div class="page">
    <Sidebar />
    <div class="content">
      <!-- 当切换到 "/products/tshirt",以下才会显示-->
      <router-view />
      <router-view name="MenTshirt" />
      <!-- 当切换到 "/products/shoes",以下才会显示-->
      <router-view name="Sneakers" />
      <router-view name="Boots" />
    </div>
  </div>
</template>

以上画面中间内容是空,因为现在是在 /products,不是 /products/tshirt 或者 /products/shoes,所以不会显示这里的 router-view。当按下 Nav 的按钮,就能切换显示相应的 router-view。

看看核心部分 router / index.js

const routes = [
  {
    path: "/",
    component: Home
  },
  {
    path: "/products",
    component: Products,
    children: [
      {
        path: "tshirt",
        components: {
          default: WomenTshirt,
          MenTshirt
        }
      },
      {
        path: "shoes",
        components: {
          Sneakers,
          Boots
        }
      }
    ]
  }
];

以上可见,当切换到 /products/tshirt 时,才会显示 WomenTshirt 和 MenTshirt。/products/shoes 则会显示 Sneakers 和 Boots。

完整程序码

https://codesandbox.io/s/qian-tao-ming-ming-shi-tu-6cbmo?file=/src/App.vue:0-142

总结

  • 嵌套路由是指一个 router-view 里,再包一个 router-view
  • 当在同一个画面需要用多於一个 router-view,就需要用命名视图。
  • 嵌套命名视图就是结合以上两者的概念。

参考资料

Vue Router - 嵌套命名视图


<<:  30天学会C语言: Day 19-考试常用的输入格式

>>:  [Day 20] 实作-主题推荐页面 组件传递资料

[ 卡卡 DAY 13 ] - React Native 页面导览 Navigation (上)

Navigation 的用处? 在一个 App 中一定会有很多页面, Navigation 提供简...

树选手1号:decision tree [python实例]

今天来用decision tree做一个预测肿瘤是恶性还是良性的应用,在这里就略过前期的资料处理与分...

DAY 8 『 CollectionView 』Part1

CollectionView:Storyboard、Xib + Collection View + ...

Rails基本介绍(三)--Migration简单操作

周一,要装得认真点~ 本篇会说到的。 Why? 名词单数复数查询。 Migration。 为何还需...

OFFICE365 企业版的SMTP设定

公司导入OFFICE365 大部分的员工都是用EXCHANGE的方式去连线 可是有部分装置或是软件仍...