绝大多数,用户角色和功能固定时,推荐在这种方式。
开发简单,工作量少,可以快速交付。
1. 登录
当用户登录时,将用户角色写入到vuex,保存当前用户角色信息。
# store/index.js
import {createStore} from 'vuex'
export default createStore({
state: {
token: localStorage.getItem('token') || '',
role: localStorage.getItem('role') || ''
},
getters: {},
mutations: {
login(state, {token, role}) {
state.token = token
state.role = role
localStorage.setItem('token', token)
localStorage.setItem('role', role)
}
},
actions: {},
modules: {}
})
# 登陆
const handleFinish = () => {
const login_info = {
token: '123',
role: formState.role
}
store.commit('login', login_info)
message.info(formState.user + "登陆成功")
router.replace({name: "admin"})
};
2.定义路由
定义路由时,基于 meta 来指定哪些角色的用户可以访问此路由。
# router/index.js
const routes = [
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue'),
meta: {is_menu: false}
}, {
path: '/admin',
name: 'admin',
component: () => import('../views/AdminView.vue'),
meta: {is_menu: false},
children:
[
{
path: 'user',
name: 'user',
component: () => import('../views/admin/UserView.vue'),
meta: {role: ['user'], is_menu: true, title: 'user'}
},
{
path: 'user2',
name: 'user2',
component: () => import('../views/admin/User2View.vue'),
meta: {role: ['admin'], is_menu: true, title: 'user2'}
},
{
path: 'all',
name: 'all',
component: () => import('../views/admin/AllView.vue'),
meta: {role: ['admin','user'], is_menu: true, title: 'all'}
}]
}]
3.路由导航守卫
用户访问页面时,在导航守卫中,进行判断,是否有权访问此路由。
- 有权,继续访问
- 无权,跳转登录页面
outer.beforeEach((to, from, next) => {
let roles = to.meta.role
if (roles) {
console.log(store.state.role)
// 在roles里找权限store.state.role,找不到返回-1
if (roles.indexOf(store.state.role) != -1) {
next()
} else {
next({name: "login"})
}
} else {
next()
}
})
4.菜单的加载
根据vuex中的角色,加载自己的路由,并添加在菜单中。
<template>
<a-layout>
<a-layout-sider :style="{ overflow: 'auto', height: '100vh', position: 'fixed', left: 0 }">
<div class="logo"/>
<a-menu theme="dark" mode="inline" v-model:selectedKeys="selectedKeys">
<a-menu-item :key="item" v-for="item in routerlist">
<user-outlined/>
<router-link :to="{name:item.name}">{{ item.meta.title }}</router-link>
</a-menu-item>
</a-menu>
</a-layout-sider>
<a-layout :style="{ marginLeft: '200px' }">
<a-layout-header :style="{ background: '#fff', padding: 0 }"/>
<a-layout-content :style="{ margin: '24px 16px 0', overflow: 'initial' }">
<div :style="{ padding: '24px', background: '#fff', textAlign: 'center' }">
<router-view/>
</div>
</a-layout-content>
</a-layout>
</a-layout>
</template>
<script setup>
import {
UserOutlined,
// VideoCameraOutlined,
} from '@ant-design/icons-vue';
import {computed, ref} from 'vue';
import {useRouter} from "vue-router";
import {useStore} from "vuex";
const router = useRouter()
const store = useStore()
const selectedKeys = ref(['1'])
const routerlist = computed(
() => {
return router.getRoutes().filter(item => {
if (item.meta.is_menu && item.meta.role.indexOf(store.state.role) != -1) {
return true
}
})
}
)
</script>
标签:vue,角色,静态,state,token,meta,role,import,权限
From: https://www.cnblogs.com/sherwin1995/p/17298952.html