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

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


配置嵌套路由

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

import Vue from 'vue'
import VueRouter from 'vue-router'  // 引入 VueRouter

// 引入组件
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'

Vue.use(VueRouter)  // 应用 VueRouter 插件

// 创建并导出 Router
export default new VueRouter({
  routes: [
    { // 一级路由
      path: '/about',
      component: About,
    },
    { // 一级路由
      path: '/home',
      component: Home,
      children: [
        { // 二级路由,路径开头无需加 “/” 分隔符
          path: 'news',
          component: News,
        },
        { // 二级路由
          path: 'message',
          component: Message,
        },
      ]
    },
  ],
})

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

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


使用嵌套路由

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

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

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

<router-link 
  class="list-group-item" 
  active-class="active" 
  to="/home/news"
>
  News
</router-link>
<router-link 
  class="list-group-item" 
  active-class="active" 
  to="/home/message"
>
  Message
</router-link>

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

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


路由 Query 传参

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

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

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

/* import... */
import MessageDetail from '../pages/MessageDetail.vue'

Vue.use(VueRouter)  // 应用 VueRouter 插件

// 创建并导出 Router
export default new VueRouter({
  routes: [
    { // 一级路由
      path: '/about',
      component: About,
    },
    { // 一级路由
      path: '/home',
      component: Home,
      children: [
        { // 二级路由
          path: 'news',
          component: News,
        },
        { // 二级路由
          path: 'message',
          component: Message,
          children: [
            { // 三级路由
              path: 'detail',
              component: MessageDetail,
            }
          ],
        },
      ]
    },
  ],
})

传递 Query 参数

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

  • 字符串拼接:

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

    <router-link :to="{
      path: '/home/message/detail',
      query: {
        id: message.id,
        title: message.title,
      }
    }">
      {{ message.title }}
    </router-link>
    

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

接收 Query 参数

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

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

computed: {
  id() {
    return this.$route.query.id
  },
  title() {
    return this.$route.query.title
  }
},

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指定它:

{
  name: 'MessageDetail',  // 路由名称
  path: 'detail',
  component: MessageDetail,
},
<router-link :to="{
  name: 'MessageDetail',
  params: {
    id: message.id,
    title: message.title,
  }
}">
  {{ message.title }}
</router-link>

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