Vue-router:10、路由守卫

2024-04-10 16:32

本文主要是介绍Vue-router:10、路由守卫,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Vue-router:10、路由守卫

Vue-router中的路由守卫,主要是对其内容进行保护,如果没有对应的权限,则不允许访问。

我们首先来看一下全局守卫,也就是所有的路由都会经过全局守卫来进行检测。

  //实现全局守卫router.beforeEach((to, from, next) => {//to:去哪个页面,from来自哪个页面,next继续执行.//判断哪个路由需要进行守卫,这里可以通过元数据方式if (to.meta.auth) {if (window.isLogin) {next();} else {next("/login?redirect=" + to.fullPath);}} else {next();}});

在上面的代码中,创建了路由守卫,但是需要判断的是需要对哪个路由进行守卫,这里就是通过元数据来进行判断的。如果所跳转到的路由有元数据,并且对应的auth属性为true表明是需要进行守卫的,那么下面就需要校验用户是否登录,这里是通过判断否window.isLogin的值是否为true来进行判断的(这里简化了操作,实际应用中应该存储到sessionStorage),如果条件成立则表明用户登录,就继续访问用户希望访问到的页面,否则跳转到登录页面,而且将用户希望访问的页面地址也传递到了登录页面,这样用户登录成功后,可以直接跳转到要访问的页面。

如果没有元数据,则继续访问用户要访问的页面。

 // 创建路由对象const router = new VueRouter({routes: [{ path: "/login", component: Login },{path: "/",component: App,redirect: "/users",children: [{path: "/users",component: Users,meta: {auth: true,},},{ path: "/userinfo/:id", component: UserInfo, props: true },{ path: "/rights", component: Rights },{ path: "/goods", component: Goods },{ path: "/orders", component: Orders },{ path: "/settings", component: Settings },],},],});

在上面的代码中,给/users路由添加了元数据。

登录组件创建如下:

  const Login = {data() {return {isLogin: window.isLogin,};},template: `<div><button @click="login" v-if="!isLogin">登录</button><button @click="logout" v-else>注销</button></div>`,methods: {login() {window.isLogin = true;this.$router.push(this.$route.query.redirect);},logout() {this.isLogin = window.isLogin = false;},},};

当单击登录按钮后,进行将window.isLogin设置为true, 并且进行跳转。

全部代码如下

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>基于vue-router的案例</title><script src="./lib/vue.js"></script><script src="https://unpkg.com/vue-router/dist/vue-router.js"></script><style type="text/css">html,body,#app {margin: 0;padding: 0px;height: 100%;}.header {height: 50px;background-color: #545c64;line-height: 50px;text-align: center;font-size: 24px;color: #fff;}.footer {height: 40px;line-height: 40px;background-color: #888;position: absolute;bottom: 0;width: 100%;text-align: center;color: #fff;}.main {display: flex;position: absolute;top: 50px;bottom: 40px;width: 100%;}.content {flex: 1;text-align: center;height: 100%;}.left {flex: 0 0 20%;background-color: #545c64;}.left a {color: white;text-decoration: none;}.right {margin: 5px;}.btns {width: 100%;height: 35px;line-height: 35px;background-color: #f5f5f5;text-align: left;padding-left: 10px;box-sizing: border-box;}button {height: 30px;background-color: #ecf5ff;border: 1px solid lightskyblue;font-size: 12px;padding: 0 20px;}.main-content {margin-top: 10px;}ul {margin: 0;padding: 0;list-style: none;}ul li {height: 45px;line-height: 45px;background-color: #a0a0a0;color: #fff;cursor: pointer;border-bottom: 1px solid #fff;}table {width: 100%;border-collapse: collapse;}td,th {border: 1px solid #eee;line-height: 35px;font-size: 12px;}th {background-color: #ddd;}</style></head><body><div id="app"><router-view></router-view></div><script>const App = {template: `<div><!-- 头部区域 --><header class="header">传智后台管理系统</header><!-- 中间主体区域 --><div class="main"><!-- 左侧菜单栏 --><div class="content left"><ul><li><router-link to="/users"> 用户管理</router-link></li><li><router-link to="/rights"> 权限管理</router-link></li><li><router-link to="/goods"> 商品管理</router-link></li><li><router-link to="/orders"> 订单管理</router-link></li><li><router-link to="/settings"> 系统设置</router-link></li></ul></div><!-- 右侧内容区域 --><div class="content right"><div class="main-content"> <router-view /></div></div></div><!-- 尾部区域 --><footer class="footer">版权信息</footer></div>`,};const Users = {data() {return {userlist: [{ id: 1, name: "张三", age: 10 },{ id: 2, name: "李四", age: 20 },{ id: 3, name: "王五", age: 30 },{ id: 4, name: "赵六", age: 40 },],};},methods: {goDetail(id) {console.log(id);this.$router.push("/userinfo/" + id);},},template: `<div><h3>用户管理区域</h3><table><thead><tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr></thead><tbody><tr v-for="item in userlist" :key="item.id"><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td><a href="javascript:;" @click="goDetail(item.id)">详情</a></td></tr></tbody></table></div>`,};//用户详情组件const UserInfo = {props: ["id"],template: `<div><h5>用户详情页 --- 用户Id为:{{id}}</h5><button @click="goback()">后退</button></div>`,methods: {goback() {// 实现后退功能this.$router.go(-1);},},};const Rights = {template: `<div><h3>权限管理区域</h3></div>`,};const Goods = {template: `<div><h3>商品管理区域</h3></div>`,};const Orders = {template: `<div><h3>订单管理区域</h3></div>`,};const Settings = {template: `<div><h3>系统设置区域</h3></div>`,};const Login = {data() {return {isLogin: window.isLogin,};},template: `<div><button @click="login" v-if="!isLogin">登录</button><button @click="logout" v-else>注销</button></div>`,methods: {login() {window.isLogin = true;this.$router.push(this.$route.query.redirect);},logout() {this.isLogin = window.isLogin = false;},},};// 创建路由对象const router = new VueRouter({routes: [{ path: "/login", component: Login },{path: "/",component: App,redirect: "/users",children: [{path: "/users",component: Users,meta: {auth: true,},},{ path: "/userinfo/:id", component: UserInfo, props: true },{ path: "/rights", component: Rights },{ path: "/goods", component: Goods },{ path: "/orders", component: Orders },{ path: "/settings", component: Settings },],},],});//实现全局守卫router.beforeEach((to, from, next) => {//to:去哪个页面,from来自哪个页面,next继续执行.//判断哪个路由需要进行守卫,这里可以通过元数据方式if (to.meta.auth) {if (window.isLogin) {next();} else {next("/login?redirect=" + to.fullPath);}} else {next();}});const vm = new Vue({el: "#app",router,});</script></body>
</html>

以上是全局守卫,对所有的路由都起作用。

但是,如果项目比较简单,路由规则定义的比较少,可以将守卫定位到某个路由规则内。这就是路由独享守卫

  // 创建路由对象const router = new VueRouter({routes: [{ path: "/login", component: Login },{path: "/",component: App,redirect: "/users",children: [{path: "/users",component: Users,meta: {auth: true,},beforeEnter(to, from, next) {if (window.isLogin) {next();} else {next("/login?redirect=" + to.fullPath);}},},{ path: "/userinfo/:id", component: UserInfo, props: true },{ path: "/rights", component: Rights },{ path: "/goods", component: Goods },{ path: "/orders", component: Orders },{ path: "/settings", component: Settings },],},],});

在上面的代码中,给/users这个路由守卫,注意这里的方法名为beforeEnter.同时,这里将守卫定义在/users路由规则内,所以不需要对元数据进行判断,只需要判断用户是否登录就可以了。(注意:在进行以上测试时,需要将全局守卫的代码注释掉)

组件内守卫

可以在路由组件内直接定义以下路由导航守卫。

beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

将如下的代码直接添加到组件内。

 const Users = {data() {return {userlist: [{ id: 1, name: "张三", age: 10 },{ id: 2, name: "李四", age: 20 },{ id: 3, name: "王五", age: 30 },{ id: 4, name: "赵六", age: 40 },],};},methods: {goDetail(id) {console.log(id);this.$router.push("/userinfo/" + id);},},template: `<div><h3>用户管理区域</h3><table><thead><tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr></thead><tbody><tr v-for="item in userlist" :key="item.id"><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td><a href="javascript:;" @click="goDetail(item.id)">详情</a></td></tr></tbody></table></div>`,beforeRouteEnter(to, from, next) {if (window.isLogin) {next();} else {next("/login?redirect=" + to.fullPath);}},};

在上面的代码中,直接将路由守卫对应的方法添加到了组件中。

注意:在测试之前将路由规则中定义的路由守卫的代码注释掉。

这篇关于Vue-router:10、路由守卫的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/891574

相关文章

vue, 左右布局宽,可拖动改变

1:建立一个draggableMixin.js  混入的方式使用 2:代码如下draggableMixin.js  export default {data() {return {leftWidth: 330,isDragging: false,startX: 0,startWidth: 0,};},methods: {startDragging(e) {this.isDragging = tr

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

js+css二级导航

效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

vue+el国际化-东抄西鉴组合拳

vue-i18n 国际化参考 https://blog.csdn.net/zuorishu/article/details/81708585 说得比较详细。 另外做点补充,比如这里cn下的可以以项目模块加公共模块来细分。 import zhLocale from 'element-ui/lib/locale/lang/zh-CN' //引入element语言包const cn = {mess

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementUI下拉框联动显示

<el-row><el-col :span="12"><el-form-item label="主账号:" prop="partyAccountId" :rules="[ { required: true, message: '主账号不能为空'}]"><el-select v-model="detailForm.partyAccountId" filterable placeholder="

vue+elementui分页输入框回车与页面中@keyup.enter事件冲突解决

解决这个问题的思路只要判断事件源是哪个就好。el分页的回车触发事件是在按下时,抬起并不会再触发。而keyup.enter事件是在抬起时触发。 so,找不到分页的回车事件那就拿keyup.enter事件搞事情。只要判断这个抬起事件的$event中的锚点样式判断不等于分页特有的样式就可以了 @keyup.enter="allKeyup($event)" //页面上的//js中allKeyup(e

vue子路由回退后刷新页面方式

最近碰到一个小问题,页面中含有 <transition name="router-slid" mode="out-in"><router-view></router-view></transition> 作为子页面加载显示的地方。但是一般正常子路由通过 this.$router.go(-1) 返回到上一层原先的页面中。通过路由历史返回方式原本父页面想更新数据在created 跟mounted