该模板是根据PanJiaChen大佬的vue-element-admin模板来修改的vue3+vite+element-plus+pinia版本,有需要可以去研究一下。
当前框架仓库:https://gitee.com/DianaYako/vue3-vite-element-plus-pinia
如果有与vue-element-admin模板功能差异、BUG、任何框架、模板上的BUG,欢迎与相关人员联系进行修复、填充,或者在相关仓库提issue。
npm install
OR npm i
npm run dev
- 对应变量文件:.env.development
npm run pro
- 对应变量文件:.env.production
npm run test
- 对应变量文件:.env.test
npm run build
【一般用来部署到最终环境并且是可生产版本】 - 对应变量文件:.env.production
npm run buildTest
【一般用来部署到测试服务器进行线上测试】 - 对应变量文件:.env.test
如果想要修改一些配置,例如隐藏tags-view
、左上角logo、面包屑导航等,可以进入该文件进行配置,该文件内有注释解释各个配置项的功能。
{
path: string // 必填 不用说
name: string // 必填 一定要填写 不然很多功能会出现问题,并且保持唯一 (注:父子路由之间,父级路由也必须填写路由【因为面包屑算法识别以及规范】)
component: Component // 必填
// ...等其他路由信息
// 框架衍生其他信息
meta: {
// 设置为 true 时,该路由不会出现在侧边栏导航,比如login、文章详情页等。
hidden: boolean // 默认 false
// 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
// 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
// 若你想不管路由下面的 children 声明的个数都显示你的根路由
// 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
alwaysShow: boolean // 默认 false 或者 undefined
title: string // 设置该路由在侧边栏和面包屑中展示的名字
icon: string // 设置该路由的图标,支持 svg-class,也支持 el-icon-x element-ui 的 icon
keepAlive: boolean, // 如果设置为true 则会对当前页面进行缓存
noCache: boolean // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)(用于tags-view)
breadcrumb: boolean // 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
affix: boolean // 如果设置为true,它则会固定在tags-view中(默认 false)
// 当路由设置了该属性,则会高亮相对应的侧边栏。
// 这在某些场景非常有用,比如:一个文章的列表页路由为:/article/list
// 点击文章进入文章详情页,这时候路由为/article/1,但你想在侧边栏高亮文章列表的路由,就可以进行如下设置
activeMenu: string
// 针对性缓存 -- 字符串数组(字符串为路由name)
// 在该数组内写入所要针对页面进行缓存的路由name
// 例子;A页面跳转B页面(name:BPAGE),A页面路由的meta.cacheToNames为['BPAGE']即可,这时A->B->A两次跳转后A页面的内容为缓存过的,不会变动,A->C->A会重新渲染,不进行缓存
// 注意:如果按照上述例子,假如A页面name为APAGE,需要在A页面的script标签内写入name,例如:<script setup lang="ts" name="APAGE">
cacheToNames: Array<string>
}
}
{
path: '/article',
component: Layout,
redirect: '/article',
name: 'Article',
meta: { title: '文章列表' },
children: [
{
path: '',
name: 'ArticleList',
component: () => import('@/views/article/index.vue'),
meta: { title: '文章列表' },
},
{
path: 'createOrUpdate',
name: 'ArticleCreateOrUpdate',
component: () => import('@/views/article/childs/create-or-update/index.vue'),
meta: { title: '新增/修改文章', hidden: true },
},
{
path: 'detail',
name: 'ArticleDetail',
component: () => import('@/views/article/childs/detail/index.vue'),
meta: { title: '文章详情', hidden: true },
}
]
}
{
path: '/article',
component: Layout,
redirect: '/article/list',
name: 'Article',
meta: { title: '文章列表', icon: 'Search' },
children: [
{
path: 'list',
name: 'ArticleList',
component: () => import('@/views/article/index.vue'),
meta: { title: '文章列表' },
},
{
path: 'detail',
name: 'ArticleDetail',
component: () => import('@/views/article/childs/detail/index.vue'),
meta: { title: '文章详情', hidden: true },
}
]
}
{
path: '/muti',
component: Layout,
redirect: '/muti/',
meta: { title: '多级导航', icon: 'User' },
children: [
{
path: 'article-list',
name: 'Article',
children: [
{
path: '',
name: 'ArticleList',
component: () => import('@/views/article/index.vue'),
meta: { title: '文章列表' },
},
{
path: 'createOrUpdate',
name: 'ArticleCreateOrUpdate',
component: () => import('@/views/article/childs/create-or-update/index.vue'),
meta: { title: '新增/修改文章', hidden: true },
},
{
path: 'detail',
name: 'ArticleDetail',
component: () => import('@/views/article/childs/detail/index.vue'),
meta: { title: '文章详情', hidden: true },
}
]
},
{
path: 'audit',
name: 'Audio',
meta: { title: '审核列表' },
children: [
{
path: '',
name: 'AuditList',
component: () => import('@/views/audit/index.vue'),
meta: { title: '审核列表' },
},
{
path: 'detail',
name: 'AuditDetail',
component: () => import('@/views/audit/childs/detail/index.vue'),
meta: { title: '审核详情', hidden: true },
}
]
},
{
path: 'user',
name: 'User',
meta: { title: '用户管理' },
children: [
{
path: 'user-school',
name: 'UserSchool',
meta: { title: '学校用户' },
children: [
{
path: 'user-school-teacher',
name: 'UserSchoolTeacher',
meta: { title: '教师列表' },
component: () => import('@/views/user/childs/school/childs/teacher/index.vue')
},
{
path: 'user-school-student',
name: 'UserSchoolStudent',
meta: { title: '学生列表' },
component: () => import('@/views/user/childs/school/childs/student/index.vue')
}
]
}
]
}
],
}
前端写路由的地方每个路由的meta参数中加一个id的唯一路由标识符,
前端用token来请求当前用户可以访问的页面的id(数组或者是树结构都可以),
然后前端在第一次进页面的时候进行获取一次这个id数组,然后进行通过这个id数组来判断要显示的路由目录,
路由的id不在这个id数组中的就是不显示(或者是直接不添加这个路由)
注:如果有父子目录,且父路由只有一个子路由,那么给予子路由id来判断即可,权限判断会判断当前目录下是否有有效菜单,没有则不显示。
相关写法
{
path: '/muti',
component: Layout,
redirect: '/muti/',
meta: { title: '多级导航', icon: 'User' },
children: [
{
path: 'article-list',
name: 'Article',
children: [
{
path: '',
name: 'ArticleList',
component: () => import('@/views/article/index.vue'),
meta: { title: '文章列表', id: 1 },
},
{
path: 'createOrUpdate',
name: 'ArticleCreateOrUpdate',
component: () => import('@/views/article/childs/create-or-update/index.vue'),
meta: { title: '新增/修改文章', hidden: true, id: 2 },
},
{
path: 'detail',
name: 'ArticleDetail',
component: () => import('@/views/article/childs/detail/index.vue'),
meta: { title: '文章详情', hidden: true, id: 3 },
}
]
},
{
path: 'audit',
name: 'Audio',
meta: { title: '审核列表' },
children: [
{
path: '',
name: 'AuditList',
component: () => import('@/views/audit/index.vue'),
meta: { title: '审核列表', id: 1 },
},
{
path: 'detail',
name: 'AuditDetail',
component: () => import('@/views/audit/childs/detail/index.vue'),
meta: { title: '审核详情', hidden: true, id: 2 },
}
]
}
],
}
上方实例,如果没有审核列表和文章列表的权限,那么整个多级导航的菜单则都不显示。
这个简单点说,就是给每个路由的meta中添加一个role属性,然后再获取登录用户信息时,会有一个当前登录人的角色信息,然后再动态添加路由时根据两者进行判断是否有权限即可。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。