一、导航守卫
1、导航守卫的需求和业务场景
需求:我们在一个SPA应用中,如何改变网页的标题?
- 网页标题是通过
<title>
标签来显示的,但是SPA只有一个固定的HTML,切换不同页面时,标题是不会变的。 - 但是我们可以通过JavaScript来修改
<title>
的内容,window.document.title='新的标题'
。
普通修改方式:
在对应路由的组件.vue文件中,通过mounted声明函数,执行对应代码进行修改就可以了。
但如果当页面足够的多,我们就需要在不同的页面执行类似的代码,很繁琐也不便于维护。
2、什么是导航守卫
- vue-router提供的导航守卫主要是用来监听路由的进入和离开。
- vue-router提供了
beforeEach
和afterEach
的钩子函数,它们会在路由即将改变前、后触发。
二、类型
1、全局守卫
- 首先配置路由
meta
属性
C87CB07B8D42DF78AD2FCB94FBF079AC.jpg
- 利用
beforeEach
完成标题的修改。-
to
:即将要进入的目标路由对象。 -
from
:当前导航即将要离开的对象。 -
next
:调用该方法后,才能进入到下一个钩子(这里必须调用)。
930BB17BDF788ADF5BDD658651F28C17.jpg
matched[0]
在路由嵌套的时候,在meta
中获取不到title
,要在matched[0]
获取。
所有的这些操作都在index.js
文件中完成,维护起来相对简单,不用一个一个文件去修改,下面是目前index.js
中的代码。
-
const Home = () => import('../components/home')
const HomeNews = () => import('../components/home/homeNews')
const HomeMessage = () => import('../components/home/homeMessage')
const About = () => import('../components/about')
const User = () => import('../components/user')
const Profile = () => import('../components/profile')
//配置路由相关信息
//1、导入插件
import Router from 'vue-router'
//2、通过Vue.use(插件),安装插件
import Vue from 'vue'
Vue.use(Router)
//3、创建路由对象
const routes = [{
//设置默认路由
path: '',
redirect: '/home'
}, {
path: '/home',
component: Home,
meta:{
title:'首页'
},
children: [{
path: '',
redirect: 'news'
},
{
path: 'news', //这里不需要加“/”
component: HomeNews
},
{
path: 'message', //这里不需要加“/”
component: HomeMessage
}
]
}, {
path: '/about',
component: About,
meta:{
title:'关于'
}
}, {
path: '/user/:userId',
component: User,
meta:{
title:'用户'
}
},{
path:'/profile',
meta:{
title:'档案'
},
component:Profile
}]
const router = new Router({
routes,
mode:'history', //默认url是有#,使用这个模式可以去掉#
})
//前置守卫(guard)
router.beforeEach((to,from,next) => {
//从from跳转到to
document.title = to.matched[0].meta.title
console.log('=====');
next()
})
//后置钩子
router.afterEach((to,form) => {
console.log('-----');
})
export default router
2、路由独享的守卫
可以直接在路由配置上定义 beforeEnter
守卫
const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: (to, from) => {
// reject the navigation
return false
},
},
]
3、路由独享的守卫
beforeRouteEnter
在进入当前组件对应的路由前调用。beforeRouteUpdate
在当前路由改变,但是该组件被复用时调用。beforeRouteLeave
在离开当前组件对应的路由前调用。
export default {
data() { ... },
beforeRouteEnter(to, from, next) {
... ...
}
}
beforeRouteEnter
不能获取组件实例this
,因为守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例this
。
4、完整的导航解析流程
- 1、导航被触发。
- 2、在失活的组件里调用
beforeRouteLeave
守卫。 - 3、调用全局的
beforeEach
守卫。 - 4、在重用的组件里调用
beforeRouteUpdate
守卫(2.2+)。 - 5、在路由配置里调用
beforeEnter
。 - 6、解析异步路由组件。
- 7、在被激活的组件里调用
beforeRouteEnter
。 - 8、调用全局的
beforeResolve
守卫(2.5+)。 - 9、导航被确认。
- 10、调用全局的
afterEach
钩子。 - 11、触发
DOM
更新。 - 12、调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
网友评论