使用 Vue 做 SPA 实现的时候,路由系统是无法绕过的一个重要子系统:
- 使用路由系统对页面进行模块化
- 对浏览器的 History API 进行封装,构建良好的用户体验
- 借助路由的调用,作为响应式编程的发起端
- 路由的嵌套关系,可以很好的展示出路由的结构关系
Vue 的路由系统分三种模式
- hash模式: 使用 URL hash 值来作路由。默认模式
- history模式: 依赖 HTML5 History API 和服务器配置
- abstract模式: 适用于客户端,移动端的抽象调用机制
为了在使用单页面应用的时候,浏览器的「前进」和「后退」可以依然有效,需要通过调用 Vue Router 提供的方法进行页面跳转:
// HTML 中
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
// JS 中
router.push({ name: 'user', params: { userId: 123 }})
- type:
string
- default:
"hash" (in browser) | "abstract" (in Node.js)
- available values:
"hash" | "history" | "abstract"
Configure the router mode.
hash
: uses the URL hash for routing. Works in all Vue-supported browsers, including those that do not support HTML5 History API.history
: requires HTML5 History API and server config. See
HTML5 History Mode.abstract
: works in all JavaScript environments, e.g. server-side with Node.js. The router will automatically be forced into this mode if no browser API is present.从三种模式的介绍中也可以看出来,客户端环境中只支持使用 abstract 模式。vue-router 自身会对环境做校验,如果发现没有浏览器的 API,vue-router 会自动强制进入 abstract 模式,所以在使用时只要不写 mode 配置即可。默认 vue-router 会在浏览器环境中使用 hash 模式,在移动端原生环境中使用 abstract 模式。
浏览器的 History API 详情:
https://developer.mozilla.org/en-US/docs/Web/API/History_API
在 console 中调试
我在 Vue 的 app.js 的最后添加这么一段代码,协助在 console 中调试:
Vue.router = router; // 可以在chrome里面使用 Vue.router.go(-1) 类似的方法来进行调试
路由的嵌套
在我看来,展示出结构性上的特征可以大大的提高代码的可阅读性和程序的整体设计思路,所以具有可嵌套的路由结构是一种非常优雅的设计
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// UserProfile will be rendered inside User's <router-view>
// when /user/:id/profile is matched
path: 'profile',
component: UserProfile
},
{
// UserPosts will be rendered inside User's <router-view>
// when /user/:id/posts is matched
path: 'posts',
component: UserPosts
}
]
}
]
})
路由的 name属性
路由的 name属性 最主要的价值是对路由的设计进行解耦,方便做结构性上的调整,所以每一条路由都有一个 name 是非常重要的
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
路由的 props属性
路由的 props属性 也是为了解耦而设计的,通过路由将路由中的参数值传给到 components 里面,方便 components 的其他部分调用
不推荐的参数使用方式:
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
推荐的参数使用方式:
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true }
// for routes with named views, you have to define the props option for each named view:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
Navigation Guards
这是一个类似 Laravel Middleware 的机制,可以对路由访问的进出过程进行控制,方便对所有路由进行统一的功能性处理,有一个印度人做了一个视频,讲解的非常清楚:
《#5 Vue.js 2.0 and Router guard - authenticating Vue.js routes - Vue.js 2.0 and Laravel 5.3》
官方文档里面提供了一个例子的展示,非常一目了然:
https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js
懒加载
为了减少每个文件的大小,Vue Router 有一种懒加载的机制:
https://router.vuejs.org/en/advanced/lazy-loading.html
其他
后面的东西比较远了,等深度时候到的时候再补充