在理解守卫之前啊 举一个生活中的例子 比如一家公司,它会在门口雇一个保安,如果呢你是这家公司的员工或者领导 保安就允许你进入公司,如果你不是公司内部人员,那么你进去,保安会把你拦截住,其实啊导航守卫也是一个道理,比如说我没有登录 那我要访问个人信息页面 是不是也要进行拦截啊。所以啊 导航守卫的意思是 从一个路由跳转另一个路由 你要对他进行怎样的操作,究竟是可以访问呢,还是不可以呢?
守卫大致分为三个: 1.组件内的守卫 3 路由独享守卫 3.全局守卫
每个守卫都有三个参数
1.to :要跳转的路由对象(去哪?)
2.from: 导航要离开的路有对象(从哪来?)
3.next: next()是一个方法,他决定你可不可以去跳转的路由(保安)
next()允许放行
next(false) 不允许放行 回到原来的页面
next(' / ') || next({path: ' / ' }) 进入指定的路由
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
,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
beforeRouteUpdate 用于带参数的跳转
beforeRouteLeave 适用于离开时 有未写完的文字 给一个是否可以跳转的弹出
分别对这三个进行组件守卫进行演示
beforeRouteEnter 栗子
beforeRouteEnter (to, from, next) {
console.log(this)
console.log(to, from)
// next() //注意奥 这里把next()注释了 任何人访问不了本页面哦
}
beforeRouteUpdate栗子
beforeRouteUpdate (to, from, next) {
console.log(this) //可以获取this
console.log(to)
console.log(from)
next()
}
beforeRouteLeave栗子 简单模拟一个留言板
代码
beforeRouteLeave (to, from, next) {
const context = document.getElementById('context')
if (context.value) {
confirm('确认要跳转吗') ? next() : next(false)
} else {
next()
}
}
定义在router/index.js中 听到全局这个名字也就是所有路由进行跳转都可以指定是否可以放行
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
使用场景 判断用户是否有权限访问我的信息
import vuex from '../store/index'
import router from './index'
const listVip = ['/setting']
router.beforeEach((to, from, next) => {
const token = vuex.state.tokenInfo.token // 获取token
console.log(to.fullPath) // 路径
if (listVip.includes(to.path)) { // 如果要访问vip页面
if (token) { // 如果有token
next()
} else {
// 没有token 就去登录页
next('/login?returnUrl=' + to.fullPath) // 记得去登录页带着要访问的路径 否则登陆成功的话 不带参数一直去登录页面
console.log('没登录 去登录页')
}
} else if (token && to.path === '/login') { // 如果已经登录了 就不能在访问登录了
console.log('已经登录了 拒绝访问')
next('/')
} else { // 如果访问的不是vip页面 就直接放行
next()
}
})
简化代码
import store from '@/store/index.js'
const vipList = ['/setting'] //1. 定义会员项(只有会员可以访问 )
router.beforeEach((to, from, next) => { // 2. 定义前置守卫
const token = store.state.tokenInfo.token //3.拿去vuex的token
console.log(token)
if (!token && vipList.includes(to.path)) { //4.如果没有token 并且访问会员页面
console.log('没有权限,不能访问vip页面') // 5.不能访问
next('/login) // 6.返回到登录页
} else if (token && to.path === '/login') { // 7.如果有token 就不能访问登录页了
console.log('已经登录了,就不能访问login了')
next('/') // 8.返回到首页
} else {
next() // 9.如果不是会员页 可以访问
}
})
export default router //10.导出
router.afterEach((to, from) => {
// ...
})
注意没有next()方法 适用于计算访问的次数