vue-admin-template中vue动态路由不显示问题解决

news2024/11/17 16:01:45

使用的的是vue-admin-template,这是一个极简的 vue admin 管理后台,它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。需要根据自己的需求二次开发。
线上地址:vue-admin-template
国内访问:vue-admin-template

  • 开发了一个公司内部的后台管理系统
  • 路由信息是登录成功后台返回,然后动态添加的
  • 遇到的问题:动态添加路由死活不显示

解决思路:

1. 所有的页面必须有index.vue

比如一个模块“日志和统计”, 它包含两个自己,‘操作日志’和‘数据列表’
日志和统计

  • LogsAndStatistics
    • OperationLog
      • index.vue
    • DataStatistics
      • index.vue
    • index.vue

对!必须有index.vue!必须有index.vue!!必须有index.vue!重要的事情3遍,不写就是不显示!!!
name也必须是一 一对应的唯一值!!!

2. 修改配置条件

  1. 先登录成功后后台会返回该账号匹配的路由信息,格式如下:
[
   {
       "title": "消息管理",
       "name": "message",
       "id": 2,
       "pid": 0,
       "icon": "el-icon-tickets",
       "component": "#",
       "path": "/message-management",
       "redirect": "/list",
       "alwaysShow": 1,
       "children": [
           {
               "title": "消息列表",
               "name": "MessageManagement",
               "id": 3,
               "pid": 2,
               "component": "MessageManagement",
               "path": "list"
           }
       ]
   },
       {
        "title": "客户管理",
        "name": "Customer:List",
        "id": 25,
        "pid": 0,
        "icon": "el-icon-user-solid",
        "component": "#",
        "path": "/customer",
        "redirect": "Customer",
        "alwaysShow": 1,
        "children": [
            {
                "title": "客户列表",
                "name": "CustomerManagement",
                "id": 26,
                "pid": 25,
                "component": "CustomerManagement",
                "path": "list"
            }
        ]
    },
    {
        "title": "用户和权限",
        "name": "",
        "id": 31,
        "pid": 0,
        "icon": "el-icon-user-solid",
        "component": "#",
        "path": "/user-permissions",
        "redirect": "/user-list",
        "alwaysShow": 1,
        "children": [
            {
                "title": "组织架构",
                "name": "OrganizationalStructure",
                "id": 37,
                "pid": 31,
                "component": "UsersAndPermissions/OrganizationalStructure",
                "path": "organizational-list"
            },
            {
                "title": "用户列表",
                "name": "UserList",
                "id": 32,
                "pid": 31,
                "component": "UsersAndPermissions/UserList",
                "path": "user-list"
            },
            {
                "title": "权限列表",
                "name": "PermissionList",
                "id": 41,
                "pid": 31,
                "component": "UsersAndPermissions/PermissionList",
                "path": "permission-list"
            },
            {
                "title": "角色列表",
                "name": "RoleList",
                "id": 44,
                "pid": 31,
                "component": "UsersAndPermissions/RoleList",
                "path": "role-list"
            }
        ]
    },
    {
        "title": "日志和统计",
        "name": "LogManagement",
        "id": 46,
        "pid": 0,
        "icon": "el-icon-error",
        "component": "#",
        "path": "/logs-statistics",
        "redirect": "/logs",
        "alwaysShow": 1,
        "children": [
            {
                "title": "操作日志",
                "name": "LogsAndStatistic",
                "id": 47,
                "pid": 46,
                "component": "LogsAndStatistics/OperationLog",
                "path": "logs"
            },
            {
                "title": "数据列表",
                "name": "DataStatistics",
                "id": 48,
                "pid": 46,
                "component": "LogsAndStatistics/DataStatistics",
                "path": "statistics"
            }
        ]
    }
]
  1. 先保存到本地:我们是登录成功后直接返回的如下图:
    在这里插入图片描述
// utils/auth.js
export function setPermission(permission){
  const permissionData = {permission}
	return localStorage.setItem(PERMISSION, JSON.stringify(permissionData))
}
export function getPermission(){
  const val = JSON.parse(localStorage.getItem(PERMISSION)|| '{}')
  return val.permission
}
  1. 我的permission配置文件直接copy的 vue-element-admin 的二次修改的。

首先是router下的index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/Login/index.vue'),
    hidden: true
  },
  {
    path: '/retrieve-password',
    component: () => import('@/views/RetrievePassword/index.vue'),
    hidden: true
  },
  {
    path: '/404',
    name:'Page404',
    component: () => import('@/views/404'),
    hidden: true
  }
]

const createRouter = () => new Router({
  isAddDynamicMenuRoutes: false, // 是否已经添加动态(菜单)路由
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes
})

const router = createRouter()
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

export default router

然后修改src 目录下的permission.js

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken,getPermission} from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'

NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = ['/login','/retrieve-password'] // 不需要重定向白名单:登录和找回密码页面不需要重定向

router.beforeEach(async(to, from, next) => {
  // start progress bar
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // 确定用户是否已登录
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done()
    } else {
      // 是否添加动态路由
      if (router.options.isAddDynamicMenuRoutes) {
        next()
      } else {
        try {
          // 获取本地存储的路由信息(后台返回的)
          const Permission = getPermission()
         if(Permission.length<1){ return Promise.reject('菜单数据加载异常')}
          const accessRoutes = await store.dispatch('permission/generateRoutes', Permission)
          router.addRoutes(accessRoutes)
          router.options.isAddDynamicMenuRoutes = true
          next({ ...to, replace: true })
        } catch (error) {
          console.log(error)
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* 未登录*/
    if (whiteList.indexOf(to.path) !== -1) {
      //在免费登录白名单中,直接进入
      next()
    } else {
      //没有访问权限的其他页面将重定向到登录页面。
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

store文件夹下添加permission.js (需要在store的index.js下引入:import permission from ‘./modules/permission’)

  • 解析返回的路由信息时import(‘@/views/XXX/index.vue’) 会报错,找不到。
  • 开始把整个路由信息’@/views/XXX/index.vue’全部返回,直接使用require([/${component}], resolve)) ,还是报错;
  • 搜索尝试后解决component只要中间部分:
    eg: `@/views/RetrievePassword/index.vue' => 'RetrievePasswod'
    解析时:require([`@/views/${component}/index.vue`], resolve))
import Vue from 'vue'
import {constantRoutes} from '@/router'
import Layout from '@/layout'
/**
* 后台查询的菜单数据拼装成路由格式的数据
* @param list 处理的路由列表
*/
export function AddMenuRoutes(list = []) {
  const newRoutes = []
  list.map((v, i) => {
    const {path,id,name,component,alwaysShow,redirect,title,icon,children} = v
    const route = {
      id,
      path: component=='#' && i==0?'/':path
    }
    if(component=='#'){ 
      Vue.set(route,'component',Layout)
    }else{
      Vue.set(route,'component',(resolve) => require([`@/views/${component}/index.vue`], resolve))
    }
    if(name){
      Vue.set(route,'name',name)
    }
    if(title){
      Vue.set(route,'meta',{title})
      if(icon){
        Object.assign(route.meta,{icon})
      }
    }
    if(alwaysShow==1){Vue.set(route,'alwaysShow',true)}
    if(redirect){Vue.set(route,'redirect',redirect)}
    if (children && children.length) {
      Vue.set(route,'children',[])
      route.children = AddMenuRoutes(v.children)
    }
    newRoutes.push(route)
  })
  return newRoutes
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  /**
	 * @param {*} permissionList 后台传回来的路由数据
	 */
  async generateRoutes({ commit }, permissionList) {
    const MenuList = []
    const permissions = permissionList || []
    Object.assign(MenuList, permissions)
    const newRoutes = await AddMenuRoutes(MenuList)
    commit('SET_ROUTES', newRoutes)
    return newRoutes
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

就可以看到效果了:
在这里插入图片描述

完整的authentic.js:

const TokenKey = 'access_token'
const PERMISSION ='Permission'
const USERINFO = 'UserInfo'
const BUTTONS = 'Buttons'
export function getUserInfo() {
  const val = JSON.parse(localStorage.getItem(USERINFO)||'{}')
  return  val.name
}
export function setUserInfo(name) {
  const userInfo={name}
  return localStorage.setItem(USERINFO, JSON.stringify(userInfo))
}
export function removeUserInfo() {
  return localStorage.removeItem(USERINFO)
}


export function getToken() {
  const val = JSON.parse(localStorage.getItem(TokenKey)|| '{}')
  return val.token
}
export function setToken(token) {
  const tokeData = {token}
  return localStorage.setItem(TokenKey, JSON.stringify(tokeData))
}
export function removeToken() {
  return localStorage.removeItem(TokenKey)
}

export function setPermission(permission){
  const permissionData = {permission}
	return localStorage.setItem(PERMISSION, JSON.stringify(permissionData))
}
export function getPermission(){
  const val = JSON.parse(localStorage.getItem(PERMISSION)|| '{}')
  return val.permission
}
export function removePermission() {
  return localStorage.removeItem(PERMISSION)
}

export function setButtons(buttons){
  const buttonsData = {buttons}
	return localStorage.setItem(BUTTONS, JSON.stringify(buttonsData))
}
export function getButtons(){
  const val = JSON.parse(localStorage.getItem(BUTTONS)|| '{}')
  return val.buttons
}
export function removeButtons() {
  return localStorage.removeItem(BUTTONS)
}

export function removeAllInfo() {
  removeButtons()
  removePermission()
  removeToken()
  removeUserInfo()
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/509327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【操作系统】进程调度

目录 调度的概念 调度目标 所有系统 批处理系统 交互式系统 实时系统 调度算法 非抢占式调度算法 先来先服务 最短作业优先 非抢占式优先级调度 抢占式调度算法 最短剩余时间优先 轮转调度 抢占式优先级调度 多级反馈队列 彩票调度 公平分享调度 调度的概念 进程是资源分配…

Windows Nvm安装

前言 在windows系统下安装的是nvm-windows&#xff0c;nvm只支持安装在在Linux和Mac系统下。之前在Linux上安装过&#xff0c;最近在Windows上安装&#xff0c;特记录一下。 下载 下载地址&#xff1a;传送门 安装 双击exe文件&#xff0c;选定安装路径&#xff0c;下一步…

在外SSH远程连接macOS服务器【cpolar内网穿透】

文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …

动态库和静态库的使用

一、什么是库&#xff1f; 库是一种可执行代码的二进制形式&#xff0c;可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码&#xff0c;相当于进行了加密&#xff0c;别人可以使用库&#xff0c;但是看不到库中的内容。 常见的库类型 共享库 静态库 动态库…

数据管理证书有哪些?DAMA-CDGA/CDGP含金量高

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

小度即将推出智能手机产品,醉翁之意意在何为?

5月8日&#xff0c;智哪儿从相关渠道获悉&#xff0c;小度即将于5月下旬发布首款智能手机产品。小度科技通过公开渠道确认了上述信息并透露将于下周披露更详细的产品信息。根据市场调查机构Counterpoint Research公布的最新报告&#xff0c;2023年第一季度全球智能手机市场出货…

巩飞:构建自治智能的数据库云管平台,加速国产数据库应用进程

导语 4月8日下午&#xff0c;为期两天的第十二届数据技术嘉年华&#xff08;DTC 2023&#xff09;在北京新云南皇冠假日酒店圆满落下帷幕。大会以“开源融合数字化——引领数据技术发展&#xff0c;释放数据要素价值”为主题&#xff0c;汇聚产学研各界精英到场交流。云和恩墨数…

什么是医学影像PACS系统?PACS系统功能有哪些?作用有哪些?对接哪些设备?业务流程是什么?

一、什么是医学影像PACS系统 PACS&#xff1a;为Picture Archive and CommunicationSystem的缩写&#xff0c;是图象归档和通讯系统。PACS系统应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声…

入门PyTorch的学习路线指南

PyTorch是目前最受欢迎的深度学习框架之一&#xff0c;它具有易于使用、灵活性强、支持动态图等优点&#xff0c;因此备受研究者和工程师的青睐。如果你想学习PyTorch&#xff0c;下面是一个入门PyTorch的学习路线。 学习基础知识&#xff1a; 学习Python编程语言&#xff1a;…

从入门到精通:教你如何使用Page Object模式提高WebUI自动化测试质量

目录 前言 什么是Page Object模式&#xff1f; 如何编写Page Object模式测试脚本&#xff1f; 步骤1&#xff1a;创建页面对象类 步骤2&#xff1a;编写测试用例 步骤3&#xff1a;运行测试用例 总结 前言 在进行Web应用程序开发的时候&#xff0c;我们经常需要进行自动…

前端工程化 搭建私有组件库 组件从开发到发布私有npm仓库的全过程

前言 基于Vue3.0 TS的组件从开发组件库到发布私有npm仓库的全过程 环境 这里列出本文所使用的环境版本 vue 3.0 vue/cli 4.5.9 nodeJs 14.15.1 npm 6.14.8 vue --version vue/cli 4.5.9 npm -v 6.14.8 node -v v14.15.1 步骤 创建项目 使用 vue-cli 创建一个 vue3 项目&a…

震坤行工业超市建设数字化采购供应链的实践

震坤行工业超市建设数字化采购供应链的实践 行业洞察&#xff1a; 【行业洞察】是震坤行工业超市新媒体推出的专注于行业思考主题栏目。 在这里&#xff0c;您可以收获&#xff1a;行业专家对于新理念、新模式、新技术的深度洞见&#xff0c;关于企业采购实操的干货分享。本…

OpenCL编程指南-1.1OpenCL简介

什么是OpenCL OpenCL是面向由CPU、GPU和其他处理器组合构成的计算机进行编程的行业标准框架。这些所谓的 “异构系统” 已经成为一类重要的平台&#xff0c;OpenCL是直接满足这些异构系统需求的第一个行业标准。OpenCL于2008年12月首次发布&#xff0c;早期产品则在2009年秋天…

数据可视化工具 - ECharts折线图的编写

1 官网找到类似实例&#xff0c; 适当分析&#xff0c;并且引入到HTML页面中 <!DOCTYPE html> <html> <head><meta charset"utf-8"/><title>ECharts</title><!-- 引入刚刚下载的 ECharts 文件 --><script src"ech…

HTML与JavaScript联动

目录 一、数组&#xff08;增删查改&#xff09; 1.创建数组 2. 增加数组元素 3.删除数组中的元素 4.查看数组元素 5.修改数组元素 二、创建方法 1.函数 2.作用域 3.作用域链 三、对象 1.使用 字面量 创建对象 [常用] 2.使用 new Object 创建对象 四、JavaScript…

thinkphp报错 in_array() expects parameter 2 to be array, object given

我的问题是 foreach ($books as $k > $v) { if (in_array($v[id], $book_id)) { //这个地方报错的 $books[$k][check] checked; }else { $books[$k][check] ; } } 这个问题是因为 你的变…

5.9-5.10学习总结

项目分析&#xff1a; 1.用户共有的&#xff1a; 登录&#xff0c;注册&#xff0c;忘记密码&#xff0c;个人资料&#xff0c;修改密码 个人资料&#xff1a;包括生日&#xff08;日期栏选择&#xff09;&#xff0c;手机号&#xff0c;邮箱&#xff0c;学号&#xff0c;姓…

网络路径下倾斜模型生产流程-空三计算,像控刺点

网络路径下倾斜模型生产流程-空三计算&#xff0c;像控刺点 1.新建工程 ①新建工程文件夹 确定本机的网络路径&#xff0c;如演示机为192.168.100.10 在网络路径下新建工程文件夹&#xff0c;如//192.168.100.10/e/YNPE27 在工程文件夹下&#xff0c;新建工程存储文件夹CC和照片…

docker安装与配置docker镜像加速器

文章目录 前言一、准备工作二、docker安装三、配置镜像加速器1.配置中科大镜像加速器2.配置阿里云镜像加速器 前言 我真的受不了虚拟机了&#xff0c;我电脑上有9个虚拟机&#xff0c;占了132G&#xff01;&#xff01;&#xff01;我还不敢随便删&#xff0c;怕到时候要用。。…

聚观早报 | 菜鸟回应明年赴港 IPO;谷歌即将发布最新 AI 大模型

今日要闻&#xff1a;菜鸟回应明年赴港 IPO&#xff1b;谷歌即将发布最新 AI 大模型&#xff1b;中国移动推出周杰伦数字人&#xff1b;“老头乐”销量冠军雷丁汽车申请破产&#xff1b;网信部门工作组进驻斗鱼平台 菜鸟回应明年赴港 IPO 近日&#xff0c;有消息称&#xff0c…