欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > vue3:九、路由守卫

vue3:九、路由守卫

2025/3/19 6:41:30 来源:https://blog.csdn.net/weixin_46001736/article/details/146318901  浏览:    关键词:vue3:九、路由守卫

官网参考:导航守卫 | Vue Router

一、Vue 路由守卫的作用

​1、权限控制

检查用户是否已登录,如果未登录则重定向到登录页面。

根据用户角色限制访问某些路由。

​2、数据预加载

在进入路由前加载必要的数据,确保页面渲染时有完整的数据。

3、​导航拦截

在某些条件下阻止用户离开当前页面(例如表单未保存时)。

​4、日志记录

记录用户访问的路由,用于分析或调试。

​5、动态路由

根据条件动态添加或修改路由。

二、根据路由守卫更改页面的名称

1、引入基本语法

首先输出一下to和from参数

//设置路由守卫
router.beforeEach((to, from, next) => {console.log('to', to)console.log('from', from)next()
})

可查看到一个参数meta.title,其可对标题名称进行修改

2、设置系统总标题

直接设置一个变量即可

//设置系统标题
const SystemTitle = 'SMS后台管理系统';

3、设置路径的标题

在之前设置的项中,设置meta下title的名称

只用设置外层页面的标题,主要的含导航内容的页面暂不修改

4、修改页面标题

修改页面的标题的方法为document.title

//设置系统标题
const SystemTitle = 'SMS后台管理系统';
//设置路由守卫
router.beforeEach((to, from, next) => {if(to.meta.title){document.title = to.meta.title + '-' + SystemTitle}next()
})

5、测试效果

三、权限控制

主要针对需要登录的页面,

  • 没有token
    • 在需要登录的页面-跳转登录页面
    • 不需要登录的页面-放行(可以继续执行)
  • 有token
    • 如果在登录页面-跳转到主页面
    • 如果没在登录页面-pinia读取用户信息

1、基本信息设置

首先获取token,查看token是否存在,如果不存在需要跳转到登录页面

①引入token获取

import { getToken } from '@/utils/token';

②获取token

const token = getToken();

③设置无需登录的页面

取name名称,因为404页面的path是一个变化量(path: '/:pathMatch(.*)*',),不能确定

//设置一个不需要进行登录的页面数组
const NoLogin = [ 'login','not-found','test']

2、token不存在情况

①无需登录的页面

无需登录的页面,是可以不需要token的,那么就可以直接放行

//在NoLogin数组中,表示不需要登录,就直接放行
if (NoLogin.includes(to.name)) {next()
}

②需要登录的页面

需要登录的页面,但没有token表示登录状态可能过期等情况,需要重新条会登录页面进行登录

//如果不在NoLogin数组中,就表示需要登录,没有token就跳转到登录页面
else{next({ name: 'login' })
}

3、token存在情况

①在登录login页面

需要进行,在登录页面,且存在token,表示可以直接跳转到主页面

//如果在登录页面,就跳转到首页
if(to.name == 'login'){next({ name: 'main' })
}

②在其他页面

需要通过pinia获取用户信息

Ⅰ简单介绍

Pinia 是 Vue.js 的官方推荐状态管理库。使用 Pinia 的主要目的是为了更简单、更灵活地管理应用程序的状态

Ⅱ参考pinia

 pinia参考:定义一个 Store | Pinia

初始创建vue项目的时候,选择pinia的会有相关数据,如果没有选择pinia可进入官网参考进行安装

安装参考:vue3:pinia安装-CSDN博客

Ⅲ使用pinia获取用户状态信息
建立user.js

在src/stores建立user.js的项目,如果是初始vue项目的话,会自动生成counter.js如下

修改代码

复制counter.js的代码到src/stores/user.js,没有就码字

先清除不要的代码

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', () => {return { count, doubleCount, increment }
})

修改名称

根据之前给的例子,可以进行用户信息的获取,设值

路由引用

在路由中的相关位置使用pinia进行数据获取/设置

路径:src/router/index.js

引入方法

import { userStore } from '@/stores/user'

获取用户信息,如果存在账号信息,就放行(有token,有账号信息,可放行)

//读取用户信息
const userstore = userStore();
if (userstore.username) {//放行next();
}

没有用户信息,但存在token,需要对用户信息进行查询

  • 成功获取用户信息:需要更新store的用户信息,并且更新新的token 
  • 没获取用户信息:删除token,并回到登录页面,需重新登录

apifox建立查询用户信息的接口

新建接口

注意:使用的是get

新建期望

返回用户的基本信息

api封装

 在src/api/user.js中写入获取用户信息的get方法

接口方法引入

 

逻辑端执行没有用户信息,存在token功能

else {//如果token存在,用户信息没查询到就去请求用户信息var res = await getuserinfo();//请求之后,如果请求成功,就设置token,设置用户信息,放行,如果请求失败,就删除token,跳转到登录页面if(res.code == 1){//设置token和用户信息setToken(res.token);//将用户信息设置到store中userstore.setUserinfo(res.data)//放行next();}else{//删除tokendelToken();//跳转到登录页面next({ name: 'login' })}
}

 注意:

defineStore的第一个参数是唯一id,如果定义别的store,此参数不能重复

 4、测试效果

①测试token不存在,看是否跳转到登录页面

首先在主页页面,可以查看到基本token信息

右击删除token

再刷新此页面 ,成功跳回login页面

 ②测试token存在,再登录页面是否会直接进入主页面

在主页面,存在token信息

将路径改为login

页面再次回到主页面

四、完整代码

1、pinia获取/设置用户信息

src/stores/user.js


import { computed, reactive } from 'vue'
import { defineStore } from 'pinia'export const userStore = defineStore('userinfo', () => {//声明用户信息const userinfo = reactive({});//对象//获取用户名等。由于用户名是通过用户信息获取的,所以需要一个计算属性const username = computed(() => userinfo.name);//设值用户信息const setUserinfo = (info) => {//对象使用assign,如果userInfo中有相同的key,则info覆盖userInfo的key信息,把之前有的信息进行更换)Object.assign(userinfo, info)}return { userinfo, username ,setUserinfo}
})

2、获取用户信息

src/api/user.js

import { post , get } from '@/utils/request';// 登录
export function login(data) {return post('/user/login', data); 
}
//重置密码-通过手机号
export function repwd(data) {return post('/user/repassword', data); 
}
//获取用户信息
export function getuserinfo() {return get('/user/getuserinfo'); 
}

3、路由信息

src/router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import { getToken, setToken, delToken } from '@/utils/token';
import { userStore } from '@/stores/user'
import { getuserinfo } from '@/api/user';
// 引入路由
const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [//将子项全部存入一个大的路由中layout/index.vue,页面刚进入时调用的时layout/index.vue,在为导航条,默认显示页面/home的内容{path: '/',name: 'main',component: () => import('@/layout/index.vue'),redirect: '/home',children: [{path: '/home',name: 'home',component: HomeView},{path: '/about',name: 'about',component: () => import('../views/AboutView.vue')},]},//登录{path: '/login',name: 'login',component: () => import('@/views/LoginView.vue'),meta: {title: '登录'}},//测试页面{path: '/test',name: 'test',component: () => import('@/views/TestView.vue'),meta: {title: '测试页面'}},//404{path: '/:pathMatch(.*)*',name: 'not-found',component: () => import('@/views/NotFoundView.vue'),meta: {title: '页面未找到'}},],
})//设置系统标题
const SystemTitle = 'SMS后台管理系统';
//设置一个不需要进行登录的页面数组
const NoLogin = ['login', 'not-found', 'test']
//设置路由守卫
router.beforeEach(async(to, from, next) => {if (to.meta.title) {//拼接新标题var newtitle = to.meta.title + '-' + SystemTitledocument.title = newtitle}// 判断是否登录const token = getToken();//如果token不存在if (!token) {//在NoLogin数组中,表示不需要登录,就直接放行if (NoLogin.includes(to.name)) {next()}//如果不在NoLogin数组中,就表示需要登录,没有token就跳转到登录页面else {next({ name: 'login' })}}//token存在else {//如果在登录页面,就跳转到首页if (to.name == 'login') {next({ name: 'main' })}else {//读取用户信息const userstore = userStore();console.log(userstore)if (userstore.username) {//放行next();}else {//如果token存在,用户信息没查询到就去请求用户信息var res = await getuserinfo();console.log(res);//请求之后,如果请求成功,就设置token,设置用户信息,放行,如果请求失败,就删除token,跳转到登录页面if(res.code == 1){//设置token和用户信息setToken(res.data.token);//将用户信息设置到store中userstore.setUserinfo(res.data)//放行next();}else{//删除tokendelToken();//跳转到登录页面next({ name: 'login' })}}}}
})export default router

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词