1. 修改标题需求
1.1 需求
需求: 在SPA应用中,如何改变网页的标题
分析:
- 网页的标题是通过
title
标签来显示的, - 但是在SPA应用中只有一个固定HTML,因此切换组件,标题不会改变
- 可以通过JavaScript 来修改
title
标签的内容, 通过window.document.title
修改
1.2 解决方案
思路:
- 先前讲过生命周期,在进行路由跳转时,会进行组件显示的切换
- 每一个组件都会经历组件自己的生命周期
- 离开的组件组件会被销毁,
- 进入当前路由的组件,会经历组件的创建与挂在
- 因此我们可以了利用生命周期的钩子函数配合
document
修改title
值
示例代码:
Home组件
<script>
export default {
name:"Home",
created(){
document.title = "首页"
}
}
</script>
解决方法分析:
- 这样就需要我们在每一个页面组件都需要手动修改
title
内容 - 如果页面组件过多,在开发和后期维护上都是一个麻烦
思考:
- 就像咱们
axios
拦截功能一样,我们也需要一个拦截 - 这个拦截可以知道我们路由跳转是从哪个组件跳转到哪一个组件
- 这样我们就可以通过你将要去哪个路由,让
title
显示哪个路由中对于的标题信息
这就是我们将要学习的全局导航守卫.
2. 全局导航守卫
2.1 什么是导航守卫
导航守卫说的通俗一点,就在在路由跳转在中间添加的一层拦截,
说明:
-
vue-router
提供的导航的导航守卫主要用来监听路由的进入和离开 -
vue-router
提供了beforeEach
和afterEach
钩子函数,会在路由跳转前和跳转后触发
2.2 导航守卫的钩子函数
vue-router
提供了两个全局导航守卫
-
beforeEach
全局守卫, 也叫作前置守卫 -
afterEach
全局守卫, 也叫后置守卫,
导航守卫钩子函数的参数是一个回调函数,
2.2.1 beforeEach
全局守卫
beforeEach
全局守卫的回调函数接受三个参数,为to
,from
,next
三个参数说明:
-
to
跳转进入的目标路由对象 -
form
当前准备离开的路由对象 -
next
调用该方法后,进入下一个钩子, 作用类似于express
或者koa
中中间件里调用的next
next
函数使用说明
- 如果
next
函数正常调用next()
表示正常进入跳转路由,导航状态为确认 - 如果
next
函数在调用是传入false
,如next(false)
, 表示终端导航跳转 -
next
函数还可以传参,表示跳转到指令路由next("/")
,或next({path:"/"})
参数的路由,
等着咱们看示例使用
2.2.2 afterEach`全局守卫
afterEach
全局守卫的回调函数接受二个参数,为to
,from
两个个参数说明:
-
to
跳转进入的目标路由对象 -
form
当前准备离开的路由对象
为什么afterEach
没有next
参数呢,因为在afterEach
被调用时, 路由已经跳转完毕,
2.3 使用全局守卫修改标题
2.3.1 使用全局守卫说明
使用全局守卫修改标题说明:
- 因为全局导航守卫回调函数参数
to
,form
表示的是路由对象, - 因此如过想在路由对象中获取
title
值,就必须现在路由映射中定义title
值 - 将
title
定义在meta
元数据对象中, 元数据修饰数据的数据 - 在跳转路由是通过跳转路由获取
title
值,然后修改页面标题
2.3.2 修改路由
修改路由,添加title
数据
{
path:'/home',
component: Home,
meta:{title:"首页"}, // 元数据中添加title信息
},
2.3.3 在全局守卫中修改标题
// 使用全局导航守卫
router.beforeEach((to,from,next) => {
// to 就是将要去的路由, 就是$route 对象
// from 是离开的路由, 就是之前显示路由 也是$route 对象
// console.log(to);
// console.log(from);
document.title = to.matched[0].meta.title
next()
})
3. 路由独享守卫
3.1 路由独享守卫说明:
- 使用的钩子函数与全局导航守卫一致,为
beforeEnter
- 不同的是:路由独享守卫是定义在路由记录中,全局导航守卫是定义在入口文件中
- 路由独享守卫只在当前路由进入时有效,全局导航守卫是所有路由跳转都会被拦截
3.2 例如:
现在只想拦截进入/离开/article
路由,就可以给/article
路由使用路由独享守卫
{
path:'/article',
component: Article,
meta:{title:"文章"},
beforeEnter(to,from,next){
// 当路由跳转到/article是触发路由独享守卫
console.log(to);
console.log(from);
console.log(next);
next()
},
},
4. 组件内的路由守卫
除了在全局和确定的路由中定义路由导航守卫,还可以在组件中定义路由导航守卫
4.1 组件内的路由守卫说明
- 组件内的守卫是定义在组件内部,组件选项对象中的路由守卫
- 组件内路由守卫有三个,为:
beforeRouteEnter
,beforeRouteUpdate
,beforeRouteLeave
-
beforeRouteEnter
组件创建前调用,不能使用组件实例this
-
beforeRouteUpdate
路由被改变,但是组件被复用时调用,比如动态路由 -
beforeRouteLeave
导航离开该组件时调用
4.2 例如
在文章组件中使用组件内的路由守卫
<script>
export default {
name:"Article",
beforeRouteEnter(to,from,next){
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
next()
},
beforeRouteUpdate(to,from,next){
// 在当前路由改变,但是该组件被复用时调用
// 带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Article 组件,
// 因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
next()
},
beforeRouteLeave(to,from,next){
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
next()
}
}
</script>
4.3 关于组件内路由守卫的next参数
说明:
-
next
是一个函数, - 因为在
beforeRouteEnter
路由守卫中不能通过this
访问组件实例 - 因此在
beforeRouteEnter
守卫中next
可以接受一个回调函数,回调函数的形参就是组件实例 -
beforeRouteUpdate
和beforeRouteLeave
中能通过this
获取组件实例,固不支持回调函数