官方文档 官方API文档
npm install vue-router
// router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
// 模块化工程中,Vue.use() 是必须的
Vue.use(VueRouter);
// 抛出模块,用于跟组件注册
const router = new VueRouter({
// ...
});
export default router
// main.js 需要引入 router
import router from './router/index.js';
// vue根组件注册 router
new Vue({
router: router
});
单页应用:
最简单的例子:
Hello App!
Go to Foo
Go to Bar
组件可以通过 "this.$router" 访问路由器,通过 "this.$route" 访问当前路由。 官方完整例子
1. 动态路由匹配: [ "path" ]
// 有如下 routes 配置
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
// 像 /user/foo 和 /user/bar 都将映射到相同的路由。
// User 组件内可以访问路径参数 "id"
console.log(this.$route.params); // { id: 'foo' }
// 像 /user/:username/post/:post_id 的多段"路径参数"
console.log(this.$route.params); // { username: 'evan', post_id: '123' }
注意,当使用路由参数时,如从 /user/foo 导航到 /user/bar ,组件实例会被复用,其生命周期函数将不会被调用。
2. 嵌套路由: [ "children" ]
// 组件的模板需要添加一个
const User = {
template: `
User {{ $route.params.id }}
`
}
const router = new VueRouter({
routes: [{
path: '/user/:id', component: User,
// children 配置与 route 类似
children: [
// 当 /user/:id/profile 匹配成功,UserProfile 会被渲染在 User 的 中
{ path: 'profile', component: UserProfile },
// 当 /user/:id/posts 匹配成功,UserPosts 会被渲染在 User 的 中
{ path: 'posts', component: UserPosts },
// 当你访问 /user/foo 时,User 的出口是不会渲染任何东西,需要提供一个"空的"子路由
{ path: '', component: UserHome }
]
}]
})
注意,以 "/" 开头的嵌套路径会被当作根路径,合理做法是使用"空路径"(" ")。 官方完整例子
3. 单视图组件注册: [ "component" ]
4. 多视图组件注册: [ "components"
5. 命名路由: [ "name" ]
const router = new VueRouter({
routes: [{
path: '/user/:userId',
// 用于 路由跳转
name: 'user',
component: User
}]
})
// 使用"声明式"路由跳转
// User
// 使用"函数式"路由跳转
// router.push({ name: 'user', params: { userId: 123 }})
6. 路由 跳转/替换: [ "
方法1,声明式,使用
User
方法2,编程式,使用 router.push(...)
// 若路径已用"name"命名,可以用 name 代替 path
router.push({ path: 'home' })
// "/user?plan=private"
router.push({ name: 'user', query: { plan: 'private' }})
// 注意:如果提供了 path,params 会被忽略,正确写法如下:(已定义 userId=123 )
router.push({ path: `/user/${userId}` }) // -> /user/123
// 替换当前路由(覆盖当前的history记录),用法与 .push() 一致
router.replace(...)
// 前进/后退,n 是整数,负数表示后退
router.go(n)
7. 重定向 & 别名 : [ "redirect" & "alias" ]
const router = new VueRouter({
routes: [
// 重定向
// 当用户访问 /a时,URL 将会被替换成 /b
{ path: '/a', redirect: '/b' },
// 重定向到指定 name
{ path: '/a', redirect: { name: 'foo' }},
// 别名
// 当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a
{ path: '/a', component: A, alias: '/b' }
]
})
8. 路由组件传参: [ "props" ] 个人完整在线demo
/vue_a/123
/vue_b
/vue_c?q=query
9. History模式: [ "mode" ]
const router = new VueRouter({
// 默认是"hash"
mode: 'history',
routes: [...]
})
10. 路由元信息: [ "meta" ]
// 官方的例子是利用"meta"的"requiresAuth"属性,实现组件是否需要权限访问
routes: [{
path: '/foo',
component: Foo,
children: [{
path: 'bar',
component: Bar,
// "requiresAuth"为自定义字段
meta: { requiresAuth: true }
}]
}]
// 在全局导航守卫中检查元字段:
router.beforeEach((to, from, next) => {
// 获取目标路径是否带有指定的"meta"字段,并进行相关鉴权或操作
if (to.matched.some(record => record.meta.requiresAuth)) {
// 鉴定是否登陆,否则跳转到登陆页面
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else { next() }
} else {
next() // 确保一定要调用 next()
}
})
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置,格式: { x: number, y: number }
// scrollBehavior 的值就是{x:number,y:number}格式的对象
}
})
1. 全局守卫:
const router = new VueRouter({ ... })
// 全局前置守卫
router.beforeEach((to, from, next) => { ... })
// 全局后置钩子,不接受next()
router.afterEach((to, from) => { ... })
2. 路由独享守卫:
const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
// 路由独享守卫
beforeEnter: (to, from, next) => { ... }
}]
})
3. 组件内的守卫:
const Foo = {
template: `...`,
// 不能访问'this',但可以通过next()回调参数访问当前组件,如下
beforeRouteEnter (to, from, next) {
next(vm => { ... })
},
// 可以访问'this',只有在动态路径之间跳转才触发
beforeRouteUpdate (to, from, next) { ... },
// 可以访问'this',只有在非动态路径之间跳转才触发,该函数常用于判断用户是否保存,否则阻止跳转,如下
beforeRouteLeave (to, from, next) {
if (confirm) { next(); } else { next(false) }
}
}
注意, "next()" 钩子函数必须调用。
完整的导航解析流程:
个人在线demo
1. 父级路由不能含有 "name" 属性,否则会提示如下错误:
2. 关于路由的两种模式: hash模式 和 history 模式
视觉上的区别是:hash模式下,主机名后面带有"#",更多查看 其他博客 。