vue动态路由及 antDesignVue a-menu菜单

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}`]);
    }
  },
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值