(精華)2020年7月14日 vue vue-router動態路由的實現許可權控制
一、 addRoutes許可權控制
場景: 對登陸成功後的使用者可能會有不同的身份許可權, 看到的系統選單以及功能不一樣, 這個時候需要用到 動態路由的方式來處理
路由結構:
|— initRoutes 預設是可以看到的路由,是所有使用者都可以看到的路由選單
|— asyncRouetes 需要登陸後確認許可權才能看到的路由
1.1 初始路由initRoutes
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
import home from '../pages/home.vue';
import news from '../pages/news.vue';
var allRoutes = [{
path:'/login',
name:'login',
meta:{
title:'登陸'
},
component:()=>import('../pages/login.vue')
},{
path:'/home',
name:'home',
component:home,
meta:{
title:'首頁'
},
},{
path:'/news',
name:'news',
meta:{
title:'新聞'
},
component:news
}]
export default new VueRouter({
routes:allRoutes,
mode:'hash', //history
base:'/',
// vue-router 認為只有路由真正匹配時,才會加上 exact-active-link 這個 class,
// 如果只有一部分重合,就會加上 active-menu。
// fallback
// 不是所有瀏覽器都支援前端路由的方式,如果不支援,設定 fallback: true,
// vue 會自動 fallback 到 hash 模式。
fallback: true,
linkActiveClass: "active-menu",
linkExactActiveClass: "exact-active-menu",
})
// 在main.js中把router 例項注入到 vue 根例項中,就可以使用路由了
1.2 動態路由 asyncRouetes
var asyncRouetes = [
{
path:'/finance',
component:()=>import('../pages/finance.vue'),
meta: {
title: '財務資訊',
roles: ['admin']
}
},
{
path:'/staffs',
component:()=>import('../pages/staffs.vue'),
meta: {
title: '員工資訊',
roles: ['admin','guest']
}
}
];
export default asyncRouetes;
1.3 預設在vueRouters 例項化的時候, 只是傳入初始的路由
export default new VueRouter({
routes:allRoutes,
mode:'hash', //history
base:'/',
// vue-router 認為只有路由真正匹配時,才會加上 exact-active-link 這個 class,
// 如果只有一部分重合,就會加上 active-menu。
// fallback
// 不是所有瀏覽器都支援前端路由的方式,如果不支援,設定 fallback: true,
// vue 會自動 fallback 到 hash 模式。
fallback: true,
linkActiveClass: "active-menu",
linkExactActiveClass: "exact-active-menu",
})
// 在main.js中把router 例項注入到 vue 根例項中,就可以使用路由了
在vue例項化的時候進行掛載
1.4 進行登入處理,獲取token和使用者資訊
localStorage.setItem('token','XXXXXXXXXXX');
localStorage.setItem('userRole','admin'); //submain, guest
1.5 新增全域性路由守衛
import Vue from 'vue';
import axios from './providers/axios2.js';
import api from './providers/api.js';
import App from './App.vue'
import VueRouter from './router/index.js';
//如果全域性, 別的頁面都不需要做任何處理, babel-plugin-component也不需要配置
// import ElementUI from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css';
// Vue.use(ElementUI);
Vue.prototype.$axios = axios;
Vue.prototype.$api = api;
window.EventEmitter = new Vue();
//template模式
// new Vue({
// el:'#app',
// data:{
// hello:'hello',
// msg:'world'
// },
// // template:`<div id="app1">
// // <h1>{{msg}}</h1>
// // </div>`,
// components:{App}, //註冊全域性元件
// template:'<App/>'
// });
import asyncRouetes from './router/dynamic.js';
var initRoutes = VueRouter.options.routes;
//優化
var allPaths = [];
asyncRouetes.forEach((option)=>{
allPaths.push(option.path);
})
VueRouter.beforeEach((to, from, next) => {
var userRole = localStorage.getItem('userRole');
var token = localStorage.getItem('token');
//需要判斷下是否已經新增過動態路由,不要重複新增
// 方式: 判斷預設和路由和 讀取的路由是否一致
var isHAS = VueRouter.options.routes.some((option)=>{
return allPaths.includes(option.path)
});
if(isHAS){
next();
return;
}
//判斷是否存在token
if(token && userRole){
var asyncRouete = asyncRouetes.filter((option,index)=>{
return option.meta.roles.includes(userRole);
});
//將新路由新增到路由中, 如果不加元件component不能正確渲染
VueRouter.addRoutes(asyncRouete);
//為了正確渲染導航,將對應的新的路由新增到VueRouter中
VueRouter.options.routes = [...initRoutes,...asyncRouete];
EventEmitter.$emit('allOption',VueRouter.options.routes)
next();
} else {
// 跳轉到登陸頁面
if(to.path=='/login') {
next();
} else {
next('/login');
}
}
})
// render
var vm = new Vue({
el:'#app',
data:{
hello:'hello',
msg:'world'
},
router:VueRouter,
// render(createElement){
// return createElement('div',{
// id:'app1'
// },[
// createElement('h1',this.msg)
// ])
// },
//使用元件,利用render函式渲染
// render(h){
// return h(App)
// },
render:h=>h(App)
});
二、 許可權控制在專案中的實際使用
2.1 配置必要的動態路由檔案
在router資料夾下新增 dynamic.js
在src/pages資料夾下新增 finance.vue, staffs.vue作為測試
var asyncRouetes = [
{
path:'/finance',
component:()=>import('../pages/finance.vue'),
meta: {
title: '財務資訊',
roles: ['admin']
}
},
{
path:'/staffs',
component:()=>import('../pages/staffs.vue'),
meta: {
title: '員工資訊',
roles: ['admin','guest']
}
}
];
export default asyncRouetes;
2.2 登入成功以後需要獲取toekn以及使用者資訊
localStorage.setItem('token','XXXXXXXXXXX');
localStorage.setItem('userRole','admin'); //submain, guest
2.3 在入口檔案main.js進行 導航守衛
引入檔案:
import asyncRouetes from './router/dynamic.js';
全域性前置守衛配置:
注意:路由守衛的時候是針對vueRouter例項物件
VueRouter.beforeEach((to,from,next)=>{
//如果自定義了標題就取標題,否則拿全域性標題
window.document.title = to.meta.title?to.meta.title:'測試系統';
//這裡可以獲取登陸後的許可權
var UserToken = localStorage.getItem('token');
var userRole = localStorage.getItem('userRole');
//判斷是否存在token
if(UserToken && userRole){
//已登入
var asyncRouteMenu = asyncRouetes.filter((item,index)=>{
return item.meta.roles.includes(userRole)
})
//將新路由新增到路由中, 如果不加元件component不能正確渲染
VueRouter.addRoutes(asyncRouteMenu);
//為了正確渲染導航,將對應的新的路由新增到VueRouter中
var initRoutes = VueRouter.options.routes;
VueRouter.options.routes = [...initRoutes,...asyncRouteMenu];
next();
} else {
//是否處於登陸頁面
if(to.path=='/login'){
//如果是登入頁面路徑,就直接next()
next();
} else {
//不然就跳轉到登入;
next('/login');
}
}
})
2.3 如何處理選單的顯示
在App.vue裡 ,原來的選單部分
<router-link to="/login" tag='li'>登陸</router-link>
<router-link to="/home?name=laney" tag='li'>主頁</router-link>
<router-link to="/news" tag='li'>新聞</router-link>
需要修改為動態的, 因為這裡所有的路由 不是寫死的, 需要從路由例項this.$router.options裡獲取
可以在計算器屬性裡設定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>許可權控制- addRoutes</title>
<link rel="stylesheet" href="css/animate.css">
<style>
.active{
font-size:20px;
color:#ff7300;
text-decoration:none;
}
.main-menu a {
display: inline-block;
margin-right: 10px;
}
</style>
<script src="js/vue.js"></script>
<script src="js/vue-router.js"></script>
</head>
<body>
<div id="itapp">
<div class="main-menu">
<!-- 寫成動態的 -->
<!-- $router.options.routes 可以從計算器屬性-->
<!-- <router-link v-for="(item,index) in $router.options.routes" :key="index" :to="item.path">{{item.meta.title}}</router-link> -->
<router-link v-for="(item,index) in getMyRoutes" :key="index" :to="item.path">{{item.meta.title}}</router-link>
</div>
<div>
<transition enter-active-class="animated bounceInLeft" leave-active-class="animated bounceOutRight">
<router-view></router-view>
</transition>
</div>
<hr>
<button @click="push">新增路由</button>
<button @click="replace">替換路由</button>
</div>
<template id="user">
<div>
<h3>使用者資訊</h3>
<ul>
<router-link to="/user/login?name=tom&pwd=123" tag="li">使用者登陸</router-link>
<router-link to="/user/regist/alice/456" tag="li">使用者註冊</router-link>
</ul>
<router-view></router-view>
</div>
</template>
<script>
var Home={
template:'<h3>我是主頁</h3>'
}
var User={
template:'#user'
}
var Login={
template:'<h4>使用者登陸。。。獲取引數:{{$route.query}},{{$route.path}}</h4>'
}
var Regist={
template:'<h4>使用者註冊。。。獲取引數:{{$route.params}},{{$route.path}}</h4>'
}
var Finance={
template:'<h4>財務資訊</h4>'
}
var News={
template:'<h3>我是新聞</h3>'
}
//預設是可以看到的路由
var initRoutes=[
{
path:'/home',
component:Home,
// 路由元資訊
meta: {
title: '首頁'
}
},
{
path:'/user',
component:User,
meta: {
title: '使用者'
},
// children:[
// {
// path:'login',
// component:Login
// },
// {
// path:'regist/:username/:password',
// component:Regist
// }
// ]
},
// {
// path:'*',
// redirect:'/home',
// hidden: true //隱藏不需要渲染到頁面上的路由
// }
];
//需要登陸後確認許可權才能看到的路由
var asyncRouetes = [
{
path:'/finance',
component:Finance,
meta: {
title: '財務資訊',
roles: ['admin']
}
},
{
path:'/news',
component:News,
meta: {
title: '新聞中心',
roles: ['admin','guest']
}
}
];
const routerAll=new VueRouter({
routes:initRoutes, //簡寫,相當於routes:routes
linkActiveClass:'active', //更新活動連結的class類名,預設的啟用的 class
linkExactActiveClass:'active-extact', //精確啟用的 class
mode: "hash", //預設
});
導航守衛
//加入你獲取了角色
routerAll.beforeEach((to, from, next) => {
// var auth = localStorage.getItem('userRole');
var auth = 'admin';
var asyncRouete = asyncRouetes.filter((option,index)=>{
return option.meta.roles.includes(auth);
});
//將新路由新增到路由中, 如果不加元件component不能正確渲染
routerAll.addRoutes(asyncRouete);
//為了正確渲染導航,將對應的新的路由新增到routerAll中
routerAll.options.routes = [...initRoutes,...asyncRouete];
debugger
next();
})
new Vue({
el:'#itapp',
router:routerAll, //注入路由
computed:{
getMyRoutes(){
var thisData = this.$router.options.routes;
return thisData;
}
},
methods:{
push(){
this.$router.push({path:'home'}); //新增路由,切換路由
},
replace(){
routerAll.replace({path:'user'}); //替換路由,沒有歷史記錄
}
}
});
</script>
</body>
</html>
藉助中心控制vue例項 , 利用eventEmitter
<template>
<div id="app">
<h1>{{msg}} <button type="button" @click="logOut()">登出</button></h1>
<div >
<ul class="main-menu">
<router-link v-for="(item,index) in getMyRoutes" :key="index" :to="item.path" tag='li'>{{item.meta.title}}</router-link>
<!-- <router-link to="/login" tag='li'>登陸</router-link>
<router-link to="/home?name=laney" tag='li'>主頁</router-link>
<router-link to="/news" tag='li'>新聞</router-link> -->
</ul>
<!-- <ul @click="gotoPage($event)">
<li tag='home'>主頁</li>
<li tag='news'>新聞</li>
</ul> -->
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to ruanmou',
getMyRoutes:[]
}
},
computed:{
// getMyRoutes(){
// console.log('this.$router.options.routes')
// console.log(this.$router.options.routes)
// var thisData = this.$router.options.routes;
// return thisData;
// }
},
methods:{
logOut(){
localStorage.clear();
this.$router.push({
path:'/login'
})
location.reload();
},
gotoPage(ev){
var target = ev.target,
tag = target.getAttribute('tag');
switch(tag){
case 'home':
//相當於get方式
this.$router.push({
path:'/home',
query:{
name:'laney'
}
})
break;
case 'news':
this.$router.push({
path:'/news',
query:{
age:'10'
}
})
break;
}
}
},
mounted(){
EventEmitter.$on('allOption',(res)=>{
console.log('mounted')
console.log(res)
this.getMyRoutes = res;
})
console.log(this.$router.options.routes)
}
}
</script>
<style scoped>
.main-menu li {
display: inline-block;
margin-right: 30px;
background: #000;
color: #fff;
padding: 5px 20px;
cursor: pointer;
}
.main-menu li.active-menu{
background: #ff6600;
}
</style>
相關文章
- (精華2020年5月8日更新) vue教程篇 vue-router路由的許可權控制Vue路由
- vue-router控制路由許可權Vue路由
- Vue | 自定義指令和動態路由實現許可權控制Vue路由
- 如何用 Vue 實現前端許可權控制(路由許可權 + 檢視許可權 + 請求許可權)Vue前端路由
- 使用動態路由實現許可權管理路由
- Vue許可權路由實現總結Vue路由
- Vue管理系統前端系列六動態路由-許可權管理實現Vue前端路由
- Vue 配合eiement動態路由,許可權驗證Vue路由
- (精華2020年5月8日更新) vue教程篇 vue-router路由的使用Vue路由
- vue許可權路由實現方式總結Vue路由
- vue許可權路由實現方式總結二Vue路由
- (精華)2020年7月18日 vue element-ui實現動態表格VueUI
- Laravel實現許可權控制Laravel
- vue實現後臺管理系統頁面功能和頁面路由許可權的控制Vue路由
- vue vuex vue-router後臺專案——許可權路由(超詳細簡單版)Vue路由
- vue+element-ui實現動態的許可權管理和選單渲染VueUI
- vue.js除了動態路由,前端許可權還可以這麼玩Vue.js路由前端
- element-admin通過後端動態路由表實現使用者許可權控制(一)後端路由
- Vue 前端應用實現RBAC許可權控制的一種方式Vue前端
- (精華)2020年7月18日 vue element-ui實現表格可編輯VueUI
- Spring Security實現基於RBAC的許可權表示式動態訪問控制Spring
- 許可權控制及AOP日誌
- 前端許可權控制系統的實現思路前端
- 基於VUE自定義指令實現按鈕級許可權控制Vue
- 基於Vue2.0實現後臺系統許可權控制Vue
- Vue2-利用自定義指令實現按鈕許可權控制Vue
- spring aop實現許可權控制,路徑控制Spring
- 關於動態許可權
- (精華)2020年7月18日 vue element-ui實現表格拖動排序VueUI排序
- vue+elementUI實現許可權的部門管理VueUI
- vue + vuex + directives實現許可權按鈕的思路Vue
- android動態許可權到自定義許可權框架Android框架
- VUE動態路由和按鈕的實現Vue路由
- SpringBoot整合SpringSecurityOauth2實現鑑權-動態許可權Spring BootGseOAuth
- Spring Boot動態許可權變更實現的整體方案Spring Boot
- SpringBoot(一) 如何實現AOP的許可權控制Spring Boot
- spring aop實現簡單的許可權控制功能Spring
- Elasticsearch 許可權控制Elasticsearch