导航守卫
- 我们来考虑一个需求: 在一个SPA应用中, 如何改变网页的标题呢?
- 网页标题是通过
<title>来显示的, 但是SPA只有一个固定的HTML, 切换不同的页面时, 标题并不会改变. - 但是我们可以通过JavaScript来修改
<title>的内容.window.document.title = '新的标题'. - 那么在Vue项目中, 在哪里修改? 什么时候修改比较合适呢?
- 网页标题是通过
- 普通的修改方式:
- 我们比较容易想到的修改标题的位置是每一个路由对应的组件.vue文件中.
- 通过mounted声明周期函数, 执行对应的代码进行修改即可.
- 但是当页面比较多时, 这种方式不容易维护(因为需要在多个页面执行类似的代码).
- 有没有更好的办法呢? 使用导航守卫即可.
- 什么是导航守卫?
- vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.
- vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发
导航守卫使用
- 我们可以利用
beforeEach来完成标题的修改 - 首先, 我们可以在钩子当中定义一些标题, 可以利用meta来定义
- 其次, 利用导航守卫,修改我们的标题
- 导航钩子的三个参数解析:
- to: 即将要进入的目标的路由对象.
- from: 当前导航即将要离开的路由对象.
- next: 调用该方法后, 才能进入下一个钩子
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
//前置钩子(hook)
router.beforeEach(function (to,from,next){
//从from到to的路由跳转
document.title = to.meta.title
})
index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from "../components/Home";
import About from "../components/About";
import User from "../components/User";
import News from "../components/homenews"
import Message from "../components/homemessage"
import Profile from "../components/profile"
Vue.use(Router)
const routes = [
{
path:"/",
redirect:"/home"
},
// 非懒加载的路由
{
path:"/home",
component:Home,
meta:{
title:"首页"
},
children:[
{
path:'',
redirect:"news"
},
{
path:"news",
component:News
},
{
path:"message",
component:Message
}
]
}
,
{
path:"/about",
component:About,
meta:{
title:"关于"
}
}
,
{
path:"/user/:userId",
component:User,
meta:{
title:"用户"
}
},
{
path:"/profile/:id",
component:Profile,
meta:{
title:"我的"
}
}
]
const router = new Router({
routes,
mode:"history",
linkActiveClass:"active"
})
export default router
我们在使用to.mate.title的时候会出现一个问题
-
当我们切换首页的时候,要么无显示,要么显示undefined,其他三个显示的正常
-
问题所在:
- 我们使用的是嵌套路由,这样我们/home/news 而我们将meta属性放在了/home上,所以匹配不上,meta中没有数据,出现错误
-
解决方法:
router.beforeEach(function (to,from,next){ //从from到to的路由跳转 document.title = to.matched[0].meta.title console.log(to); next() }) -
效果展示
导航守卫补充
-
补充一:如果是后置钩子, 也就是afterEach, 不需要主动调用next()函数
router.beforeEach(function (to,from,next){ //从from到to的路由跳转 document.title = to.matched[0].meta.title console.log(to); next() }) router.afterEach((to,from)=>{ console.log("------"); }) -
补充二: 上面我们使用的导航守卫, 被称之为全局守卫
-
路由独享的守卫
-
组件内的守卫
-
-
更多内容, 可以查看官网进行学习: