├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html └── src ├── App.vue ├── components ├── Dashboard.vue └── LeftMenu.vue ├── css └── common.scss ├── main.js ├── router.js ├── store.js └── views ├── goods.vue ├── index.vue ├── member.vue └── orders.vue /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode 3 | .history/ 4 | node_modules/ 5 | dist/ 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | test/unit/coverage 10 | test/e2e/reports 11 | selenium-debug.log 12 | 13 | 14 | # Editor directories and files 15 | .idea 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-permission 2 | 此demo结合vuex实现动态路由表设置,核心方法为router.addRoutes。 3 | 可通过修改src/store文件中的permission属性来实现区分管理员权限和普通用户权限(1 为管理员权限,2 为角色权限),正常需要接口来返回相关数据,这里通过静态数据来实现。 4 | 5 | ## Project setup 6 | ``` 7 | npm install 8 | ``` 9 | 10 | ### Compiles and hot-reloads for development 11 | ``` 12 | npm run serve 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | ``` 17 | npm run build 18 | ``` 19 | ### Customize configuration 20 | See [Configuration Reference](https://cli.vuejs.org/config/). 21 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "vue": "^2.5.17", 11 | "vue-router": "^3.0.1", 12 | "vuex": "^3.0.1" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.2.0", 16 | "@vue/cli-service": "^3.2.0", 17 | "element-ui": "^2.4.11", 18 | "node-sass": "^4.9.0", 19 | "sass-loader": "^7.0.1", 20 | "vue-template-compiler": "^2.5.17" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzlu1004/vue_permission/11a747d853239f6ddb60f6d95ab8182028e4d096/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-permission 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/components/Dashboard.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 23 | 24 | 25 | 39 | -------------------------------------------------------------------------------- /src/components/LeftMenu.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /src/css/common.scss: -------------------------------------------------------------------------------- 1 | html,body{ 2 | height: 100%; 3 | margin: 0; 4 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import ElementUI from 'element-ui'; 6 | import 'element-ui/lib/theme-chalk/index.css'; 7 | import './css/common.scss'; 8 | Vue.use(ElementUI); 9 | 10 | Vue.config.productionTip = false 11 | // // 安全路由 12 | const nextRoute = ['service'] 13 | // 全局路由守卫 14 | router.beforeEach((to, from, next) => { 15 | if(store.getters.addRouters.length > 0){ 16 | next() 17 | }else{ 18 | let isAdmin = store.getters.permission 19 | store.dispatch('GenerateRoutes',isAdmin).then(res => { // 拉取service 20 | router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表 21 | next(to.path) 22 | }) 23 | } 24 | }); 25 | new Vue({ 26 | router, 27 | store, 28 | render: h => h(App) 29 | }).$mount('#app') 30 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use(Router) 5 | 6 | 7 | // 默认路由 8 | export const defalutRouter = [] 9 | 10 | // 管理员权限路由 11 | export const constantRouterMap = [ 12 | { 13 | path: '/', 14 | redirect: 'index', 15 | component: () => import('./components/Dashboard.vue'), 16 | children:[ 17 | { 18 | path: '/index', 19 | name: 'index', 20 | component: () => import('./views/index.vue') 21 | }, 22 | { 23 | path: '/goods', 24 | name: 'goods', 25 | component: () => import('./views/goods.vue') 26 | }, 27 | { 28 | path: '/member', 29 | name: 'member', 30 | component: () => import('./views/member.vue') 31 | }, 32 | { 33 | path: '/orders', 34 | name: 'orders', 35 | component: () => import('./views/orders.vue') 36 | } 37 | ] 38 | } 39 | ] 40 | 41 | // 角色权限路由 42 | export const asyncRouterMap = [ 43 | { 44 | path: '/', 45 | redirect: 'index', 46 | component: () => import('./components/Dashboard.vue'), 47 | children:[ 48 | { 49 | path: '/index', 50 | name: 'index', 51 | component: () => import('./views/index.vue') 52 | }, 53 | { 54 | path: '/member', 55 | name: 'member', 56 | component: () => import('./views/member.vue') 57 | }, 58 | ] 59 | } 60 | ] 61 | 62 | 63 | export default new Router({ 64 | linkActiveClass: 'linkclass', 65 | routes: defalutRouter 66 | }) 67 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import {constantRouterMap,asyncRouterMap} from './router' 4 | 5 | Vue.use(Vuex) 6 | 7 | 8 | 9 | // 获取异步路由表,返回符合用户开通服务的路由表 10 | function getAsyncRouterByService(data){ 11 | if(data == 1){ // 1 为管理员权限,2 为角色权限 12 | return constantRouterMap 13 | }else{ 14 | return asyncRouterMap 15 | } 16 | } 17 | 18 | export default new Vuex.Store({ 19 | state: { 20 | permission: 1, // 1 为管理员权限,2 为角色权限 21 | addRouters: [] 22 | }, 23 | mutations: { 24 | SET_ROUTERS: (state, routers) => { 25 | state.addRouters = routers 26 | } 27 | }, 28 | actions: { 29 | GenerateRoutes ({ commit }, data) { 30 | return new Promise(resolve => { 31 | let accessedRouters = getAsyncRouterByService(data) 32 | commit('SET_ROUTERS', accessedRouters) 33 | resolve() 34 | }) 35 | } 36 | }, 37 | getters: { 38 | permission: state => state.permission, 39 | addRouters: state => state.addRouters, 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /src/views/goods.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/member.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/orders.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | --------------------------------------------------------------------------------