守卫分类
作用
通过跳转或取消的方式守卫导航。
PS:参数或查询的改变不会触发进入/离开的导航守卫。
1、全局守卫
const router = new VueRouter({
//coding
})
router.beforeEach((to, from, next) =>{
//coding
})
to: 即将进入的路由对象
from: 当前导航正要离开的路由对象
next: 通过这个方法来resolve导航钩子.
2、全局解析守卫(vue2.5+)
通过router.beforeResolve注册一个全局守卫. 和router.beforeEach类似, 区别是在导航被确认之前, 同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用.
3、全局后置钩子
通过router.afterEach注册, 这些钩子不会接受next函数也不会改变导航本身
router.afterEach((to, from) => {
//coding
})
4、路由独享守卫
const router = new Vue.VueRouter({
route:[
{
path:'/home',
component:Home,
beforeEach:(to, from, next) =>{
//coding
}
}
]
})
组件内的守卫
const Home = {
template: `Home`,
beforeRouteEnter(to, from, next){
next(vm =>{
//coding
})
// 在渲染该组件的对应路由被 confirm 前调用
// 组件实例未创建,无法获取组件实例 `this`
//可以通过回调next的方式访问组件实例
},
beforeTouteUpdate(to, from, next){
//当前路由改变,但该组件被复用时调用(如:/home/:id中,在/home/1和/home/2中间跳转时)
//可以访问组件实例this
},
beforeRouteLeave(to,from, next){
//导航离开组件时调用
//可以访问组件实例this
}
//PS:beforeTouteEnter是支持给next传递回调的唯一守卫,beforeTouteUpdate和beforeRouteLeave中,this已经可用了
}
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-router</title>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script>
const bar = {
template: 'bar-{
{userId}}',
computed: {
userId() {
return this.$route.params.userId }
},
//组件内的守卫
beforeRouteEnter (to, from, next) {
console.log('beforeRouteEnter')
next()
},
beforeRouteUpdate (to, from, next) {
console.log('beforeRouteUpdate')
next()
},
beforeRouteLeave (to, from, next) {
console.log('beforeRouteLeave')
next()
}
}
const error = {
template: 'oops! error'}
const home = {
template: 'this is home'}
const routes = [
{
path: '/error', component: error },
{
path: '/', component: home },
// 路由独享守卫,用法与beforeEach一样
{
path: '/bar/:userId', component: bar, beforeEnter: ((to, from, next) => {
console.log('beforeEnter')
next()
})
}
]
const router = new VueRouter({
routes
})
// 全局前置守卫: 进入to路由前执行
router.beforeEach((to, from, next) => {
console.log('beforeEach')
next()
// 跳转到指定页面
// 不能直接next('/error'),会陷入死循环
// to.path == '/error' ? next() : next('/error')
// 只能停留在当前页面
// next(false)
})
// 全局解析守卫
router.beforeResolve((to, from, next) => {
console.log('beforeResolve')
next()
})
// 全局后置钩子
router.afterEach((to, from) => {
console.log('afterEach')
})
const app = new Vue({
el: "#app",
router
})
</script>
</body>
</html>