路由详解-基础
router-link和router-view组件
router-link: 封装了一个a标签
router-view: 视图渲染组件
路由配置
动态路由
router/index.js
{
path: '/about/:name',
component: () => import('../views/About.vue')
}
about.vue
This is an about page
传递的参数是: {{ $route.params.name}}
// $route 当前路由对象
嵌套路由
router/index.js
{
path: '/parent',
component: () => import('../views/parent.vue'),
children: [
{
path: 'child',
component: () => import('../views/child.vue')
}
]
}
parent.vue
这是parent.vue页面
child.vue
这是children.vue页面
效果
命名路由
router-link标签的to属性, 可以通过传入路径或者传入name值进行跳转
注意写法: :to="{name:'Home'}"
Home
Home
router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home
}
}
命名视图
一个页面内可以使用多个router-view组件, 如果 router-view 没有设置名字,那么默认为 default。
app.vue
router/index.js
{
path: '/name',
components: {
default: () => import('../views/About.vue'),
parent: () => import('../views/parent.vue'),
child: () => import('../views/child.vue')
}
}
效果
重定向和别名
重定向
router/index.js
{
path: '/test',
redirect: '/'
}
别名
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
js操作路由
文档
路由详解-进阶
官方文档
导航守卫
导航守卫就是路由跳转过程中vue-router的生命周期,路由跳转是一个大的过程,这个大的过程分为跳转前中后等等细小的过程,在每一个过程中都有一函数,这个函数能让你操作一些其他的事儿的时机,这就是导航守卫。
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用离开守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫 (2.5+)。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
全局前置守卫
beforeEach
const router = new VueRouter({
routes
})
// 根据常量HAS_LOGINED判断用户是否登录, 如果未登录, 则用户只能跳转到登录页面, 如果用户已经登录, 那么无法进入登录页面
const HAS_LOGINED = false
router.beforeEach((to, from, next) => {
console.log('要去的页面', to.path)
console.log('离开的页面', from.path)
if (to.path === '/login') {
if (HAS_LOGINED) {
next('/')
} else {
console.log('已经进入了login页面')
next()
}
} else {
if (HAS_LOGINED) next()
else next('/login')
}
})
路由守卫
你可以在路由配置上直接定义 beforeEnter
守卫:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
这些守卫与全局前置守卫的方法参数是一样的。
组件内的守卫
你可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteEnter 守卫 不能 访问 this
,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}