[Vue]解决某一用户登录后通过当前页面修改链接可访问其他角色的页面

1. 前情

本人Vue菜鸟选手
在本人进行Vue项目时,某天睡醒正坐,突然想到自己的前端项目虽然进行了拦截,但仅限于不同页面的情况下,同页面情况下由于认证解决问题,必定可以在用户A登录后通过管理员相关链接直接访问进入管理员页面进行操作。

于是乎在多方查找解决方法,但不知道为何找不到相关的文章,终于翻了很多篇文章推荐后找到了下面的文章,并进行操作,成功解决了问题。

【vue】通过路由拦截无权限访问的权限页面

本文章主要用以个人记录以及分享,且帮助避开上文中存在几次问题。
使用的结构分层与参考链接有些区别,写的有些粗糙,但解决了我的问题,希望大佬轻喷。

2. 我的写法

  • 文档结构如下
  • router- index.js
import Vue from 'vue'
import VueRouter from 'vue-router'

//举例几个管理员页面
import Administration from '../components/administration.vue'
import QueryCargo from '../components/administration_children/queryCargo.vue'
import Welcome from '../components/administration_children/welcome.vue'

//举例几个用户页面
import User from '../components/visit/user.vue'
import UserWelcome from '../components/visit/userWelcome.vue'
import QueryCargoFD from '../components/visit/queryCargoForV.vue'

Vue.use(VueRouter)

const routes = [
	
	{
		path: '/administration',
		component: Administration,
		//输入administration自动映射到welcome页面
		redirect: '/welcome',
		//设置为子路由
		children: [
			{
				path: '/welcome',
				component: Welcome,
				meta: {
					// 元数据 requireAuth来做是否需要拦截的判断
					requireAuth: true
				}
			},
			{
				path: '/queryCargo',
				component: QueryCargo,
				meta: {
					// 元数据 requireAuth来做是否需要拦截的判断
					requireAuth: true
				}
			},
		],
	},
	{
		path: '/user',
		component: User,
		redirect: '/userWelcome',
		children: [
			{
				path: '/userWelcome',
				component: UserWelcome,
				meta: {
					// 元数据 requireAuth来做是否需要拦截的判断
					requireAuth: true
				}
			},
			{
				path: '/queryCargofd',
				component: QueryCargoFD,
				meta: {
					// 元数据 requireAuth来做是否需要拦截的判断
					requireAuth: true
				}
			},
		],
	}
]


const router = new VueRouter({
	routes
})

export default router

  • store- index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        //用到了 sessionStorage,使用sessionStorage ,
        //关掉浏览器的时候会被清除掉,和 localStorage 相比,
        //比较利于保证实时性。
        //我个人使用自己传入sessionStorage中的user的内容来区分用户和管理员
        token: sessionStorage.getItem("token"),
        user: JSON.parse(sessionStorage.getItem("user")),
        //
        //允许访问的页面
         menuListStatus: [],
         //
         menuListAd: [],
        //
    },
    mutations: {
        
        //(用户可以访问的页面)
        saveMenuListStatus (state,data) {
			state.menuListStatus = data;
		},
		saveMenuListAd (state,data) {
			state.menuListAd= data;
		},
       
        // set
        SET_TOKENN: (state, token) => {
            state.token = token
            sessionStorage.setItem("token", token)
        },
        SET_USER: (state, user) => {
            state.user = user
            sessionStorage.setItem("user", JSON.stringify(user))
        },
        REMOVE_INFO : (state) => {
            state.token = ''
            state.user = {}
            sessionStorage.setItem("token", '')
            sessionStorage.setItem("user", JSON.stringify(''))
        }
    },
    getters: {

    },
    actions: {
    },
    modules: {
    }
})
  • main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from '@/store'
import './plugins/element.js'
//导入全局样式表
import './assets/css/global.css'

import { Message } from "element-ui"

import axios from 'axios'
import _ from 'lodash'


Vue.config.productionTip = false

//配置请求的根路径
//设置反向代理,前端请求默认发送到http://127.0.0.1:8081
axios.defaults.baseURL = 'http://127.0.0.1:8081';

var menuList = [
  {
    id: 1,
    title: '/user'
  },
  {
    id: 2,
    title: '/userWelcome'
  },
  {
    id: 3,
    title: '/queryCargofd'
  },
]

var menuListad = [
  {
    id: 1,
    title: '/administration'
  },
  {
    id: 2,
    title: '/welcome'
  },
  {
    id: 3,
    title: '/queryCargo'
  },
]
// 把拿到的菜单存储在vuex中
store.commit('saveMenuListStatus', menuList);
store.commit('saveMenuListAd', menuListad);

//禁止用户跳管理员及管理员跳用户
//to为去向那个页面,from为从哪个页面来,next为放行
router.beforeEach((to, from, next) => {
	//判断是否需要拦截
	if (to.meta.requireAuth) {
		//进行登陆拦截判断,只有先登录才可以访问,登录后添加token至sessionStorage
		if (store.state.token) {
			//通过登录后传入sessionStorage的user值判断登录人,admin为管理员
			//管理员不可以登录后跳转用户的页面
			if (store.state.user.uid === "admin") {
				//获取管理员可以访问的页面数组
				//这里有些问题,我放在之后的总结讲,标号 1 
				let menuListAd = store.state.menuListAd; 
				if (menuListAd && menuListAd.length != 0) {
					//对to页面进行对比	
					let isMenu = deepQuery(menuListAd, to.path);
					if (isMenu) {// 若存在,继续访问
						next();
					}else{
						Message({
						message: '无权限访问',
						type: "warning"
						});
						next(from.path);
					}
				} else{
					next();
				}
			}else{
				//登陆的是用户,不论具体是谁
				//获取用户可以访问的页面数组
				let menuListStatus = store.state.menuListStatus; //接口返回可以访问的菜单,存储在vuex中
				if (menuListStatus && menuListStatus.length != 0) {
					//对to页面进行对比
					let isMenu = deepQuery(menuListStatus, to.path);
					if (isMenu) {// 若存在,继续访问
						next();
					} else {
						Message({
							message: '无权限访问',
							type: "warning"
						});
						next(from.path);
					}
				} else {
					next();
				}
			}
		}else{
		//没有登录的情况
			next({
				path: 'login',
				query: { redirect: to.fullPath }
			})
		}
	}else {
    next();
  }
})

// 查找菜单数组中path是否存在
function deepQuery(tree, path) {
  var isGet = false;
  var retNode = null;
  function deepSearch(tree, path) {
    for (var i = 0; i < tree.length; i++) {
      console.log(tree[i].children)
      console.log(tree[i].length)
      console.log(tree[i].id)
      console.log(tree[i].title)
      if (tree[i].children && tree[i].children.length > 0) {
        deepSearch(tree[i].children, path);
      }
      if (path === tree[i].title || isGet) {
        isGet || (retNode = tree[i]);
        isGet = true;
        break;
      }
    }
  }
  deepSearch(tree, path);
  return retNode;
}
//配置请求的默认头部
Vue.prototype.$http = axios;

var vueThis = new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

export default vueThis;

3. 自己的代码的问题

  1. 大部分处理代码堆积在main.js中,但实际上我因为对Vue不熟悉,这是我第一次接触Vue框架(纯纯小白),写法不够优雅,本想要跟参考文章一样将存储数组的代码放在别的地方,但不知道怎么处理,于是干脆写在了main里面,但实际运行起来,每次跳转页面时可能都会跑一趟,挺浪费时间。
    在这个地方其实可以之前使用前面的数组名,直接引用里面的内容,交给优秀的你进行改善了。

谢谢你看完,希望能够对你产生帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值