目录
1.权限应用-拆分静态路由-动态路由
2.权限应用-根据用户权限添加动态路由
3.权限应用-根据权限显示左侧菜单
4.权限应用-退出登录重置路由
5.权限应用-功能权限-按钮权限标识
6.权限应用-自定义指令应用功能权限
7.其他模块-集成
8.首页-基本结构和数字滚动
9.首页-个人信息展示
10.首页-企业数据获取
11.首页-通知消息获取
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
import departmentRouter from './modules/department'
import approvalRouter from './modules/approval'
import attendanceRouter from './modules/attendance'
import employeeRouter from './modules/employee'
import permissionRouter from './modules/permission'
import roleRouter from './modules/role'
import salaryRouter from './modules/salary'
import socialRouter from './modules/social'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]
// 动态路由
export const asyncRoutes = [
departmentRouter,
roleRouter,
employeeRouter,
permissionRouter,
attendanceRouter,
approvalRouter,
salaryRouter,
socialRouter]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes // 默认引入静态路由
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
怎么匹配?
async getUserInfo(context) {
const result = await getUserInfo()
context.commit('setUserInfo', result)
return result // 返回数据
}
import router from '@/router'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store'
import { asyncRoutes } from '@/router'
/**
*前置守卫
*
*/
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
nprogress.start()
if (store.getters.token) {
// 存在token
if (to.path === '/login') {
// 跳转到主页
next('/') // 中转到主页
// next(地址)并没有执行后置守卫
nprogress.done()
} else {
// 判断是否获取过资料
if (!store.getters.userId) {
const { roles } = await store.dispatch('user/getUserInfo')
// console.log(roles.menus) // 数组 不确定 可能是8个 1个 0个
// console.log(asyncRoutes) // 数组 8个
const filterRoutes = asyncRoutes.filter(item => {
// return true/false
return roles.menus.includes(item.name)
}) // 筛选后的路由
router.addRoutes([...filterRoutes, { path: '*', redirect: '/404', hidden: true }]) // 添加动态路由信息到路由表
// router添加动态路由之后 需要转发一下
next(to.path) // 目的是让路由拥有信息 router的已知缺陷
} else {
next() // 放过
}
}
} else {
// 没有token
if (whiteList.includes(to.path)) {
next()
} else {
next('/login') // 中转到登录页
nprogress.done()
}
}
})
/** *
* 后置守卫
* **/
router.afterEach(() => {
console.log('123')
nprogress.done()
})
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
}
]
import { getToken, setToken, removeToken } from '@/utils/auth'
import { login, getUserInfo } from '@/api/user'
import { constantRoutes } from '@/router'
const state = {
token: getToken(), // 从缓存中读取初始值
userInfo: {}, // 存储用户基本资料状态
routes: constantRoutes // 静态路由的数组
}
const mutations = {
setToken(state, token) {
state.token = token
// 同步到缓存
setToken(token)
},
removeToken(state) {
// 删除Vuex的token
state.token = null
removeToken()
},
setUserInfo(state, userInfo) {
state.userInfo = userInfo
},
setRoutes(state, newRoutes) {
state.routes = [...constantRoutes, ...newRoutes] // 静态路由 + 动态路由
}
}
const actions = {
// context上下文,传入参数
async login(context, data) {
console.log(data)
// todo: 调用登录接口
const token = await login(data)
// 返回一个token 123456
context.commit('setToken', token)
},
// 获取用户的基本资料
async getUserInfo(context) {
const result = await getUserInfo()
context.commit('setUserInfo', result)
return result // 返回数据
},
// 退出登录的action
logout(context) {
context.commit('removeToken') // 删除token
context.commit('setUserInfo', {}) // 设置用户信息为空对象
}
}
export default {
namespaced: true, // 开启命名空间
state,
mutations,
actions
}
import router from '@/router'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store'
import { asyncRoutes } from '@/router'
/**
*前置守卫
*
*/
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
nprogress.start()
if (store.getters.token) {
// 存在token
if (to.path === '/login') {
// 跳转到主页
next('/') // 中转到主页
// next(地址)并没有执行后置守卫
nprogress.done()
} else {
// 判断是否获取过资料
if (!store.getters.userId) {
const { roles } = await store.dispatch('user/getUserInfo')
// console.log(roles.menus) // 数组 不确定 可能是8个 1个 0个
// console.log(asyncRoutes) // 数组 8个
const filterRoutes = asyncRoutes.filter(item => {
// return true/false
return roles.menus.includes(item.name)
}) // 筛选后的路由
store.commit('user/setRoutes', filterRoutes)
router.addRoutes([...filterRoutes, { path: '*', redirect: '/404', hidden: true }]) // 添加动态路由信息到路由表
// router添加动态路由之后 需要转发一下
next(to.path) // 目的是让路由拥有信息 router的已知缺陷
} else {
next() // 放过
}
}
} else {
// 没有token
if (whiteList.includes(to.path)) {
next()
} else {
next('/login') // 中转到登录页
nprogress.done()
}
}
})
/** *
* 后置守卫
* **/
router.afterEach(() => {
console.log('123')
nprogress.done()
})
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
userId: state => state.user.userInfo.userId,
avatar: state => state.user.userInfo.staffPhoto, // 头像
name: state => state.user.userInfo.username, // 用户名称
routes: state => state.user.routes
}
export default getters
export default {
components: { SidebarItem, Logo },
computed: {
...mapGetters([
'sidebar', 'routes'
]),
// 路由信息的计算属性
// routes() {
// // 返回所有的路由信息
// return this.$router.options.routes
// },
}
}
import { resetRouter } from '@/router'
// 退出登录的action
logout(context) {
context.commit('removeToken') // 删除token
context.commit('setUserInfo', {}) // 设置用户信息为空对象
// 重置路由
resetRouter()
}
// 封装自定义指令 用来控制操作权
Vue.directive('permission', {
// 会在指令作用的元素插入到页面完成以后触发
inserted(el, binding) {
// el 指令作用的元素的dom对象
console.log(el)
const points = store.state.user.userInfo?.roles?.points || [] // 当前用户信息的操作权
if (!points.includes(binding.value)) {
// 不存在就要删除或者禁用
el.remove() // 删除元素
// el.disabled = true
// 线上的权限数据和线下的代码进行对应
}
}
})
添加员工
素材中,已经给大家提供了 其他模块的请求/路由/组件,只需要拷贝到src即可
组织总人数
228
正式员工
334
合同待签署
345
待入职
890
本月待转正
117
本月待离职
234
接口总访问
789
快捷入口
假期审批
社保管理
角色管理
薪资设置
流程设置
社保申报数据
申报人数
223
待申报(人)
117
申报中(人)
167
已申报(人)
24
公积金申报数据
申报人数
335
待申报(人)
345
申报中(人)
109
已申报(人)
77
帮助链接
入门指南
在线帮助手册
联系技术支持
添加链接
通知公告
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
$ npm i vue-count-to
组织总人数
正式员工
合同待签署
待入职
本月待转正
本月待离职
接口总访问
快捷入口
假期审批
社保管理
角色管理
薪资设置
流程设置
社保申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
公积金申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
帮助链接
入门指南
在线帮助手册
联系技术支持
添加链接
通知公告
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
userId: state => state.user.userInfo.userId,
avatar: state => state.user.userInfo.staffPhoto, // 头像
name: state => state.user.userInfo.username, // 用户名称
routes: state => state.user.routes,
company: state => state.user.userInfo.company, // 公司名称
departmentName: state => state.user.userInfo.departmentName // 部门名称
}
export default getters
组织总人数
正式员工
合同待签署
待入职
本月待转正
本月待离职
接口总访问
快捷入口
假期审批
社保管理
角色管理
薪资设置
流程设置
社保申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
公积金申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
帮助链接
入门指南
在线帮助手册
联系技术支持
添加链接
通知公告
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
import request from '@/utils/request'
/**
* 获取首页数据
*
*/
export function getHomeData() {
return request({
url: '/home/data'
})
}
组织总人数
正式员工
合同待签署
待入职
本月待转正
本月待离职
接口总访问
快捷入口
假期审批
社保管理
角色管理
薪资设置
流程设置
社保申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
公积金申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
帮助链接
入门指南
在线帮助手册
联系技术支持
添加链接
通知公告
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
朱继柳 发布了
第1期“传智大讲堂”互动讨论获奖名单公布
2018-07-21 15:21:38
export function getMessageList() {
return request({
url: '/home/notice'
})
}
组织总人数
正式员工
合同待签署
待入职
本月待转正
本月待离职
接口总访问
快捷入口
假期审批
社保管理
角色管理
薪资设置
流程设置
社保申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
公积金申报数据
申报人数
待申报(人)
申报中(人)
已申报(人)
帮助链接
入门指南
在线帮助手册
联系技术支持
添加链接
通知公告
{{ item.notice }}
{{ item.createTime }}