Vue Router
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
login
用户登录之后,获取动态路由
async loginSuccess(data) {
console.log('---🍎新登录的接口参数', data)
const user = {
username: data.user_info.username,
Authorization: data.token,
area_level: data.org_info.area_info ? data.org_info.area_info.level : '',
}
let _privileges = []
let routerMenus = [] //全部路由
data.system_configs.forEach((system) =>{
routerMenus = routerMenus.concat(system.menus)
if(system.id === 1){
_privileges = system.privileges
}
})
LocalEvent.set("user", user);
LocalEvent.set("sidermap", generateSidermap(routerMenus));
LocalEvent.set("cmenus", routerMenus);
LocalEvent.set("system_configs", data.system_configs);
console.log('---🍎cmenus', LocalEvent.get("cmenus"))
console.log('---🍎sidermap', LocalEvent.get("sidermap"))
console.log('---🍎system_configs', LocalEvent.get("system_configs"))
// 路由 addRoutes
const dynamicRoutes = dynamicRouterGenerator(routerMenus);
this.$router.addRoutes(dynamicRoutes);
// 权限表转换后存入localstorage, 目前只有网监有详细的权限表
const priv_map = {};
_privileges.forEach((f) => {
priv_map[f.action] = f;
});
LocalEvent.set("privilege", priv_map);
console.log('---🍎privilege', LocalEvent.get("privilege"))
// 跳转
this.$router.push("layout/otm/index/index");
}
接口返回的数据形式如下
{
"org_info": {
"secondAuthorityId": 0,
"showName": "xxxxxx管理局",
"level": 1,
"sysId": 1,
"utime": 1670918067,
"orgIndex": "18.",
"cityId": 0,
"upperId": 1,
"provinceId": 520000,
"authorityId": 0,
"districtId": 0,
"isSpecial": 0,
"fourthAuthorityId": 0,
"name": "xxxx督管理局",
"ctime": 1665471321,
"firstAuthorityId": 0,
"id": 18,
"area_info": {
"full_name": "贵州省",
"level": 1,
"name": "贵州省",
"id": 520000
},
"thirdAuthorityId": 0,
"opUid": 31
},
"user_info": {
"utime": 1665471328,
"lastlogin": 1690251053,
"roleId": 2,
"deptId": 0,
"mobile": "",
"orgLevel": 1,
"dept": "",
"orgId": 18,
"token": "xxxx",
"password": "ad9883aa6a741cb36e71bc6086762366",
"name": "",
"ctime": 1665471328,
"id": 29,
"opUid": 27,
"status": 1,
"username": "guizhou"
},
"department_info": {
"name": "网监部门",
"id": 1
},
"system_configs": [ // 菜单
{
"role_name": "string|角色名称",
"privileges": [
{
"name": "首页数据",
"action": "index/index",
"id": 1
},
{
"name": "任务列表",
"action": "task/list",
"id": 2
}
],
"role_id": "int|角色ID",
"name": "string|网络交易监管系统",
"id": 1,
"menus": [
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "首页",
"action": "otm/index/index",
"id": 1,
"upper_id": 0,
"key": "1"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "主体管理",
"action": "otm/net/master-manage",
"id": 2,
"upper_id": 0,
"key": "2"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "经营主体",
"action": "otm/net/master",
"id": 3,
"upper_id": 0,
"key": "3"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "经营客体",
"action": "otm/net/object",
"id": 4,
"upper_id": 0,
"key": "4"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "标签管理",
"action": "otm/net/tag-manage",
"id": 5,
"upper_id": 0,
"key": "5"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "数据下载",
"action": "otm/net/data-download",
"id": 6,
"upper_id": 0,
"key": "6"
}
]
},
{
"role_name": "string|角色名称",
"privileges": [],
"role_id": "int|角色ID",
"name": "电子取证",
"id": 2,
"menus": [
{
"privilege_ids": [],
"level": 1,
"name": "取证任务",
"action": "obtain-evidence/forensicTasks",
"id": 7,
"upper_id": 0,
"key": "7"
},
{
"privilege_ids": [],
"level": 1,
"children": [
{
"privilege_ids": [],
"level": 2,
"name": "手机管理",
"action": "obtain-evidence/phonemgr",
"id": 32,
"upper_id": 5,
"key": "32"
}
],
"name": "系统运维",
"action": "obtain-evidence/system",
"id": 8,
"upper_id": 0
}
]
},
{
"role_name": "string|角色名称",
"privileges": [],
"role_id": "int|角色ID",
"name": "基础服务",
"id": 3,
"menus": [
{
"privilege_ids": [],
"level": 1,
"name": "用户管理",
"action": "base-sys/user-manage",
"id": 9,
"upper_id": 0,
"key": "9"
}
]
}
],
"token": "xxxxxx"
}
index.js 拼接动态路由、静态路由
入口:main.js 引入的router.js
import VueRouter from 'vue-router'
import { generateAllRoutes } from './utils.js'
import { staticRouterGenerator } from './routers/staticRouter.js';
import { dynamicRouterGenerator } from './routers/dynamicRouter.js';
Vue.use(VueRouter)
// 生成路由的函数
// 首次登陆:入参为 ''
// 登陆后刷新:入参为 接口获取到的 menus 菜单
const routes = generateAllRoutes(
LocalEvent.get('cmenus'),
staticRouterGenerator,
dynamicRouterGenerator
)
const router = new VueRouter({
base: process.env.BASE_URL,
routes: routes
})
// 检验特殊情况: 用户登陆后在系统中某页面 手动清空localstorage的cmenus后直接跳转回登陆也
router.beforeEach((to,from,next)=>{
if(to.path!=='/'&&!LocalEvent.get('cmenus')){
next('/')
}else{
next()
}
})
静态路由
export function staticRouterGenerator(){
return [
{
path: '/',
name: 'login',
component: Login,
meta: {
title: 'login'
}
},
{
path: '/layout',
name: 'layout',
component: Layout,
children: [{
path: '/layout/review/reviewpage',
name: 'reviewPage',
component: ReviewPage,
meta: {
title: 'reviewPage'
}
},
{
path: '/layout/task/check',
name: 'clueCheck',
component: CommonPage,
meta: {
title: 'clueCheck'
}
},
{
path: '/layout/task/deal',
name: 'clueCheck',
component: CommonPage,
meta: {
title: 'clueCheck'
}
},
{
path: '/layout/task/edit',
name: 'clueEdit',
component: EditPage,
meta: {
title: 'clueEdit'
}
}]
},
{
path: '/document_print/:id',
name: 'documentPrint',
component: DocumentPrint,
meta: {
title: 'documentPrint'
}
},
{
path: '/clue_document_print/:id',
name: 'clueDocumentPrint',
component: ClueDocumentPrint,
meta: {
title: 'clueDocumentPrint'
}
},
{
path: '/layout/big_screen',
name: 'bigScreen',
component: BigScreen,
meta: {
title: 'bigScreen'
}
}
]
}
动态路由
import Layout from '@layout/layout.vue'
// 首页
import Index from '@pages/index/index.vue'
// 系统设置
import Organize from '@pages/system/organize/system-organize.vue'
import Privilege from '@pages/system/privilege/system-privilege.vue'
import Role from '@pages/system/role/system-role.vue'
import Area from '@pages/system/area/index.vue'
// 经营主体数据
import Websites from '@pages/mainpart/websites/websites.vue'
import TransactionPlatforms from '@pages/mainpart/transaction-platforms/transaction-platforms.vue'
import Takeaways from '@pages/mainpart/takeaways/takeaways.vue'
import AppDevs from '@pages/mainpart/app-devs/app-devs.vue'
import WechatAccounts from '@pages/mainpart/wechat-accounts/wechat-accounts.vue'
import MiniPrograms from '@pages/mainpart/mini-programs/mini-programs.vue'
import MobileEcommerce from '@pages/mainpart/mobile-ecommerce/mobile-ecommerce.vue'
import Streamers from '@pages/mainpart/streamers/streamers.vue'
// 智能线索发现
import TaskMana from '@pages/taskMana/taskMana.vue'
import ClueReview from '@pages/intelligentClue/clueReview/review.vue'
import ClueDataSearch from '@pages/intelligentClue/clueDataSearch/clueDataSearch.vue'
import MyClue from '@pages/intelligentClue/myClue/index.vue'
import SpecialInspection from '@pages/intelligentClue/specialInspection/index.vue'
// 经营行为
import Website from '@pages/content/website/index.vue'
import Shop from '@pages/content/shop/index.vue'
import OrderShop from '@pages/content/order-shop/index.vue'
// 取证
import ObtainEvidence from '@pages/obtainEvidence/obtainEvidence.vue'
// 数据统计
import DataStatis from '@pages/dataStatis/dataStatis.vue'
// 用户管理
import UserManagement from '@pages/baseService/user-management/user.vue'
import Myiframe from '@pages/iframe/index.vue'
//网络交易监管
import MasterManage from '@pages/net/master-manage/master-manage.vue' // 主体管理
import BusinessEntity from '@pages/net/business-entity/business-entity.vue' // 经营主体
import BusinessCurriculum from '@pages/net/business-curriculum/business-curriculum.vue' // 经营客体
import TagsManage from '@pages/net/tags-manage/tags-manage.vue' // 标签管理
import DataDownload from '@pages/net/data-download/data-download.vue' // 数据下载
// 移动电商监控管理
import ClueSearch from '@pages/m-commerce/clueDataSearch/clueDataSearch.vue' // 线索查询
import MyClueM from '@pages/m-commerce/myClue/index.vue' // 我的线索
import SpecialInspect from '@pages/m-commerce/specialInspection/index.vue' // 专项检查
/**
* @description 从接口 menus 中获取到动态部分的路由
* menus 格式说明
* 数组
* 数组元素为对象
* 1. key: id action name children?
* 2. 最底层menu(即需要绑定router的menu)的特征是没有 children
* @return dynamicRouters 放到
* 从 routermapLocal 中匹配action获取到routers数组
*/
export function dynamicRouterGenerator(menus){
console.log('🍌menus', menus)
const [actionArr,metaIdMap] = __getLowestMenuAction(menus)
// 从 routermapLocal 中取出menus中有的路由
const neededRoutes = dynamicRouter.filter(f=>actionArr.includes(f.path))
console.log('🍌neededRoutes', neededRoutes)
// 给neededRoutes 每个添加meta.id
const res = neededRoutes.map(m=>{
m.meta.id = metaIdMap[m.path]
return m
})
return [{
path: '/layout',
name: 'layout',
component: Layout,
children: res
}]
}
const dynamicRouter = [
// 首页
{ path: 'otm/index/index',name: '首页',meta: { title: '首页' },component: Index },
{ path: 'otm/net/master-manage',name: '主体管理',meta: { title: '主体管理' },component: MasterManage },
{ path: 'otm/net/master',name: '经营主体',meta: { title: '经营主体' },component: BusinessEntity },
{ path: 'otm/net/object',name: '经营客体',meta: { title: '经营客体' },component: BusinessCurriculum },
{ path: 'otm/net/tag-manage',name: '标签管理',meta: { title: '标签管理' },component: TagsManage }
]
/**
* @private for @function convertFromMenuToRouters
* 获取没有children的menu的action数组
* 获取action:id 的映射对象
* 【temp】先临时做成仅仅兼容 [{[]}]
*/
function __getLowestMenuAction(menus){
const actionArr = []
const metaIdMap = {}
menus.forEach(menu=>{
if(!menu.children){
// 无子菜单 例如:首页
actionArr.push(menu.action)
metaIdMap[menu.action] = menu.id
}else{
// 有子菜单
menu.children.forEach(submenu=>{
actionArr.push(submenu.action)
metaIdMap[submenu.action] = submenu.id
})
}
})
console.log('🍌actionArr,metaIdMap',actionArr,metaIdMap)
return [actionArr,metaIdMap]
}
模拟数据
🍌actionArr
[
"otm/index/index",
"otm/net/master-manage",
"otm/net/master",
"otm/net/object",
"otm/net/tag-manage",
"otm/net/data-download",
"obtain-evidence/forensicTasks",
"obtain-evidence/phonemgr",
"base-sys/user-manage"
]
metaIdMap
{
"otm/index/index": 1,
"otm/net/master-manage": 2,
"otm/net/master": 3,
"otm/net/object": 4,
"otm/net/tag-manage": 5,
"otm/net/data-download": 6,
"obtain-evidence/forensicTasks": 7,
"obtain-evidence/phonemgr": 32,
"base-sys/user-manage": 9
}
菜单list
[
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "首页",
"action": "otm/index/index",
"id": 1,
"upper_id": 0,
"key": "1"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "主体管理",
"action": "otm/net/master-manage",
"id": 2,
"upper_id": 0,
"key": "2"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "经营主体",
"action": "otm/net/master",
"id": 3,
"upper_id": 0,
"key": "3"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "经营客体",
"action": "otm/net/object",
"id": 4,
"upper_id": 0,
"key": "4"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "标签管理",
"action": "otm/net/tag-manage",
"id": 5,
"upper_id": 0,
"key": "5"
},
{
"privilege_ids": [1,2,3,4,5],
"level": 1,
"name": "数据下载",
"action": "otm/net/data-download",
"id": 6,
"upper_id": 0,
"key": "6"
},
{
"privilege_ids": [],
"level": 1,
"name": "取证任务",
"action": "obtain-evidence/forensicTasks",
"id": 7,
"upper_id": 0,
"key": "7"
},
{
"privilege_ids": [],
"level": 1,
"children": [
{
"privilege_ids": [],
"level": 2,
"name": "手机管理",
"action": "obtain-evidence/phonemgr",
"id": 32,
"upper_id": 5,
"key": "32"
}
],
"name": "系统运维",
"action": "obtain-evidence/system",
"id": 8,
"upper_id": 0
},
{
"privilege_ids": [],
"level": 1,
"name": "用户管理",
"action": "base-sys/user-manage",
"id": 9,
"upper_id": 0,
"key": "9"
}
]
neededRoutes
菜单a-menu
a-menu(
mode="inline",
theme="dark",
class="layout-sider-menu"
style="height: 100vh; overflow-x: scroll; padding-bottom: 50px",
:selectedKeys="defaultItem",
:inline-collapsed="collapsed",
:open-keys="openKeys",
@openChange="onOpenChange",
@select="onSelect"
)
a-sub-menu.my-menu-sub(:key="item.key", v-for="item in list" v-if="item.children")
span(slot="title")
a-icon(:type="iconMap[item.name]")
span {{ item.name }}
a-menu-item(
v-if="item.children",
v-for="child in item.children",
:key="child.key",
@click="routerTo(child.action)"
)
//- a-icon(:type="iconMap[child.name]")
span {{ child.name }}
a-sub-menu(v-else, :key="child.key")
span(slot="title")
a-icon(:type="iconMap[child.name]")
span {{ child.name }}
a-menu-item.my-menu-sub-ul(
v-for="grandChild in child.children",
:key="grandChild.key",
@click="routerTo(grandChild.action)"
)
span {{ grandChild.name }}
a-menu-item(
v-else
:key="item.key"
@click="routerTo(item.action)"
)
a-icon(:type="iconMap[item.name]")
span {{item.name}}
<script>
const iconMap = {
首页: "home",
系统管理: "setting"
};
export default {
data() {
return {
user: {},
list: [],
flag: false,
openKeys: [],
iconMap,
// 默认选中的item
defaultItem: ["1"],
collapsed: false,
subMap,
siteTitle: "",
isActive: 1
};
},
created() {
//this.siteTitle = window.location.hostname == 'jl.ot.dubhe-irp.cn' ? 'xx' : '系统';
},
async mounted() {
// 从localStorage中获取用户名
this.user = LocalEvent.get("user") ? LocalEvent.get("user") : {};
this.list = LocalEvent.get("sidermap") ? LocalEvent.get("sidermap") : [];
console.log('---🍇菜单list', this.list)
this.openKeys = LocalEvent.get("latestMenu")
? LocalEvent.get("latestMenu")
: [];
this.defaultItem = LocalEvent.get("latestItem")
? LocalEvent.get("latestItem")
: ["1"];
// this.fetchTaskData();
this.$store.dispatch("getTasknum");
// 用于刷新时恢复页面
this.isActive = LocalEvent.get('activeSystemTab')
let systemConfigs = LocalEvent.get('system_configs')
systemConfigs.forEach((system) =>{
if(system.id === this.isActive){
this.list = system.menus
}
})
},
watch: {
$route(val) {
this.dealSider(val);
},
},
methods: {
changeSys (val){
this.isActive = val
LocalEvent.set('activeSystemTab', val)
let systemConfigs = LocalEvent.get('system_configs')
systemConfigs.forEach((system) =>{
if(system.id === val){
this.list = system.menus
}
})
},
dealSider(val) {
console.log('监听路由变化', val)
const subMenu = [];
for (const key in subMap) {
if (val.path.includes(key)) {
subMenu.push(subMap[key]);
}
}
const openKeys = new Set([...subMenu, ...this.openKeys]);
this.defaultItem = [`${val.meta.id}`];
LocalEvent.set("latestItem", this.defaultItem);
LocalEvent.set("latestMenu", [...openKeys]);
console.log('🍊最新打开的菜单和最新打开的路由', LocalEvent.get("latestItem"), LocalEvent.get("latestMenu"))
},
onOpenChange(openKeys) {
this.openKeys = openKeys;
if (openKeys.length === 0) {
LocalEvent.clear("latestMenu");
} else {
LocalEvent.set("latestMenu", openKeys);
}
},
routerTo(path) {
if (this.$route.path === path) return;
if (path === 'big_screen') {
const router = this.$router.resolve({
path: `/layout/big_screen`
})
window.open(router.href)
}else{
this.$router.push("/layout/" + path);
}
},
clickNavigator() {
this.flag = true;
if (!this.collapsed) {
// 折叠动作
// LocalEvent.set("latestItem", this.defaultItem);
} else {
this.defaultItem = LocalEvent.get("latestItem");
const subMenu = [];
for (const key in subMap) {
if (this.$route.path.includes(key)) {
subMenu.push(subMap[key]);
}
}
LocalEvent.set("latestMenu", subMenu);
this.openKeys = subMenu;
}
this.collapsed = !this.collapsed;
},
onSelect(option) {
if (option.key === 0) {
return;
}
this.defaultItem = [`${option.key}`];
LocalEvent.set("latestItem", [`${option.key}`]);
}
},
};