├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── package.json
├── public
├── index.html
└── logo.ico
├── src
├── App.vue
├── assets
│ ├── 404_images
│ │ ├── 404.png
│ │ └── 404_cloud.png
│ └── logo.ico
├── components
│ ├── Dialog
│ │ └── index.vue
│ ├── Pagination
│ │ └── index.vue
│ ├── PowerWrapper
│ │ └── index.vue
│ ├── SvgIcon
│ │ └── index.vue
│ └── UploadImg
│ │ ├── UploadImg.vue
│ │ └── lib
│ │ └── crypto1
│ │ ├── crypto
│ │ ├── crypto-min.js
│ │ └── crypto.js
│ │ ├── hmac
│ │ ├── hmac-min.js
│ │ └── hmac.js
│ │ └── sha1
│ │ ├── sha1-min.js
│ │ └── sha1.js
├── icons
│ ├── index.js
│ └── svg
│ │ ├── suger.svg
│ │ └── yueliang.svg
├── main.js
├── permission.js
├── router
│ ├── asyncRoutes.js
│ └── index.js
├── services
│ └── user.js
├── store.js
├── styles
│ ├── base.less
│ ├── element-ui.less
│ ├── iconfont.less
│ └── index.less
├── utils
│ ├── auth.js
│ ├── get-page-title.js
│ ├── request.js
│ └── utils.js
└── views
│ ├── Layout
│ ├── SidebarItem
│ │ └── index.vue
│ ├── appMain
│ │ └── index.vue
│ └── index.vue
│ ├── Login.vue
│ ├── UserRelation
│ └── UserRelation.vue
│ ├── error-page
│ └── 404.vue
│ ├── navigatorOne
│ ├── itemOne
│ │ └── itemOne.vue
│ ├── itemThree
│ │ └── itemThree.vue
│ └── itemTwo
│ │ └── itemTwo.vue
│ └── navigatorTwo
│ ├── CommonInvite
│ └── index.vue
│ ├── itemFour
│ └── itemFour.vue
│ ├── itemOne
│ └── itemOne.vue
│ ├── itemThree
│ └── itemThree.vue
│ └── itemTwo
│ └── itemTwo.vue
└── vue.config.js
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | browser: true,
5 | node: true,
6 | },
7 | extends: [
8 | 'plugin:vue/essential',
9 | // '@vue/airbnb',
10 | ],
11 | rules: {
12 | 'no-console': 0,
13 | 'linebreak-style': 0,
14 | 'comma-dangle':0,
15 | "indent": 0,
16 | "semi":0,
17 | "space-infix-ops":0,
18 | "no-mixed-operators":0,
19 | "no-trailing-spaces":0,
20 | "no-multi-spaces":0,
21 | "no-else-return": 0
22 | },
23 | // parserOptions: {
24 | // parser: 'babel-eslint',
25 | // }
26 | };
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | package-lock.json
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw?
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### vue-element-admin-template
2 |
3 | #### 包含权限管理
4 |
5 | ##### 登录 用户名 admin 密码 123
6 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-element-admin-template",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^0.19.0",
12 | "core-js": "^3.3.2",
13 | "element-ui": "^2.12.0",
14 | "js-base64": "^2.5.1",
15 | "js-cookie": "^2.2.1",
16 | "less": "^3.10.3",
17 | "moment": "^2.24.0",
18 | "nprogress": "^0.2.0",
19 | "qrcode.vue": "^1.7.0",
20 | "qs": "^6.9.1",
21 | "vue": "^2.6.10",
22 | "vue-router": "^3.1.3",
23 | "vuex": "^3.1.2"
24 | },
25 | "devDependencies": {
26 | "@vue/cli-plugin-babel": "^4.0.0",
27 | "@vue/cli-plugin-eslint": "^4.0.0",
28 | "@vue/cli-service": "^4.0.0",
29 | "babel-eslint": "^10.0.3",
30 | "eslint": "^5.16.0",
31 | "eslint-plugin-vue": "^5.0.0",
32 | "less-loader": "^5.0.0",
33 | "svg-sprite-loader": "^5.0.0",
34 | "vue-template-compiler": "^2.6.10"
35 | },
36 | "eslintConfig": {
37 | "root": true,
38 | "env": {
39 | "node": true
40 | },
41 | "extends": [
42 | "plugin:vue/essential",
43 | "eslint:recommended"
44 | ],
45 | "rules": {},
46 | "parserOptions": {
47 | "parser": "babel-eslint"
48 | }
49 | },
50 | "postcss": {
51 | "plugins": {
52 | "autoprefixer": {}
53 | }
54 | },
55 | "browserslist": [
56 | "> 1%",
57 | "last 2 versions"
58 | ]
59 | }
60 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | vue-admin-start
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tang-yue/vue-element-admin-template/715eb4a8d163ee169714d3cd91f191f48039472c/public/logo.ico
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
16 |
17 |
31 |
--------------------------------------------------------------------------------
/src/assets/404_images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tang-yue/vue-element-admin-template/715eb4a8d163ee169714d3cd91f191f48039472c/src/assets/404_images/404.png
--------------------------------------------------------------------------------
/src/assets/404_images/404_cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tang-yue/vue-element-admin-template/715eb4a8d163ee169714d3cd91f191f48039472c/src/assets/404_images/404_cloud.png
--------------------------------------------------------------------------------
/src/assets/logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tang-yue/vue-element-admin-template/715eb4a8d163ee169714d3cd91f191f48039472c/src/assets/logo.ico
--------------------------------------------------------------------------------
/src/components/Dialog/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
62 |
63 |
--------------------------------------------------------------------------------
/src/components/Pagination/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
81 |
82 |
91 |
--------------------------------------------------------------------------------
/src/components/PowerWrapper/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
抱歉,你没有权限访问
7 |
8 |
9 |
10 |
11 |
27 |
28 |
31 |
--------------------------------------------------------------------------------
/src/components/SvgIcon/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
25 |
26 |
42 |
--------------------------------------------------------------------------------
/src/components/UploadImg/UploadImg.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
81 |
82 |
85 |
--------------------------------------------------------------------------------
/src/components/UploadImg/lib/crypto1/crypto/crypto-min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Crypto-JS v1.1.0
3 | * http://code.google.com/p/crypto-js/
4 | * Copyright (c) 2009, Jeff Mott. All rights reserved.
5 | * http://code.google.com/p/crypto-js/wiki/License
6 | */
7 | (function(){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";window.Crypto={};var a=Crypto.util={rotl:function(d,c){return(d<>>(32-c))},rotr:function(d,c){return(d<<(32-c))|(d>>>c)},endian:function(d){if(d.constructor==Number){return a.rotl(d,8)&16711935|a.rotl(d,24)&4278255360}for(var c=0;c0;d--){c.push(Math.floor(Math.random()*256))}return c},stringToBytes:function(e){var c=[];for(var d=0;d>>5]|=f.charCodeAt(g)<<(24-d%32)}return e},bytesToWords:function(d){var f=[];for(var e=0,c=0;e>>5]|=d[e]<<(24-c%32)}return f},wordsToBytes:function(e){var d=[];for(var c=0;c>>5]>>>(24-c%32))&255)}return d},bytesToHex:function(c){var e=[];for(var d=0;d>>4).toString(16));e.push((c[d]&15).toString(16))}return e.join("")},hexToBytes:function(e){var d=[];for(var f=0;f>>2));f=(d[e]&3)<<4;break;case 1:c.push(b.charAt(f|(d[e]>>>4)));f=(d[e]&15)<<2;break;case 2:c.push(b.charAt(f|(d[e]>>>6)));c.push(b.charAt(d[e]&63));f=-1}}if(f!=undefined&&f!=-1){c.push(b.charAt(f))}while(c.length%4!=0){c.push("=")}return c.join("")},base64ToBytes:function(d){if(typeof atob=="function"){return a.stringToBytes(atob(d))}d=d.replace(/[^A-Z0-9+\/]/ig,"");var c=[];for(var e=0;e>>4));break;case 2:c.push(((b.indexOf(d.charAt(e-1))&15)<<4)|(b.indexOf(d.charAt(e))>>>2));break;case 3:c.push(((b.indexOf(d.charAt(e-1))&3)<<6)|(b.indexOf(d.charAt(e))));break}}return c}};Crypto.mode={}})();
--------------------------------------------------------------------------------
/src/components/UploadImg/lib/crypto1/crypto/crypto.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Crypto-JS v1.1.0
3 | * http://code.google.com/p/crypto-js/
4 | * Copyright (c) 2009, Jeff Mott. All rights reserved.
5 | * http://code.google.com/p/crypto-js/wiki/License
6 | */
7 | (function(){
8 |
9 | var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10 |
11 | // Global Crypto object
12 | window.Crypto = {};
13 |
14 | // Crypto utilities
15 | var util = Crypto.util = {
16 |
17 | // Bit-wise rotate left
18 | rotl: function (n, b) {
19 | return (n << b) | (n >>> (32 - b));
20 | },
21 |
22 | // Bit-wise rotate right
23 | rotr: function (n, b) {
24 | return (n << (32 - b)) | (n >>> b);
25 | },
26 |
27 | // Swap big-endian to little-endian and vice versa
28 | endian: function (n) {
29 |
30 | // If number given, swap endian
31 | if (n.constructor === Number) {
32 | return util.rotl(n, 8) & 0x00FF00FF |
33 | util.rotl(n, 24) & 0xFF00FF00;
34 | }
35 |
36 | // Else, assume array and swap all items
37 | for (var i = 0; i < n.length; i++)
38 | n[i] = util.endian(n[i]);
39 | return n;
40 |
41 | },
42 |
43 | // Generate an array of any length of random bytes
44 | randomBytes: function (n) {
45 | for (var bytes = []; n > 0; n--)
46 | bytes.push(Math.floor(Math.random() * 256));
47 | return bytes;
48 | },
49 |
50 | // Convert a string to a byte array
51 | stringToBytes: function (str) {
52 | var bytes = [];
53 | for (var i = 0; i < str.length; i++)
54 | bytes.push(str.charCodeAt(i));
55 | return bytes;
56 | },
57 |
58 | // Convert a byte array to a string
59 | bytesToString: function (bytes) {
60 | var str = [];
61 | for (var i = 0; i < bytes.length; i++)
62 | str.push(String.fromCharCode(bytes[i]));
63 | return str.join("");
64 | },
65 |
66 | // Convert a string to big-endian 32-bit words
67 | stringToWords: function (str) {
68 | var words = [];
69 | for (var c = 0, b = 0; c < str.length; c++, b += 8)
70 | words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
71 | return words;
72 | },
73 |
74 | // Convert a byte array to big-endian 32-bits words
75 | bytesToWords: function (bytes) {
76 | var words = [];
77 | for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
78 | words[b >>> 5] |= bytes[i] << (24 - b % 32);
79 | return words;
80 | },
81 |
82 | // Convert big-endian 32-bit words to a byte array
83 | wordsToBytes: function (words) {
84 | var bytes = [];
85 | for (var b = 0; b < words.length * 32; b += 8)
86 | bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
87 | return bytes;
88 | },
89 |
90 | // Convert a byte array to a hex string
91 | bytesToHex: function (bytes) {
92 | var hex = [];
93 | for (var i = 0; i < bytes.length; i++) {
94 | hex.push((bytes[i] >>> 4).toString(16));
95 | hex.push((bytes[i] & 0xF).toString(16));
96 | }
97 | return hex.join("");
98 | },
99 |
100 | // Convert a hex string to a byte array
101 | hexToBytes: function (hex) {
102 | var bytes = [];
103 | for (var c = 0; c < hex.length; c += 2)
104 | bytes.push(parseInt(hex.substr(c, 2), 16));
105 | return bytes;
106 | },
107 |
108 | // Convert a byte array to a base-64 string
109 | bytesToBase64: function (bytes) {
110 |
111 | // Use browser-native function if it exists
112 | if (typeof btoa === "function") return btoa(util.bytesToString(bytes));
113 |
114 | var base64 = [],
115 | overflow;
116 |
117 | for (var i = 0; i < bytes.length; i++) {
118 | // eslint-disable-next-line
119 | switch (i % 3) {
120 | case 0:
121 | base64.push(base64map.charAt(bytes[i] >>> 2));
122 | overflow = (bytes[i] & 0x3) << 4;
123 | break;
124 | case 1:
125 | base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));
126 | overflow = (bytes[i] & 0xF) << 2;
127 | break;
128 | case 2:
129 | base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));
130 | base64.push(base64map.charAt(bytes[i] & 0x3F));
131 | overflow = -1;
132 | }
133 | }
134 |
135 | // Encode overflow bits, if there are any
136 | if (overflow !== undefined && overflow !== -1)
137 | base64.push(base64map.charAt(overflow));
138 |
139 | // Add padding
140 | while (base64.length % 4 !== 0) base64.push("=");
141 |
142 | return base64.join("");
143 |
144 | },
145 |
146 | // Convert a base-64 string to a byte array
147 | base64ToBytes: function (base64) {
148 |
149 | // Use browser-native function if it exists
150 | if (typeof atob === "function") return util.stringToBytes(atob(base64));
151 |
152 | // Remove non-base-64 characters
153 | base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
154 |
155 | var bytes = [];
156 |
157 | for (var i = 0; i < base64.length; i++) {
158 | // eslint-disable-next-line
159 | switch(i%4) {
160 | case 1:
161 | bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |
162 | (base64map.indexOf(base64.charAt(i)) >>> 4));
163 | break;
164 | case 2:
165 | bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |
166 | (base64map.indexOf(base64.charAt(i)) >>> 2));
167 | break;
168 | case 3:
169 | bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |
170 | (base64map.indexOf(base64.charAt(i))));
171 | break;
172 | }
173 | }
174 |
175 | return bytes;
176 |
177 | }
178 |
179 | };
180 |
181 | // Crypto mode namespace
182 | Crypto.mode = {};
183 |
184 | })();
185 |
--------------------------------------------------------------------------------
/src/components/UploadImg/lib/crypto1/hmac/hmac-min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Crypto-JS v1.1.0
3 | * http://code.google.com/p/crypto-js/
4 | * Copyright (c) 2009, Jeff Mott. All rights reserved.
5 | * http://code.google.com/p/crypto-js/wiki/License
6 | */
7 | (function(){var a=Crypto.util;Crypto.HMAC=function(g,h,f,d){f=f.length>g._blocksize*4?g(f,{asBytes:true}):a.stringToBytes(f);var c=f,j=f.slice(0);for(var e=0;e hasher._blocksize * 4 ?
16 | hasher(key, { asBytes: true }) :
17 | util.stringToBytes(key);
18 |
19 | // XOR keys with pad constants
20 | var okey = key,
21 | ikey = key.slice(0);
22 | for (var i = 0; i < hasher._blocksize * 4; i++) {
23 | okey[i] ^= 0x5C;
24 | ikey[i] ^= 0x36;
25 | }
26 |
27 | var hmacbytes = hasher(util.bytesToString(okey) +
28 | hasher(util.bytesToString(ikey) + message, { asString: true }),
29 | { asBytes: true });
30 | return options && options.asBytes ? hmacbytes :
31 | options && options.asString ? util.bytesToString(hmacbytes) :
32 | util.bytesToHex(hmacbytes);
33 |
34 | };
35 |
36 | })();
37 |
--------------------------------------------------------------------------------
/src/components/UploadImg/lib/crypto1/sha1/sha1-min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Crypto-JS v1.1.0
3 | * http://code.google.com/p/crypto-js/
4 | * Copyright (c) 2009, Jeff Mott. All rights reserved.
5 | * http://code.google.com/p/crypto-js/wiki/License
6 | */
7 | (function(){var a=Crypto.util;var b=Crypto.SHA1=function(e,c){var d=a.wordsToBytes(b._sha1(e));return c&&c.asBytes?d:c&&c.asString?a.bytesToString(d):a.bytesToHex(d)};b._sha1=function(k){var u=a.stringToWords(k),v=k.length*8,o=[],q=1732584193,p=-271733879,h=-1732584194,g=271733878,f=-1009589776;u[v>>5]|=128<<(24-v%32);u[((v+64>>>9)<<4)+15]=v;for(var y=0;y>>31)}var r=((q<<5)|(q>>>27))+f+(o[x]>>>0)+(x<20?(p&h|~p&g)+1518500249:x<40?(p^h^g)+1859775393:x<60?(p&h|p&g|h&g)-1894007588:(p^h^g)-899497514);f=g;g=h;h=(p<<30)|(p>>>2);p=q;q=r}q+=D;p+=C;h+=B;g+=A;f+=z}return[q,p,h,g,f]};b._blocksize=16})();
--------------------------------------------------------------------------------
/src/components/UploadImg/lib/crypto1/sha1/sha1.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Crypto-JS v1.1.0
3 | * http://code.google.com/p/crypto-js/
4 | * Copyright (c) 2009, Jeff Mott. All rights reserved.
5 | * http://code.google.com/p/crypto-js/wiki/License
6 | */
7 | (function(){
8 |
9 | // Shortcut
10 | var util = Crypto.util;
11 |
12 | // Public API
13 | var SHA1 = Crypto.SHA1 = function (message, options) {
14 | var digestbytes = util.wordsToBytes(SHA1._sha1(message));
15 | return options && options.asBytes ? digestbytes :
16 | options && options.asString ? util.bytesToString(digestbytes) :
17 | util.bytesToHex(digestbytes);
18 | };
19 |
20 | // The core
21 | SHA1._sha1 = function (message) {
22 |
23 | var m = util.stringToWords(message),
24 | l = message.length * 8,
25 | w = [],
26 | H0 = 1732584193,
27 | H1 = -271733879,
28 | H2 = -1732584194,
29 | H3 = 271733878,
30 | H4 = -1009589776;
31 |
32 | // Padding
33 | m[l >> 5] |= 0x80 << (24 - l % 32);
34 | m[((l + 64 >>> 9) << 4) + 15] = l;
35 |
36 | for (var i = 0; i < m.length; i += 16) {
37 |
38 | var a = H0,
39 | b = H1,
40 | c = H2,
41 | d = H3,
42 | e = H4;
43 |
44 | for (var j = 0; j < 80; j++) {
45 |
46 | if (j < 16) w[j] = m[i + j];
47 | else {
48 | var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
49 | w[j] = (n << 1) | (n >>> 31);
50 | }
51 |
52 | var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
53 | j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
54 | j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
55 | j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
56 | (H1 ^ H2 ^ H3) - 899497514);
57 |
58 | H4 = H3;
59 | H3 = H2;
60 | H2 = (H1 << 30) | (H1 >>> 2);
61 | H1 = H0;
62 | H0 = t;
63 |
64 | }
65 |
66 | H0 += a;
67 | H1 += b;
68 | H2 += c;
69 | H3 += d;
70 | H4 += e;
71 |
72 | }
73 |
74 | return [H0, H1, H2, H3, H4];
75 |
76 | };
77 |
78 | // Package private blocksize
79 | SHA1._blocksize = 16;
80 |
81 | })();
82 |
--------------------------------------------------------------------------------
/src/icons/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import SvgIcon from '@/components/SvgIcon' // svg component
3 |
4 | // register globally
5 | Vue.component('svg-icon', SvgIcon)
6 |
7 | const req = require.context('../icons/svg', false, /\.svg$/)
8 | const requireAll = requireContext => requireContext.keys().map(requireContext)
9 | requireAll(req)
10 |
--------------------------------------------------------------------------------
/src/icons/svg/suger.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/icons/svg/yueliang.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import ElementUI from 'element-ui';
3 | import 'element-ui/lib/theme-chalk/index.css';
4 | import App from './App'
5 | import router from './router/index'
6 | import store from './store'
7 | import '@/styles/base.less'
8 | import '@/styles/element-ui.less'
9 | import '@/styles/iconfont.less'
10 | import '@/styles/index.less' // global css
11 | import './permission'
12 | import './icons/index'
13 |
14 | Vue.use(ElementUI);
15 |
16 | Vue.config.productionTip = false
17 |
18 | new Vue({
19 | render: h => h(App),
20 | router,
21 | store
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/src/permission.js:
--------------------------------------------------------------------------------
1 | import router from '@/router'
2 | import store from './store'
3 | import { Message } from 'element-ui'
4 | import NProgress from 'nprogress'
5 | import 'nprogress/nprogress.css'
6 | import { getToken } from '@/utils/auth'
7 | import getPageTitle from '@/utils/get-page-title'
8 | import path from 'path'
9 |
10 | NProgress.configure({ showSpinner: false })
11 |
12 | function getRoutePath(routes, _path) {
13 | var routerPath = ''
14 | routes.some((item) => {
15 | if (!item.hidden) {
16 | routerPath = _path ? path.resolve(_path, item.path) : item.path
17 | if (item.children) {
18 | routerPath = getRoutePath(item.children, routerPath)
19 | }
20 | return true
21 | }
22 | })
23 | return routerPath
24 | }
25 |
26 | router.beforeEach(async (to, from, next) => {
27 | NProgress.start()
28 | document.title = to.meta.title ? getPageTitle(to.meta.title) : getPageTitle(to.name);
29 | const hasToken = getToken()
30 | if (hasToken) {
31 | if (to.path === '/login') {
32 | next({ path: '/' })
33 | NProgress.done()
34 | } else {
35 | const hasRoles = store.state.roles && store.state.roles.length > 0
36 | if (hasRoles) {
37 | next()
38 | } else {
39 | try {
40 | store.dispatch('getInfo').then(roles => {
41 | // 根据roles 动态处理路由
42 | console.log('执行了吗?')
43 | store.dispatch('handleRoutes', { roles: roles }).then(() => {
44 | router.addRoutes(store.getters.addRouters)
45 | // 重定向到有权限的第一个菜单栏路由
46 | const authRouters = store.getters.addRouters
47 | if (to.path === '/') {
48 | const nextRoutePath = getRoutePath(authRouters)
49 | next({ path: nextRoutePath, replace: true })
50 | } else {
51 | next({ ...to, replace: true })
52 | }
53 | })
54 | })
55 | } catch (error) {
56 | await store.dispatch('resetToken')
57 | Message.error(error || 'Has Error')
58 | next(`/login?redirect=${to.path}`)
59 | NProgress.done()
60 | }
61 | }
62 | }
63 | } else {
64 | if (to.path === '/login') {
65 | next()
66 | } else {
67 | next({ path: `/login?redirect=${to.path}` })
68 | NProgress.done()
69 | }
70 | }
71 | })
72 |
73 | router.afterEach(() => {
74 | NProgress.done()
75 | })
76 |
--------------------------------------------------------------------------------
/src/router/asyncRoutes.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Layout from '@/views/Layout'
4 | import Login from '@/views/Login'
5 | // 共同拥有部分, 不需要任何的权限
6 | // 404 页面
7 | import errorPage from '@/views/error-page/404'
8 |
9 | import navigatorOneThree from '@/views/navigatorOne/itemThree/itemThree'
10 | import navigatorOneTwo from '@/views/navigatorOne/itemTwo/itemTwo'
11 | import navigatorOneOne from '@/views/navigatorOne/itemOne/itemOne'
12 | import Common from '@/views/navigatorTwo/CommonInvite'
13 |
14 | import navigatorTwoOne from '@/views/navigatorTwo/itemOne/itemOne'
15 | import navigatorTwoTwo from '@/views/navigatorTwo/itemTwo/itemTwo'
16 | import navigatorTwoThree from '@/views/navigatorTwo/itemThree/itemThree'
17 | import navigatorTwoFour from '@/views/navigatorTwo/itemFour/itemFour'
18 |
19 | export const asyncRoutes = [
20 | {
21 | path: '/navigatorOne',
22 | name: 'one',
23 | component: Layout,
24 | redirect: '/navigatorOne/itemOne',
25 | meta: {
26 | icon: 'icon-suger',
27 | title: 'navigatorOne'
28 | },
29 | children: [
30 | {
31 | name: '1-itemOne',
32 | path: 'itemOne',
33 | component: navigatorOneOne,
34 | meta: {
35 | title: 'item one',
36 | // codes: ['item-one']
37 | }
38 | },
39 | {
40 | name: '1-itemTwo',
41 | path: 'itemTwo',
42 | component: navigatorOneTwo,
43 | meta: {
44 | title: 'item two',
45 | codes: ['item-two'] // 无权限
46 | }
47 | },
48 | {
49 | name: '1-itemThree',
50 | path: 'itemThree',
51 | component: navigatorOneThree,
52 | meta: {
53 | title: 'itme three',
54 | codes: ['item-three'] // 无权限
55 | }
56 | }
57 | ]
58 | },
59 | {
60 | path: '/navigatorTwo',
61 | name: 'two',
62 | component: Layout,
63 | redirect: '/navigatorTwo/itemOne',
64 | meta: {
65 | icon: 'icon-yueliang',
66 | title: 'navigatorTwo'
67 | },
68 | // hidden: true,
69 | children: [
70 | {
71 | path: 'itemOne',
72 | component: navigatorTwoOne,
73 | meta: {
74 | title: 'example',
75 | codes: ['item-one']
76 | }
77 | },
78 | {
79 | path: 'itemTwo',
80 | name: 'itemTwo',
81 | component: Common,
82 | meta: {
83 | title: 'item two',
84 | },
85 | children: [
86 | {
87 | path: 'table1',
88 | name: 'table1',
89 | component: navigatorTwoOne,
90 | meta: {
91 | title: 'table1'
92 | }
93 | },
94 | {
95 | path: 'table2',
96 | name: 'table2',
97 | component: navigatorTwoTwo,
98 | meta: {
99 | title: 'table2',
100 | }
101 | },
102 | {
103 | name: 'two/id',
104 | path: 'two/:id',
105 | component: navigatorTwoThree,
106 | hidden: true,
107 | meta: {
108 | activeMenu: '/navigatorTwo/itemTwo/table2'
109 | }
110 | },
111 | ]
112 | },
113 | {
114 | path: 'itemThree',
115 | component: navigatorTwoThree,
116 | meta: {
117 | title: 'item three',
118 | }
119 | },
120 | {
121 | path: 'itemFour',
122 | component: navigatorTwoFour,
123 | meta: {
124 | title: 'item four',
125 | }
126 | },
127 | ]
128 | },
129 | {
130 | path: '*',
131 | name: '404',
132 | component: errorPage,
133 | hidden: true
134 | }
135 | ]
136 |
137 |
138 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Layout from '@/views/Layout'
4 | import Login from '@/views/Login'
5 |
6 | Vue.use(Router)
7 |
8 | export const fixedRoutes = [
9 | {
10 | path: '/',
11 | name: 'home',
12 | component: Layout,
13 | hidden: true
14 | },
15 | {
16 | path: '/login',
17 | name: 'Login',
18 | component: Login,
19 | hidden: true
20 | }
21 | ]
22 |
23 | const createRouter = () => new Router({
24 | mode: 'history',
25 | base: '/vue-element-admin-template',
26 | scrollBehavior: () => ({ y: 0 }),
27 | routes: fixedRoutes
28 | })
29 |
30 | const router = createRouter()
31 |
32 | export default router
33 |
--------------------------------------------------------------------------------
/src/services/user.js:
--------------------------------------------------------------------------------
1 | import request from '../utils/request';
2 | import { commonConfig } from '../utils/utils'
3 |
4 |
5 | export async function getInfo() {
6 | return request(`${commonConfig.apiUrl}/xxxxx`);
7 | }
8 |
9 | export async function login(params) {
10 | return request(`${commonConfig.apiUrl}/xxxx/xxx`, params);
11 | }
12 |
13 | export async function savePassword(params) {
14 | return request(`${commonConfig.apiUrl}/xxxx/xxxx`, params);
15 | }
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import { fixedRoutes } from '@/router'
4 | import { asyncRoutes } from '@/router/asyncRoutes'
5 | // import { getInfor } from '@/services/user'
6 | import {
7 | removeToken
8 | } from '@/utils/auth'
9 |
10 | Vue.use(Vuex)
11 |
12 | function hasPermission (roles, route) {
13 | if (route.meta && route.meta.codes) {
14 | return roles.some(role => route.meta.codes.includes(role))
15 | } else {
16 | return true
17 | }
18 | }
19 |
20 | function filterAsyncRoutes(routes, roles) {
21 | const res = []
22 | routes.forEach(route => {
23 | const tmp = { ...route }
24 | if (hasPermission(roles, tmp)) {
25 | if (tmp.children) {
26 | tmp.children = filterAsyncRoutes(tmp.children, roles)
27 | }
28 | res.push(tmp)
29 | }
30 | })
31 | return res
32 | }
33 |
34 | const store = new Vuex.Store({
35 | state: {
36 | roles: [],
37 | name: '',
38 | routes: fixedRoutes,
39 | uploadImages: {},
40 | addRouters: [],
41 | user: { username: 'admin' }
42 | },
43 | mutations: {
44 | SET_TOKEN: (state, token) => {
45 | state.token = token
46 | },
47 | SET_USER: (state, user) => {
48 | state.user = user
49 | },
50 | SET_ROLES: (state, roles) => {
51 | state.roles = roles
52 | },
53 | SET_UPLOAD_IMG: (state, images) => {
54 | state.uploadImages = { ...state.uploadImages, ...images }
55 | },
56 | REMOVE_UPLOAD_IMG: (state) => {
57 | state.uploadImages = {}
58 | },
59 | SET_ROUTES: (state, routes) => {
60 | state.addRouters = routes
61 | state.routes = fixedRoutes.concat(routes)
62 | }
63 | },
64 | // 下面这两个都是全局的
65 | actions: {
66 | getInfo ({ commit, state }) {
67 | return new Promise((resolve) => {
68 | // getInfor(state.token).then(response => {
69 | // if (response.data && response.data.errCode === 0) {
70 | // const result = response.data.data
71 | // const { permissionCodeList, userVo } = result
72 | // commit('SET_USER', userVo)
73 | const permissionCodeList = ['item-one']
74 | commit('SET_ROLES', permissionCodeList)
75 | resolve(permissionCodeList)
76 | // } else {
77 | // removeToken()
78 | // window.location.href = window.location.origin + '/vue-element-admin/login'
79 | // }
80 | // })
81 | })
82 | },
83 | handleRoutes ({ commit }, { roles }) {
84 | return new Promise((resolve) => {
85 | let accessedRoutes = []
86 | accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
87 | // 再次筛选最外层如果存在children, 但是children 为空数组,那么也要从里面剔除掉,(只遍历一遍)
88 | const new_accessedRoutes = []
89 | accessedRoutes.map((item) => {
90 | if (item.children && item.children.length === 0) {
91 | // delete item.children
92 | } else {
93 | new_accessedRoutes.push(item)
94 | }
95 | })
96 | commit('SET_ROUTES', new_accessedRoutes)
97 | resolve()
98 | })
99 | },
100 | resetToken ({ commit }) {
101 | return new Promise(resolve => {
102 | commit('SET_TOKEN', '')
103 | commit('SET_ROLES', [])
104 | removeToken()
105 | resolve()
106 | })
107 | },
108 | addUplaodImages ({ commit }, imgUrlObj) {
109 | return new Promise((resolve) => {
110 | commit('SET_UPLOAD_IMG', imgUrlObj)
111 | resolve()
112 | })
113 | },
114 | removeUploadImages ({ commit }) {
115 | return new Promise((resolve) => {
116 | commit('REMOVE_UPLOAD_IMG')
117 | resolve()
118 | })
119 | }
120 | },
121 | getters: {
122 | roles: state => state.roles,
123 | name: state => state.name,
124 | routesConfig: state => state.routes,
125 | uploadImages: state => state.uploadImages,
126 | addRouters: state => state.addRouters
127 | }
128 | })
129 |
130 | export default store
131 |
--------------------------------------------------------------------------------
/src/styles/base.less:
--------------------------------------------------------------------------------
1 | em, i, strong {
2 | font-weight: 400;
3 | }
4 | a {
5 | text-decoration: none;
6 | list-style: none;
7 | }
8 | h1, h2, h3, h4, h5, h6, p {
9 | margin: 0;
10 | padding: 0;
11 | }
12 | h3 {
13 | font-size: 18px;
14 | }
--------------------------------------------------------------------------------
/src/styles/element-ui.less:
--------------------------------------------------------------------------------
1 | // cover some element-ui styles
2 |
3 | .el-button, .el-input__inner {
4 | height: 32px;
5 | line-height: 32px;
6 | }
7 | .el-input__inner {
8 | height: 32px;
9 | line-height: 32px;
10 | }
11 | .el-button {
12 | padding: 0 20px;
13 | }
14 | .el-button.is-round {
15 | padding: 0 20px;
16 | }
17 |
18 | .el-table td, .el-table th {
19 | text-align: center;
20 | }
21 |
22 | .el-table td, .el-table th {
23 | padding: 8px 0;
24 | }
25 |
26 | .el-form-item__label {
27 | line-height: 40px;
28 | }
29 |
30 | .el-submenu__icon-arrow {
31 | color: #909399 !important;
32 | }
33 |
34 | .el-menu-item i {
35 | color: #dee4eb;
36 | }
37 | .el-menu-item.is-active i {
38 | color: #409EFF;
39 | }
--------------------------------------------------------------------------------
/src/styles/iconfont.less:
--------------------------------------------------------------------------------
1 | @font-face {font-family: "iconfont";
2 | src: url('//at.alicdn.com/t/font_1647403_aybihsndmv.eot?t=1582123640102'); /* IE9 */
3 | src: url('//at.alicdn.com/t/font_1647403_aybihsndmv.eot?t=1582123640102#iefix') format('embedded-opentype'), /* IE6-IE8 */
4 | url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAPcAAsAAAAACEAAAAOPAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqEKINkATYCJAMMCwgABCAFhG0HOBssBxFVlNdkPw6cs+zMPfcvMBOlnMf5X3b/ndvdH5SyhZGCnle7EeBoGiCAoObWdGVMoyJUl+z51rP8j6Td+cU6j9MohZAgHH/cO/2roYHNZ1k5jLlsrEldFMeddwGNMc77ZAWIDWM3UR7EcyAA6rCGJygxObMQqhAA6wgAdba11EE1ZYGoKSaogqBcclSAlkEJqmw+uwVgKf89fYQ/qQIMShxga25zUiNi30S8OcJn5VlUUgTS8VwAtFMAB+AJQABUXeopBQ9jnuBQdzSiPlsZAgQ2VlCWAS5xdcor/eMxgJQBNJoixVXNTkqKeUDAmyNiUYvz9wHKPRJHAbyUKIYzlaCiqaXpaaSmpq+Gd45oLjgwd1BDa+H+2X2NpL4nwXDR2N3bUKgrVQ4dVdjwLVKw5qFHlmzz/aA2tzmqS1IxVyhKtB4/LmKzj4oXHDCnpFqj0xvq6ofuWWLdvpK5MwtOzZ5eeLYimFpUsnbDnl2GhYduWW4SkwqbrVJDsb5ZohVNmy1cp667wFyiOQWgL3xc89vii16zQ7MeFXCfxCM02zcPqp6WPfFLPJWpbtojY9/36MTEPvvzjOToPNORn0kWSVIedXRT3jPK7+jKoz+5dXZR/n7fi9dquX4x9VJ6fX0a1Q12a11vkkovFePpZ+sNUQei9ket77K2PhAZfixy/6+foU+i/x/dGh32RL9i7qRXdolxttfBOdPYSmfrA1EbotZH7e9aaNNQhO1ydpfrjjxbnTu9zNDecFnu1JrW3FPz5p/OvYeETBhtQS0AQL7LT/JgGSSuC7Avv/o93Fdrv1WjE/lbVUMAAJ4OdIxyabsCHkxFBNUX4SX4seMGWQaELgdWPluD2mYCcM02r80EdRgEZICAPn79fUaIYhdR1aUiMCqsgFPliAqKJyjREAjKVMWAOg9UpzUYwFmgqQFwx0sAoos3MNrOAqeLDyooX1BijD8o06UFqCvO4EoNztTuExyKgBrkE1rFEyF72AfFB6yvg3BJOWde0Pk2CFmcZpMVTujG2OFvdR4CATkeoRRew2FgMI47VCFuQjBFklAZSbHiMdpL4CAhQBpAegK0FDYhOjzY575/gGpXA8HVdHX4L5DjtZMDMsRIW6CVZmrVdS2zvZtajiAgeRVx2AhQii40wBgDmPJFHaQEMZoeEaNAIvWjtpp4ft34fEcA1IF7eYw4CbCH7rTwjWThdBQBAA==') format('woff2'),
5 | url('//at.alicdn.com/t/font_1647403_aybihsndmv.woff?t=1582123640102') format('woff'),
6 | url('//at.alicdn.com/t/font_1647403_aybihsndmv.ttf?t=1582123640102') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
7 | url('//at.alicdn.com/t/font_1647403_aybihsndmv.svg?t=1582123640102#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family: "iconfont" !important;
12 | font-size: 16px;
13 | font-style: normal;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | .icon-58:before {
19 | content: "\e63b";
20 | }
21 |
22 | .icon-dashboard:before {
23 | content: "\e6b6";
24 | }
25 |
--------------------------------------------------------------------------------
/src/styles/index.less:
--------------------------------------------------------------------------------
1 | @backgroundColorSty: #304156;
2 |
3 | .layout {
4 | position: relative;
5 | height: 100%;
6 | width: 100%;
7 | .menu {
8 | background-color: @backgroundColorSty;
9 | height: 100%;
10 | position: fixed;
11 | top: 0;
12 | bottom: 0;
13 | left: 0;
14 | z-index: 1001;
15 | .scrollbar-wrapper {
16 | overflow-x: hidden !important;
17 | }
18 | .scrollbar-wrapper {
19 | overflow-x: hidden !important;
20 | }
21 | .el-scrollbar__bar.is-vertical {
22 | right: 0px;
23 | }
24 | .el-scrollbar {
25 | height: 100%;
26 | }
27 | .activeWidth {
28 | width: 230px;
29 | transition: transform .28s;
30 | }
31 | .el-menu {
32 | height: 100%;
33 | .el-submenu__title {
34 | text-align: left;
35 | i {
36 | color: #dee4eb;
37 | }
38 | }
39 | .el-icon-arrow-right:before {
40 | content: '' !important;
41 | }
42 | .el-menu-item {
43 | text-align: left;
44 | }
45 | }
46 | }
47 | .main {
48 | line-height: 32px;
49 | position: relative;
50 | min-height: 100%;
51 | margin-left: 230px;
52 | transition: margin-left .28s; // 原来滑动效果是这样做出来的
53 | .header {
54 | height: 50px;
55 | width: 100%;
56 | box-shadow: 1px 2px 6px #ddd;
57 | background-color: #fff;
58 | .el-icon-s-fold, .el-icon-s-unfold {
59 | cursor: pointer;
60 | margin: 13px 10px;
61 | font-size: 25px;
62 | }
63 | .user {
64 | cursor: pointer;
65 | float: right;
66 | font-size: 18px;
67 | font-weight: bold;
68 | margin: 15px 25px;
69 | text-align: center;
70 | }
71 | }
72 | }
73 | }
74 | .hideSidebar {
75 | .main {
76 | margin-left: 54px;
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/src/utils/auth.js:
--------------------------------------------------------------------------------
1 | import Cookies from 'js-cookie';
2 |
3 | export function getToken() {
4 | return Cookies.get('token')
5 | }
6 | export function removeUserId() {
7 | return Cookies.remove('userId')
8 | }
9 | export function removeId() {
10 | return Cookies.remove('staffId')
11 | }
12 | export function removeNickname() {
13 | return Cookies.remove('nickname')
14 | }
15 | export function removeToken() {
16 | return Cookies.remove('token')
17 | }
18 | export function setToken(token) {
19 | return Cookies.set('token', token)
20 | }
21 | export function getStaffId() {
22 | return Cookies.get('staffId')
23 | }
24 | export function getUserId() {
25 | return Cookies.get('userId')
26 | }
27 | export function getNickname() {
28 | return Cookies.get('nickname')
29 | }
--------------------------------------------------------------------------------
/src/utils/get-page-title.js:
--------------------------------------------------------------------------------
1 | const title = 'vue-element-admin-template'
2 |
3 | export default function getPageTitle(pageTitle) {
4 | if(pageTitle) {
5 | return `${pageTitle} - ${title}`
6 | }
7 | return title;
8 | }
--------------------------------------------------------------------------------
/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import Cookie from 'js-cookie';
3 |
4 | const instance = axios.create({
5 | baseURL: '',
6 | timeout: 500000
7 | });
8 |
9 | instance.interceptors.request.use((req) => {
10 | req.headers.authorization = Cookie.get('token');
11 | return req;
12 | }, err => Promise.reject(err));
13 |
14 | instance.interceptors.response.use(
15 | res => res,
16 | err => Promise.reject(err)
17 | );
18 |
19 | export default function request(url, options) {
20 | const opt = options || {};
21 | return new Promise((resolve, reject) => {
22 | instance({
23 | url,
24 | method: opt.type || 'get',
25 | data: opt.params || {},
26 | headers: {
27 | 'Content-Type': 'application/json',
28 | }
29 | }).then((res) => {
30 | if (res) {
31 | const h = res.headers;
32 | resolve({data: res.data, headers:h})
33 | }
34 | return res;
35 | })
36 | .catch((err) => { reject(err) });
37 | });
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/src/utils/utils.js:
--------------------------------------------------------------------------------
1 | export const uploadOssConfig = {
2 | accessid: "",
3 | accesskey: "",
4 | host: "",
5 | policyText: {
6 | expiration: "2021-01-01T12:00:00.000Z", //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
7 | conditions: [
8 | ["content-length-range", 0, 1048576000] // 设置上传文件的大小限制
9 | ]
10 | },
11 | uploadUrl: ""
12 | }
13 |
14 | export function judgePower(arr, str) {
15 | for (let i = 0; i < arr.length; i++) {
16 | if (arr[i] === str) {
17 | return true;
18 | }
19 | }
20 | return false;
21 | }
22 |
23 | function domainConfig() {
24 | if (window.location.origin.indexOf("online domain name") !== -1) {
25 | return "https://api.xxxx.com";
26 | }
27 | return "https://api.testing.xxxx.com";
28 | }
29 |
30 | export const commonConfig = {
31 | apiUrl: domainConfig(),
32 | };
--------------------------------------------------------------------------------
/src/views/Layout/SidebarItem/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{onlyOneChild.meta.title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{route.meta.title}}
16 |
17 |
24 |
25 |
26 |
27 |
28 |
66 |
67 |
72 |
--------------------------------------------------------------------------------
/src/views/Layout/appMain/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
50 |
51 |
62 |
--------------------------------------------------------------------------------
/src/views/Layout/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
65 |
66 |
71 |
--------------------------------------------------------------------------------
/src/views/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
83 |
84 |
216 |
217 |
286 |
--------------------------------------------------------------------------------
/src/views/UserRelation/UserRelation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 登录成功页
4 |
5 |
6 |
7 |
8 |
13 |
14 |
22 |
--------------------------------------------------------------------------------
/src/views/error-page/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
20 |
21 |
146 |
--------------------------------------------------------------------------------
/src/views/navigatorOne/itemOne/itemOne.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorOne/itemThree
4 |
5 |
6 |
7 |
8 |
12 |
13 |
21 |
--------------------------------------------------------------------------------
/src/views/navigatorOne/itemThree/itemThree.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorOne/itemOne
4 |
5 |
6 |
7 |
8 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/views/navigatorOne/itemTwo/itemTwo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorOne/itemTwo
4 |
5 |
6 |
7 |
8 |
13 |
14 |
22 |
--------------------------------------------------------------------------------
/src/views/navigatorTwo/CommonInvite/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
21 |
--------------------------------------------------------------------------------
/src/views/navigatorTwo/itemFour/itemFour.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorTwo/itemFour
4 |
5 |
6 |
7 |
8 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/src/views/navigatorTwo/itemOne/itemOne.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorTwo/itemOne/one/one
4 |
5 |
6 |
7 |
11 |
12 |
20 |
--------------------------------------------------------------------------------
/src/views/navigatorTwo/itemThree/itemThree.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorTwo/itemThree
4 |
5 |
6 |
7 |
8 |
13 |
14 |
22 |
--------------------------------------------------------------------------------
/src/views/navigatorTwo/itemTwo/itemTwo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | /navigatorTwo/itemTwo
4 | 跳转隐藏自路由
5 |
6 |
7 |
8 |
9 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 |
4 | function resolve(dir) {
5 | return path.join(__dirname, dir)
6 | }
7 |
8 | module.exports = {
9 | publicPath: '/vue-element-admin-template',
10 | outputDir: 'dist/vue-element-admin-template',
11 | devServer: {
12 | port: 10080,
13 | disableHostCheck: true, // solve Invilid host header problem
14 | hotOnly: true, // 热更新
15 | },
16 | chainWebpack: config => {
17 | config.module
18 | .rule('svg')
19 | .exclude.add(resolve('src/icons'))
20 | .end()
21 | config.module
22 | .rule('icons')
23 | .test(/\.svg$/)
24 | .include.add(resolve('src/icons'))
25 | .end()
26 | .use('svg-sprite-loader')
27 | .loader('svg-sprite-loader')
28 | .options({
29 | symbolId: 'icon-[name]'
30 | })
31 | .end()
32 | }
33 | }
--------------------------------------------------------------------------------