Vue 嵌套路由又称多级路由。一些应用程序的UI由多层嵌套的组件组成(即一个路由下又配置了其它几个路由)。通过Vue Router,可以使用嵌套路由配置来表达这种关系。

路由介绍中的案例,为Home组件新增两个路由NewsMessage


配置嵌套路由

首先是配置Router(router/index.js):

 1import Vue from 'vue'
 2import VueRouter from 'vue-router'  // 引入 VueRouter
 3
 4// 引入组件
 5import Home from '../pages/Home.vue'
 6import About from '../pages/About.vue'
 7import News from '../pages/News.vue'
 8import Message from '../pages/Message.vue'
 9
10Vue.use(VueRouter)  // 应用 VueRouter 插件
11
12// 创建并导出 Router
13export default new VueRouter({
14  routes: [
15    { // 一级路由
16      path: '/about',
17      component: About,
18    },
19    { // 一级路由
20      path: '/home',
21      component: Home,
22      children: [
23        { // 二级路由,路径开头无需加 “/” 分隔符
24          path: 'news',
25          component: News,
26        },
27        { // 二级路由
28          path: 'message',
29          component: Message,
30        },
31      ]
32    },
33  ],
34})

在Router配置中,routes配置项的每个元素都是一级路由(AboutHome)。在每个一级路由中,可以使用children配置项为每个一级路由配置其子路由,也就是二级路由。children配置项的配置方式与routes配置项基本一致。

路由可以配置多个级别,也就是说除了一级路由可以使用children配置二级路由外,二级路由也可以使用children配置三级路由,以此类推。理论上可以配置无限个级别的路由,但是在实际开发过程中,路由最多可能就配置到第六层级。


使用嵌套路由

配置完嵌套路由后,需要在对应的组件中使用<router-link><router-view>来链接和展示。

嵌套路由的使用方式与普通的一级路由一样,都是使用<router-link><router-view>来链接和展示路由组件。只不过<router-link>在使用时有一些小细节。

如上,在Home组件中为其子路由添加<router-link>

 1<router-link 
 2  class="list-group-item" 
 3  active-class="active" 
 4  to="/home/news"
 5>
 6  News
 7</router-link>
 8<router-link 
 9  class="list-group-item" 
10  active-class="active" 
11  to="/home/message"
12>
13  Message
14</router-link>

可以看出,为NewsMessage添加的<router-link>,其to Prop配置的都是以/home开头的完整的目录路径。

这是因为,如果使用相对路径,那么路由的路径可能会出错。


路由 Query 传参

路由有了嵌套的关系之后,必然会涉及到父子路由之间数据的传递。Vue Router可以像调用API一样,让路由通过Query的形式传递参数。

Query传参形式也就是在URL后,以?为开始,使用&分隔每个参数项的参数传递方式。例如:http://localhost:8080/home/user?name=张三

假设现在有个名为MessageDetail的路由组件,该组件是Message的子路由组件,且需要Message给他传递一些消息数据。

 1/* import... */
 2import MessageDetail from '../pages/MessageDetail.vue'
 3
 4Vue.use(VueRouter)  // 应用 VueRouter 插件
 5
 6// 创建并导出 Router
 7export default new VueRouter({
 8  routes: [
 9    { // 一级路由
10      path: '/about',
11      component: About,
12    },
13    { // 一级路由
14      path: '/home',
15      component: Home,
16      children: [
17        { // 二级路由
18          path: 'news',
19          component: News,
20        },
21        { // 二级路由
22          path: 'message',
23          component: Message,
24          children: [
25            { // 三级路由
26              path: 'detail',
27              component: MessageDetail,
28            }
29          ],
30        },
31      ]
32    },
33  ],
34})

传递 Query 参数

在Vue Router中,使用<router-link>to prop给Route组件实例传参。<router-link>传递Query参数有两种方式:

  • 字符串拼接:

    1<router-link 
    2  :to="`/home/message/detail?id=${message.id}&title=${message.title}`"
    3>
    4  {{ message.title }}
    5</router-link>
    
  • 传入对象:通过v-bind指令给to prop传递一个对象类型的参数。通过这个to prop对象指定传递的Query

    1<router-link :to="{
    2  path: '/home/message/detail',
    3  query: {
    4    id: message.id,
    5    title: message.title,
    6  }
    7}">
    8  {{ message.title }}
    9</router-link>
    

    to prop对象中的query属性中配置传递的参数以及它们的值。query属性的key是传递的参数的名称,value是传递的参数的值(就像Axios的params配置那样)。

接收 Query 参数

接收参数需要在对应的路由组件中进行配置。

如上,在MessageDetail路由组件中,使用路由组件实例的$route.query对象接收并获取这些参数:

1computed: {
2  id() {
3    return this.$route.query.id
4  },
5  title() {
6    return this.$route.query.title
7  }
8},

Vue Router的Query参数都会被对应的路由组件的实例中的$route.query对象接收。通过$route.query.argName的形式获取这些参数的值。

注:

获取Query参数的形式很固定,为了使代码更加简介、书写更加简便,可以如上使用computed属性来接收它们的值。当然还有其它更简便的方法。

在Vue Router中,使用Query形式传递的参数,即使它们在对应的路由组件中没有被使用,依然会被$route.query接收到。


命名路由

当嵌套路由的路径过长时,在<router-link>to prop中,就需要配置一串冗长的路径。通过为路由指定name字段,然后在<router-link>to prop对象中使用name属性指定使用的路由。

修改上例,给MessageDetail的路由添加name,并且在<router-link>使用to prop的name指定它:

1{
2  name: 'MessageDetail',  // 路由名称
3  path: 'detail',
4  component: MessageDetail,
5},
1<router-link :to="{
2  name: 'MessageDetail',
3  params: {
4    id: message.id,
5    title: message.title,
6  }
7}">
8  {{ message.title }}
9</router-link>

<router-link>使用to prop的name指定了路由后,就无需使用to prop的path指定一段冗长的路径。