Vue全局前置守卫路由代码分析
Admin 2023-04-01 群英技术资讯 607 次浏览
“导航” 表示路由正在发生改变
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。
v-router官网:https://router.vuejs.org/zh/guide/
我这里用到的是全局前置守卫:
在路由中可以使用router.beforeEach,注册一个全局前置守卫
const router = new VueRouter({ routes }); router.beforeEach((to, from, next) => { const isover = to.matched.some(record => record.path == '/over') if (isover || to.path == '/overview') { if (!store.getters.token) { // 未登录 next('/login'); return } if (!isHome) { next(); return } } else { next() // 无需登录验证 } })
当一个导航触发时,全局前置守卫按照创建顺序调用,守卫是异步解析执行,此时导航在所有守卫resolve完之前一直处于等待中。
每个守卫方法接收3个参数
to: Route:即将要进入的目标 路由对象
from: Route :当前导航正要离开的路由
next: Function : 一定要调用该方法来resolve这个钩子,执行效果依赖next方法的调用参数
1.next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
2.next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
3.next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
4.** 确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错 **这里有一个在用户未能验证身份时重定向到 /login 的示例:
// BAD router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) // 如果用户未能验证身份,则 `next` 会被调用两次 next() })
// GOOD router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) else next() })
对于路由的导航动态实现,我们首先要确定我们拥有的路由有哪些,并且对于命名有一定的良好习惯。其中最重要的就是在我们的路由里面进行设定,设置我们的路由守卫,能对路由进行控制和及时的更新我们的路由数据,然后就可以直接在功能实现区域进行调用实现了。
1.router文件夹
在router里面引入我们的store
路由守卫
// 路由守卫 router.beforeEach((to, from, next) => { localStorage.setItem("currentPathName", to.name) // 设置当前的路由名称,为了在Header组件中去使用 store.commit("setPath") // 触发store的数据更新 next() // 放行路由 })
2.store文件夹
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { currentPathName: '' }, mutations: { setPath (state) { state.currentPathName = localStorage.getItem("currentPathName") } } }) export default store
3.main.js
import Vue from 'vue' import App from './App.vue' import router from './router' import store from "@/store"; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import request from "@/utils/request"; import './assets/css/global.css' // import * as echarts from 'echarts' Vue.config.productionTip = false Vue.use(ElementUI,{size: "mini"}); Vue.prototype.request = request; new Vue({ router, store, render: h => h(App) }).$mount('#app')
4.实现
<template> <div style="display: flex; line-height: 35px; background-color: whitesmoke"> <div style="flex: 1"> <span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px"></span> <el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px"> <img src="../assets/images/宿舍管理.png" alt="" style="width: 30px; position: relative; top: 20px; right: 5px"> <h3 style="margin-left: 30px; color: lightskyblue">宿舍后台管理</h3> <el-breadcrumb-item :to="'/'" style="margin-left: 200px; margin-top: -10px">首页</el-breadcrumb-item> <el-breadcrumb-item style="margin-top: -10px;">{{ currentPathName }}</el-breadcrumb-item> </el-breadcrumb> </div> <el-dropdown style="width: 130px; cursor: pointer"> <div style="display: inline-block; float: right; margin-right: 10px"> <img :src="user.avatarUrl" alt="" style="width: 30px; border-radius: 50%; position: relative; top: 10px; right: 5px"> <span>{{user.nickname}}</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i> </div> <el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center"> <el-dropdown-item style="font-size: 14px; padding: 5px 0"> <span style="text-decoration: none" @click="person">个人信息</span> </el-dropdown-item> <el-dropdown-item style="font-size: 14px; padding: 5px 0"> <span style="text-decoration: none" @click="logout">退出登录</span> </el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </template> <script> export default { name: "Header", props: { collapseBtnClass: String, user: Object }, computed: { currentPathName () { return this.$store.state.currentPathName; //需要监听的数据 } }, data() { return { user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {} } }, methods: { logout() { this.$router.push("/login") this.$message.success("退出成功") }, person(){ this.$router.push("/mall/person") } } } </script> <style scoped> </style>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
目录写在前面javscript 中函数和对象的关系面向对象编程(OOP)继承多态封装函数编程编程(FP)闭包和高阶函数柯里化偏函数组合和管道函子写在最后写在前面浏览下文我觉得还是要有些基础的!下文涉及的知识点太多,基本上每一个拿出来都能写几篇文章,我在写文章的过程中只是做了简单的实现,我只是提供了一个思路,更多的细节还
这篇文章主要介绍了vue的provide和inject使用方法及其原理,本文通过源码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
今天给大家分享的是用JavaScript实现滑块验证功能,在实际的项目中,常常会遇到验证功能的需求,因此分享给大家做个参考。下文JavaScript实现登录的滑块验证代码,感兴趣的朋友可以参考,接下来我们一起来详细看看吧。
这篇文章给大家分享的是React实现文件转base64的方法。小编觉得挺实用的,因此分享给大家做个参考,文中的示例代码介绍得很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。
这篇文章主要为大家介绍了Vue2 中的数据劫持简写示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008