1. 全局导航守卫
语法:
# 守卫参数
+ to: Route: 即将要进入的目标 路由对象
+ from: Route: 当前导航正要离开的路由
+ next: Function: 一定要调用该next方法,否则路由不向下执行,页面空白。# 全局前置守卫,当一个导航触发时,立刻触发前置守卫,
router.beforeEach((to, from, next) => {
// ...
next()
})//全局解析守卫,等到路由独享守卫和组件内守卫都解析完毕后执行
router.beforeResolve((to, from, next) => {
// ...
next()
})# 全局后置钩子,全部守卫执行完毕后执行
// 此钩子不会接受 next 函数也不会改变导航本身
router.afterEach((to, from) => {
// ...
})
全局导航守卫执行顺序:
news.js(这个文件是从 index.js 文件中抽取拆分出来的,最终要被引入到 insex.js 文件中):
import News from '@/views/News' import Detail from '@/views/Detail' import Login from '@/views/Login' const routes = [ { path: '/news', component: News, }, { path: '/news/:id', name: 'xw', component: Detail, }, { // 这是登录页 path: '/login', component: Login, } ] export default routes
index.js:
import Vue from 'vue' import VueRouter from 'vue-router' import news from './routes/news' // 以插件的方式添加 Vue.use(VueRouter) // 实例化路由对象及配置路由表 const routes = [...news] const router = new VueRouter({ // 路由模式 mode: 'history', // 路由规则表 routes }) // 全局守卫 每次切换页面都会执行到 // 前置 router.beforeEach((to, from, next) => { console.log('全局 --- beforeEach') next() }) // 解析 router.beforeResolve((to, from, next) => { console.log('全局 --- beforeResolve') next() }) // 后置 router.afterEach((to, from) => { console.log('全局 --- afterEach') }) export default router
登录页(index.vue):
<template> <div> <button>登录用户</button> </div> </template> <script> export default { } </script> <style lang="scss" scoped></style>
现在我们有这样一个需求,用户只有在登录成功之后,才能访问新闻页面,该怎么做呢?
index.js:
import Vue from 'vue' import VueRouter from 'vue-router' import news from './routes/news' // 以插件的方式添加 Vue.use(VueRouter) // 实例化路由对象及配置路由表 const routes = [...news] const router = new VueRouter({ // 路由模式 mode: 'history', // 路由规则表 routes }) // 用全局前置守卫判断用户是否登录 router.beforeEach((to, from, next) => { // 在使用导航守卫来验证用户是否登录,一定要把登录页面路由排除掉,防止死循环 // 如果没有在本地存储中获取到token值,并且即将跳转的页面不是登录页 if (!sessionStorage.getItem('token') && to.path != '/login') { // 到登录页面 // next('/login') // replace: true表示跳转到登录页面后,不允许回退 next({ path: '/login', replace: true }) } else { next() } }) export default router
2. 路由独享守卫
语法:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... next() } } ] })
使用:
news.js(这个文件是从 index.js 文件中抽取拆分出来的,最终要被引入到 insex.js 文件中):
import News from '@/views/News' import Detail from '@/views/Detail' import Login from '@/views/Login' const routes = [ { path: '/news', component: News, }, { path: '/news/:id', name: 'xw', component: Detail, }, { // 这是登录页 path: '/login', component: Login, // 路由独享守卫 // 只有当前的路由规则才生效,比如登录页面的路由独享守卫在进入新闻页面时就不会生效 // 路由独享守卫在每次进入到当前路由页面时都会执行 beforeEnter: (to, from, next) => { console.log('路由独享守卫 ==login -- --- beforeEnter') next() } } ] export default routes
3. 组件内守卫
语法:
你可以在路由组件内直接定义以下路由导航守卫:
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` } }
所有守卫和生命周期函数的执行顺序:
news.js(这个文件是从 index.js 文件中抽取拆分出来的,最终要被引入到 insex.js 文件中):
import News from '@/views/News' import Detail from '@/views/Detail' import Login from '@/views/Login' const routes = [ { path: '/news', component: News, }, { path: '/news/:id', name: 'xw', component: Detail, beforeEnter: (to, from, next) => { console.log('路由独享守卫 -- detail --- beforeEnter') next() } }, { // 这是登录页 path: '/login', component: Login, // 路由独享守卫 // 只有当前的路由规则才生效,比如登录页面的路由独享守卫在进入新闻页面时就不会生效 // 路由独享守卫在每次进入到当前路由页面时都会执行 beforeEnter: (to, from, next) => { console.log('路由独享守卫 ==login -- --- beforeEnter') next() }, } ] export default routes
详情页(index.vue):
<template> <div> <h3>新闻详情页</h3> </div> </template> <script> export default { // 当路由访问到此组件时,执行此钩子函数 beforeRouteEnter(to, from, next) { console.log("组件 --- beforeRouteEnter"); next(); }, // 离开当前路由组件 beforeRouteLeave(to, from, next) { console.log("组件 --- beforeRouteLeave"); next(); }, // 路由参数的改变,触发路由组件守卫 beforeRouteUpdate(to, from, next) { console.log(this); console.log("组件 --- beforeRouteUpdate"); next(); }, // 和生命周期函数比较以下执行顺序 // 所有路由解析完毕以后,才开始执行生命周期函数 beforeCreate() { console.log('组件 === beforeCreate') }, beforeDestroy() { console.log('组件 === beforeDestroy') }, destroyed() { console.log('组件 === destroyed') }, }; </script> <style lang="scss" scoped></style>
下面我们来看beforeRouteUpdate
函数什么时候执行。
详情页(index.vue):
<template> <div> <h3>新闻详情页</h3> <router-link to="/news/1">111</router-link><br /> <router-link to="/news/2">222</router-link><br /> <router-link to="/news/3">333</router-link> </div> </template> <script> export default { // 当路由访问到此组件时,执行此钩子函数 beforeRouteEnter(to, from, next) { console.log("组件 --- beforeRouteEnter"); next(); }, // 离开当前路由组件 beforeRouteLeave(to, from, next) { console.log("组件 --- beforeRouteLeave"); next(); }; // 路由参数的改变,触发路由组件守卫 // 可以用来监听页面是否发生变化 beforeRouteUpdate(to, from, next) { // console.log(this); console.log("组件 --- beforeRouteUpdate"); next(); }, // 监听器也可以用来监听页面是否发生变化 // watch:{ // '$route'(n){ // console.log('watch --- ' ,n); // } // }, // 和生命周期函数比较以下执行顺序 // 所有路由解析完毕以后,才开始执行生命周期函数 beforeCreate() { console.log('组件 === beforeCreate') }, beforeDestroy() { console.log('组件 === beforeDestroy') }, destroyed() { console.log('组件 === destroyed') }, }; </script> <style lang="scss" scoped></style>
到此这篇关于Vue守卫零基础介绍的文章就介绍到这了,更多相关Vue守卫内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!