vue-router
动态路由匹配(Dynamic Route Matching)
路径参数
一个“路径参数”使用冒号 : 标记。
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: ‘evan’ } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: ‘evan’, post_id: 123 } |
匹配优先级
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。
1 | const routes = [ |
当路由参数为bar时,/foo/bar 匹配了两个路由,这时就就会遵循路由匹配优先级规则。
嵌套路由
一个被渲染组件同样可以包含自己的嵌套 <router-link :to=”…”> 。例如,在 Deatil 组件的模板添加一个 <router-link :to=”…”>
路由组件中包含<router-link :to=”…”>
1 | <template> |
定义嵌套路由
1 | { |
编程式的导航(Programmatic Navigation)
router.push(location, onComplete?, onAbort?)
声明式 | 编程式 |
---|---|
<router-link :to=”…”> | router.push(…) |
1 | // 字符串 |
router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
<router-link :to=”…” replace> | router.replace(…) |
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。1
2
3
4
5
6
7
8
9
10
11
12// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
重定向和别名
重定向(redirect)
1 | { |
别名(alias)
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。1
2
3
4
5const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
router.mode
类型: string
默认值: “hash” (浏览器环境) | “abstract” (Node.js 环境)
可选值: “hash” | “history” | “abstract”
history: 依赖 HTML5 History API 和服务器配置。
导航守卫(Navigation Guards)
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
全局守卫
使用 router.beforeEach 注册一个全局前置守卫:1
2
3
4
5
6
7const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
export default router
每个守卫方法接收三个参数:
to: Route: 即将要进入的目标路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
例子,在每次路由跳转时判断用户的登录状态
1 | // router.js |
确保要调用 next 方法,否则钩子就不会被 resolved。
全局后置钩子
全局后置钩子与守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:1
2
3router.afterEach((to, from) => {
// ...
})
过渡动效
单个路由过渡
1 | const Foo = { |
基于路由的动态过渡
1 | <!-- 使用动态的 transition name --> |
1 | // 接着在父组件内 |
路由懒加载
有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。1
2
3
4
5const Login = () => import(/* webpackChunkName: "group-login" */ './Login.vue')
const User = () => import(/* webpackChunkName: "group-user" */ './User.vue')
const Fund = () => import(/* webpackChunkName: "group-detail" */ './Fund.vue')
const Company = () => import(/* webpackChunkName: "group-detail" */ './Company.vue')
const Manager = () => import(/* webpackChunkName: "group-detail" */ './FunManager.vue')
vue-router demo
源码解读
参考网址: Vue Router
人的一切痛苦,本质上都是对自己的无能的愤怒。
——王小波