Commit 1172ebb79113b8a99000521190fdd9f936ea649f
1 parent
c44ba96f68
Exists in
master
auto commit the code by alias command
Showing
29 changed files
with
1834 additions
and
243 deletions
Show diff stats
.eslintrc.js
| 1 | module.exports = { | 1 | module.exports = { |
| 2 | root: true, | 2 | root: true, |
| 3 | parserOptions: { | 3 | parserOptions: { |
| 4 | parser: 'babel-eslint', | 4 | parser: 'babel-eslint', |
| 5 | sourceType: 'module' | 5 | sourceType: 'module' |
| 6 | }, | 6 | }, |
| 7 | env: { | 7 | env: { |
| 8 | browser: true, | 8 | browser: true, |
| 9 | node: true, | 9 | node: true, |
| 10 | es6: true, | 10 | es6: true, |
| 11 | }, | 11 | }, |
| 12 | extends: ['plugin:vue/recommended', 'eslint:recommended'], | 12 | extends: ['plugin:vue/recommended', 'eslint:recommended'], |
| 13 | 13 | ||
| 14 | // add your custom rules here | 14 | // add your custom rules here |
| 15 | //it is base on https://github.com/vuejs/eslint-config-vue | 15 | //it is base on https://github.com/vuejs/eslint-config-vue |
| 16 | rules: { | 16 | rules: { |
| 17 | "vue/max-attributes-per-line": [2, { | 17 | "vue/max-attributes-per-line": [2, { |
| 18 | "singleline": 10, | 18 | "singleline": 10, |
| 19 | "multiline": { | 19 | "multiline": { |
| 20 | "max": 1, | 20 | "max": 1, |
| 21 | "allowFirstLine": false | 21 | "allowFirstLine": false |
| 22 | } | 22 | } |
| 23 | }], | 23 | }], |
| 24 | "vue/singleline-html-element-content-newline": "off", | 24 | "vue/singleline-html-element-content-newline": "off", |
| 25 | "vue/multiline-html-element-content-newline":"off", | 25 | "vue/multiline-html-element-content-newline":"off", |
| 26 | "vue/name-property-casing": ["error", "PascalCase"], | 26 | "vue/name-property-casing": ["error", "PascalCase"], |
| 27 | "vue/no-v-html": "off", | 27 | "vue/no-v-html": "off", |
| 28 | 'accessor-pairs': 2, | 28 | 'accessor-pairs': 2, |
| 29 | 'arrow-spacing': [2, { | 29 | 'arrow-spacing': [2, { |
| 30 | 'before': true, | 30 | 'before': true, |
| 31 | 'after': true | 31 | 'after': true |
| 32 | }], | 32 | }], |
| 33 | 'block-spacing': [2, 'always'], | 33 | 'block-spacing': [2, 'always'], |
| 34 | 'brace-style': [2, '1tbs', { | 34 | 'brace-style': [2, '1tbs', { |
| 35 | 'allowSingleLine': true | 35 | 'allowSingleLine': true |
| 36 | }], | 36 | }], |
| 37 | 'camelcase': [0, { | 37 | 'camelcase': [0, { |
| 38 | 'properties': 'always' | 38 | 'properties': 'always' |
| 39 | }], | 39 | }], |
| 40 | 'comma-dangle': [2, 'never'], | 40 | 'comma-dangle': [2, 'never'], |
| 41 | 'comma-spacing': [2, { | 41 | 'comma-spacing': [2, { |
| 42 | 'before': false, | 42 | 'before': false, |
| 43 | 'after': true | 43 | 'after': true |
| 44 | }], | 44 | }], |
| 45 | 'comma-style': [2, 'last'], | 45 | 'comma-style': [2, 'last'], |
| 46 | 'constructor-super': 2, | 46 | 'constructor-super': 2, |
| 47 | 'curly': [2, 'multi-line'], | 47 | 'curly': [2, 'multi-line'], |
| 48 | 'dot-location': [2, 'property'], | 48 | 'dot-location': [2, 'property'], |
| 49 | 'eol-last': 2, | 49 | 'eol-last': 2, |
| 50 | 'eqeqeq': ["error", "always", {"null": "ignore"}], | 50 | 'eqeqeq': ["error", "always", {"null": "ignore"}], |
| 51 | 'generator-star-spacing': [2, { | 51 | 'generator-star-spacing': [2, { |
| 52 | 'before': true, | 52 | 'before': true, |
| 53 | 'after': true | 53 | 'after': true |
| 54 | }], | 54 | }], |
| 55 | 'handle-callback-err': [2, '^(err|error)$'], | 55 | 'handle-callback-err': [2, '^(err|error)$'], |
| 56 | 'indent': [2, 2, { | 56 | 'indent': [2, 2, { |
| 57 | 'SwitchCase': 1 | 57 | 'SwitchCase': 1 |
| 58 | }], | 58 | }], |
| 59 | 'jsx-quotes': [2, 'prefer-single'], | 59 | 'jsx-quotes': [2, 'prefer-single'], |
| 60 | 'key-spacing': [2, { | 60 | 'key-spacing': [2, { |
| 61 | 'beforeColon': false, | 61 | 'beforeColon': false, |
| 62 | 'afterColon': true | 62 | 'afterColon': true |
| 63 | }], | 63 | }], |
| 64 | 'keyword-spacing': [2, { | 64 | 'keyword-spacing': [2, { |
| 65 | 'before': true, | 65 | 'before': true, |
| 66 | 'after': true | 66 | 'after': true |
| 67 | }], | 67 | }], |
| 68 | 'new-cap': [2, { | 68 | 'new-cap': [2, { |
| 69 | 'newIsCap': true, | 69 | 'newIsCap': true, |
| 70 | 'capIsNew': false | 70 | 'capIsNew': false |
| 71 | }], | 71 | }], |
| 72 | 'new-parens': 2, | 72 | 'new-parens': 2, |
| 73 | 'no-array-constructor': 2, | 73 | 'no-array-constructor': 2, |
| 74 | 'no-caller': 2, | 74 | 'no-caller': 2, |
| 75 | 'no-console': 'off', | 75 | 'no-console': 'off', |
| 76 | 'no-class-assign': 2, | 76 | 'no-class-assign': 2, |
| 77 | 'no-cond-assign': 2, | 77 | 'no-cond-assign': 2, |
| 78 | 'no-const-assign': 2, | 78 | 'no-const-assign': 2, |
| 79 | 'no-control-regex': 0, | 79 | 'no-control-regex': 0, |
| 80 | 'no-delete-var': 2, | 80 | 'no-delete-var': 2, |
| 81 | 'no-dupe-args': 2, | 81 | 'no-dupe-args': 2, |
| 82 | 'no-dupe-class-members': 2, | 82 | 'no-dupe-class-members': 2, |
| 83 | 'no-dupe-keys': 2, | 83 | 'no-dupe-keys': 2, |
| 84 | 'no-duplicate-case': 2, | 84 | 'no-duplicate-case': 2, |
| 85 | 'no-empty-character-class': 2, | 85 | 'no-empty-character-class': 2, |
| 86 | 'no-empty-pattern': 2, | 86 | 'no-empty-pattern': 2, |
| 87 | 'no-eval': 2, | 87 | 'no-eval': 2, |
| 88 | 'no-ex-assign': 2, | 88 | 'no-ex-assign': 2, |
| 89 | 'no-extend-native': 2, | 89 | 'no-extend-native': 2, |
| 90 | 'no-extra-bind': 2, | 90 | 'no-extra-bind': 2, |
| 91 | 'no-extra-boolean-cast': 2, | 91 | 'no-extra-boolean-cast': 2, |
| 92 | 'no-extra-parens': [2, 'functions'], | 92 | 'no-extra-parens': [2, 'functions'], |
| 93 | 'no-fallthrough': 2, | 93 | 'no-fallthrough': 2, |
| 94 | 'no-floating-decimal': 2, | 94 | 'no-floating-decimal': 2, |
| 95 | 'no-func-assign': 2, | 95 | 'no-func-assign': 2, |
| 96 | 'no-implied-eval': 2, | 96 | 'no-implied-eval': 2, |
| 97 | 'no-inner-declarations': [2, 'functions'], | 97 | 'no-inner-declarations': [2, 'functions'], |
| 98 | 'no-invalid-regexp': 2, | 98 | 'no-invalid-regexp': 2, |
| 99 | 'no-irregular-whitespace': 2, | 99 | 'no-irregular-whitespace': 2, |
| 100 | 'no-iterator': 2, | 100 | 'no-iterator': 2, |
| 101 | 'no-label-var': 2, | 101 | 'no-label-var': 2, |
| 102 | 'no-labels': [2, { | 102 | 'no-labels': [2, { |
| 103 | 'allowLoop': false, | 103 | 'allowLoop': false, |
| 104 | 'allowSwitch': false | 104 | 'allowSwitch': false |
| 105 | }], | 105 | }], |
| 106 | 'no-lone-blocks': 2, | 106 | 'no-lone-blocks': 2, |
| 107 | 'no-mixed-spaces-and-tabs': 2, | 107 | 'no-mixed-spaces-and-tabs': 2, |
| 108 | 'no-multi-spaces': 2, | 108 | 'no-multi-spaces': 2, |
| 109 | 'no-multi-str': 2, | 109 | 'no-multi-str': 2, |
| 110 | 'no-multiple-empty-lines': [2, { | 110 | 'no-multiple-empty-lines': [2, { |
| 111 | 'max': 1 | 111 | 'max': 1 |
| 112 | }], | 112 | }], |
| 113 | 'no-native-reassign': 2, | 113 | 'no-native-reassign': 2, |
| 114 | 'no-negated-in-lhs': 2, | 114 | 'no-negated-in-lhs': 2, |
| 115 | 'no-new-object': 2, | 115 | 'no-new-object': 2, |
| 116 | 'no-new-require': 2, | 116 | 'no-new-require': 2, |
| 117 | 'no-new-symbol': 2, | 117 | 'no-new-symbol': 2, |
| 118 | 'no-new-wrappers': 2, | 118 | 'no-new-wrappers': 2, |
| 119 | 'no-obj-calls': 2, | 119 | 'no-obj-calls': 2, |
| 120 | 'no-octal': 2, | 120 | 'no-octal': 2, |
| 121 | 'no-octal-escape': 2, | 121 | 'no-octal-escape': 2, |
| 122 | 'no-path-concat': 2, | 122 | 'no-path-concat': 2, |
| 123 | 'no-proto': 2, | 123 | 'no-proto': 2, |
| 124 | 'no-redeclare': 2, | 124 | 'no-redeclare': 2, |
| 125 | 'no-regex-spaces': 2, | 125 | 'no-regex-spaces': 2, |
| 126 | 'no-return-assign': [2, 'except-parens'], | 126 | 'no-return-assign': [2, 'except-parens'], |
| 127 | 'no-self-assign': 2, | 127 | 'no-self-assign': 2, |
| 128 | 'no-self-compare': 2, | 128 | 'no-self-compare': 2, |
| 129 | 'no-sequences': 2, | 129 | 'no-sequences': 2, |
| 130 | 'no-shadow-restricted-names': 2, | 130 | 'no-shadow-restricted-names': 2, |
| 131 | 'no-spaced-func': 2, | 131 | 'no-spaced-func': 2, |
| 132 | 'no-sparse-arrays': 2, | 132 | 'no-sparse-arrays': 2, |
| 133 | 'no-this-before-super': 2, | 133 | 'no-this-before-super': 2, |
| 134 | 'no-throw-literal': 2, | 134 | 'no-throw-literal': 2, |
| 135 | 'no-trailing-spaces': 2, | 135 | 'no-trailing-spaces': 2, |
| 136 | 'no-undef': 2, | 136 | 'no-undef': 2, |
| 137 | 'no-undef-init': 2, | 137 | 'no-undef-init': 2, |
| 138 | 'no-unexpected-multiline': 2, | 138 | 'no-unexpected-multiline': 2, |
| 139 | 'no-unmodified-loop-condition': 2, | 139 | 'no-unmodified-loop-condition': 2, |
| 140 | 'no-unneeded-ternary': [2, { | 140 | 'no-unneeded-ternary': [2, { |
| 141 | 'defaultAssignment': false | 141 | 'defaultAssignment': false |
| 142 | }], | 142 | }], |
| 143 | 'no-unreachable': 2, | 143 | 'no-unreachable': 2, |
| 144 | 'no-unsafe-finally': 2, | 144 | 'no-unsafe-finally': 2, |
| 145 | 'no-unused-vars': [2, { | 145 | 'no-unused-vars': [2, { |
| 146 | 'vars': 'all', | 146 | 'vars': 'all', |
| 147 | 'args': 'none' | 147 | 'args': 'none' |
| 148 | }], | 148 | }], |
| 149 | 'no-useless-call': 2, | 149 | 'no-useless-call': 2, |
| 150 | 'no-useless-computed-key': 2, | 150 | 'no-useless-computed-key': 2, |
| 151 | 'no-useless-constructor': 2, | 151 | 'no-useless-constructor': 2, |
| 152 | 'no-useless-escape': 0, | 152 | 'no-useless-escape': 0, |
| 153 | 'no-whitespace-before-property': 2, | 153 | 'no-whitespace-before-property': 2, |
| 154 | 'no-with': 2, | 154 | 'no-with': 2, |
| 155 | 'one-var': [2, { | 155 | 'one-var': [2, { |
| 156 | 'initialized': 'never' | 156 | 'initialized': 'never' |
| 157 | }], | 157 | }], |
| 158 | 'operator-linebreak': [2, 'after', { | 158 | 'operator-linebreak': [2, 'after', { |
| 159 | 'overrides': { | 159 | 'overrides': { |
| 160 | '?': 'before', | 160 | '?': 'before', |
| 161 | ':': 'before' | 161 | ':': 'before' |
| 162 | } | 162 | } |
| 163 | }], | 163 | }], |
| 164 | 'padded-blocks': [2, 'never'], | 164 | 'padded-blocks': [2, 'never'], |
| 165 | 'quotes': [2, 'single', { | 165 | 'quotes': [2, 'single', { |
| 166 | 'avoidEscape': true, | 166 | 'avoidEscape': true, |
| 167 | 'allowTemplateLiterals': true | 167 | 'allowTemplateLiterals': true |
| 168 | }], | 168 | }], |
| 169 | 'semi': [2, 'never'], | 169 | 'semi': [2, 'never'], |
| 170 | // 'semi': 0, | ||
| 170 | 'semi-spacing': [2, { | 171 | 'semi-spacing': [2, { |
| 171 | 'before': false, | 172 | 'before': false, |
| 172 | 'after': true | 173 | 'after': true |
| 173 | }], | 174 | }], |
| 174 | 'space-before-blocks': [2, 'always'], | 175 | 'space-before-blocks': [2, 'always'], |
| 175 | 'space-before-function-paren': [2, 'never'], | 176 | 'space-before-function-paren': [2, 'never'], |
| 176 | 'space-in-parens': [2, 'never'], | 177 | 'space-in-parens': [2, 'never'], |
| 177 | 'space-infix-ops': 2, | 178 | 'space-infix-ops': 2, |
| 178 | 'space-unary-ops': [2, { | 179 | 'space-unary-ops': [2, { |
| 179 | 'words': true, | 180 | 'words': true, |
| 180 | 'nonwords': false | 181 | 'nonwords': false |
| 181 | }], | 182 | }], |
| 182 | 'spaced-comment': [2, 'always', { | 183 | 'spaced-comment': [2, 'always', { |
| 183 | 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] | 184 | 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] |
| 184 | }], | 185 | }], |
| 185 | 'template-curly-spacing': [2, 'never'], | 186 | 'template-curly-spacing': [2, 'never'], |
| 186 | 'use-isnan': 2, | 187 | 'use-isnan': 2, |
| 187 | 'valid-typeof': 2, | 188 | 'valid-typeof': 2, |
| 188 | 'wrap-iife': [2, 'any'], | 189 | 'wrap-iife': [2, 'any'], |
| 189 | 'yield-star-spacing': [2, 'both'], | 190 | 'yield-star-spacing': [2, 'both'], |
| 190 | 'yoda': [2, 'never'], | 191 | 'yoda': [2, 'never'], |
| 191 | 'prefer-const': 2, | 192 | 'prefer-const': 2, |
| 192 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, | 193 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, |
| 193 | 'object-curly-spacing': [2, 'always', { | 194 | 'object-curly-spacing': [2, 'always', { |
| 194 | objectsInObjects: false | 195 | objectsInObjects: false |
| 195 | }], | 196 | }], |
| 196 | 'array-bracket-spacing': [2, 'never'] | 197 | 'array-bracket-spacing': [2, 'never'] |
| 197 | } | 198 | } |
| 198 | } | 199 | } |
| 199 | 200 |
babel.config.js
| 1 | // module.exports = { | ||
| 2 | // presets: [ | ||
| 3 | // '@vue/app' | ||
| 4 | // ] | ||
| 5 | // } | ||
| 6 | // "@babel/preset-env", | ||
| 7 | // { | ||
| 8 | // "modules": false | ||
| 9 | // }, | ||
| 1 | module.exports = { | 10 | module.exports = { |
| 2 | presets: [ | 11 | "presets": [ |
| 3 | '@vue/app' | 12 | [ |
| 13 | '@vue/app', | ||
| 14 | // '@babel/preset-env', | ||
| 15 | { | ||
| 16 | // "modules": false, | ||
| 17 | // "targets": { // 配置代码的运行环境 | ||
| 18 | // "chrome": 64 | ||
| 19 | // }, | ||
| 20 | // "useBuiltIns": true // 开启对 babel-polyfill 的优化 | ||
| 21 | } | ||
| 22 | ] | ||
| 23 | ], | ||
| 24 | "plugins": [ | ||
| 25 | [ | ||
| 26 | "component", | ||
| 27 | { | ||
| 28 | "libraryName": "element-ui", | ||
| 29 | "styleLibraryName": "theme-chalk" | ||
| 30 | } | ||
| 31 | ] | ||
| 4 | ] | 32 | ] |
| 5 | } | 33 | } |
| 6 | 34 |
mock/index.js
| 1 | import Mock from 'mockjs' | 1 | import Mock from 'mockjs' |
| 2 | import { param2Obj } from '../src/utils' | 2 | import { |
| 3 | param2Obj | ||
| 4 | } from '../src/utils' | ||
| 3 | 5 | ||
| 4 | import user from './user' | 6 | import user from './user' |
| 5 | import table from './table' | 7 | import table from './table' |
| 6 | 8 | ||
| 7 | const mocks = [ | 9 | const mocks = [ |
| 8 | ...user, | 10 | ...user, |
| 9 | ...table | 11 | ...table |
| 10 | ] | 12 | ] |
| 11 | 13 | ||
| 12 | // for front mock | 14 | // for front mock |
| 13 | // please use it cautiously, it will redefine XMLHttpRequest, | 15 | // please use it cautiously, it will redefine XMLHttpRequest, |
| 14 | // which will cause many of your third-party libraries to be invalidated(like progress event). | 16 | // which will cause many of your third-party libraries to be invalidated(like progress event). |
| 15 | export function mockXHR() { | 17 | export function mockXHR() { |
| 16 | // mock patch | 18 | // mock patch |
| 17 | // https://github.com/nuysoft/Mock/issues/300 | 19 | // https://github.com/nuysoft/Mock/issues/300 |
| 18 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send | 20 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send |
| 19 | Mock.XHR.prototype.send = function() { | 21 | Mock.XHR.prototype.send = function () { |
| 20 | if (this.custom.xhr) { | 22 | if (this.custom.xhr) { |
| 21 | this.custom.xhr.withCredentials = this.withCredentials || false | 23 | this.custom.xhr.withCredentials = this.withCredentials || false |
| 22 | 24 | ||
| 23 | if (this.responseType) { | 25 | if (this.responseType) { |
| 24 | this.custom.xhr.responseType = this.responseType | 26 | this.custom.xhr.responseType = this.responseType |
| 25 | } | 27 | } |
| 26 | } | 28 | } |
| 27 | this.proxy_send(...arguments) | 29 | this.proxy_send(...arguments) |
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | function XHR2ExpressReqWrap(respond) { | 32 | function XHR2ExpressReqWrap(respond) { |
| 31 | return function(options) { | 33 | return function (options) { |
| 32 | let result = null | 34 | let result = null |
| 33 | if (respond instanceof Function) { | 35 | if (respond instanceof Function) { |
| 34 | const { body, type, url } = options | 36 | const { |
| 37 | body, | ||
| 38 | type, | ||
| 39 | url | ||
| 40 | } = options | ||
| 35 | // https://expressjs.com/en/4x/api.html#req | 41 | // https://expressjs.com/en/4x/api.html#req |
| 36 | result = respond({ | 42 | result = respond({ |
| 37 | method: type, | 43 | method: type, |
| 38 | body: JSON.parse(body), | 44 | body: JSON.parse(body), |
| 39 | query: param2Obj(url) | 45 | query: param2Obj(url) |
| 40 | }) | 46 | }) |
| 41 | } else { | 47 | } else { |
| 42 | result = respond | 48 | result = respond |
| 43 | } | 49 | } |
| 44 | return Mock.mock(result) | 50 | return Mock.mock(result) |
| 45 | } | 51 | } |
| 46 | } | 52 | } |
| 47 | 53 | ||
| 48 | for (const i of mocks) { | 54 | for (const i of mocks) { |
| 49 | Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) | 55 | Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) |
| 50 | } | 56 | } |
| 51 | } | 57 | } |
| 52 | 58 | ||
| 53 | // for mock server | 59 | // for mock server |
| 54 | const responseFake = (url, type, respond) => { | 60 | const responseFake = (url, type, respond) => { |
| 55 | return { | 61 | return { |
| 56 | url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`), | 62 | url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`), |
| 57 | type: type || 'get', | 63 | type: type || 'get', |
| 58 | response(req, res) { | 64 | response(req, res) { |
| 59 | console.log('request invoke:' + req.path) | 65 | console.log('request invoke:' + req.path) |
| 60 | res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) | 66 | res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) |
| 61 | } | 67 | } |
| 62 | } | 68 | } |
| 63 | } | 69 | } |
| 64 | 70 | ||
| 65 | export default mocks.map(route => { | 71 | export default mocks.map(route => { |
| 66 | return responseFake(route.url, route.type, route.response) | 72 | return responseFake(route.url, route.type, route.response) |
| 67 | }) | 73 | }) |
| 68 | 74 |
mock/table.js
| 1 | import Mock from 'mockjs' | 1 | import Mock from 'mockjs' |
| 2 | 2 | ||
| 3 | const data = Mock.mock({ | 3 | const data = Mock.mock({ |
| 4 | 'items|10': [{ | 4 | 'items|10': [{ |
| 5 | id: '@id', | 5 | id: '@id', |
| 6 | title: '@sentence(3, 10)', | 6 | title: '@sentence(10, 10)', |
| 7 | 'status|1': ['published', 'draft', 'deleted'], | 7 | 'status|1': ['published', 'draft', 'deleted'], |
| 8 | author: 'name@integer(300, 5000)', | 8 | username: '@sentence(1, 2)', |
| 9 | display_time: '@datetime', | 9 | create_at: '@datetime', |
| 10 | pageviews: '@integer(300, 5000)' | 10 | pageviews: '@integer(10, 500)', |
| 11 | openid: '@sentence(1, 1)', | ||
| 12 | avatar:'----' | ||
| 11 | }] | 13 | }] |
| 12 | }) | 14 | }) |
| 13 | 15 | ||
| 14 | export default [ | 16 | export default [ |
| 15 | { | 17 | { |
| 16 | url: '/yp/table/list', | 18 | url: '/yp/table/list', |
| 17 | type: 'get', | 19 | type: 'get', |
| 18 | response: config => { | 20 | response: config => { |
| 19 | const items = data.items | 21 | const items = data.items |
| 20 | return { | 22 | return { |
| 21 | code: 20000, | 23 | code: 20000, |
| 22 | data: { | 24 | data: { |
| 23 | total: items.length, | 25 | total: items.length, |
| 24 | items: items | 26 | items: items |
| 25 | } | 27 | } |
| 26 | } | 28 | } |
| 27 | } | 29 | } |
| 28 | } | 30 | } |
| 29 | ] | 31 | ] |
| 30 | 32 |
package.json
| 1 | { | 1 | { |
| 2 | "name": "yp-plan", | 2 | "name": "yp-plan", |
| 3 | "version": "4.2.1", | 3 | "version": "4.2.1", |
| 4 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", | 4 | "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", |
| 5 | "author": "XYT==admin@xiuyetang.com", | 5 | "author": "XYT==admin@xiuyetang.com", |
| 6 | "license": "MIT", | 6 | "license": "MIT", |
| 7 | "scripts": { | 7 | "scripts": { |
| 8 | "dev": "vue-cli-service serve", | 8 | "dev": "vue-cli-service serve", |
| 9 | "build:prod": "vue-cli-service build", | 9 | "build:prod": "vue-cli-service build", |
| 10 | "build:stage": "vue-cli-service build --mode staging", | 10 | "build:stage": "vue-cli-service build --mode staging", |
| 11 | "preview": "node build/index.js --preview", | 11 | "preview": "node build/index.js --preview", |
| 12 | "lint": "eslint --ext .js,.vue src", | 12 | "lint": "eslint --ext .js,.vue src", |
| 13 | "test:unit": "jest --clearCache && vue-cli-service test:unit", | 13 | "test:unit": "jest --clearCache && vue-cli-service test:unit", |
| 14 | "test:ci": "npm run lint && npm run test:unit", | 14 | "test:ci": "npm run lint && npm run test:unit", |
| 15 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" | 15 | "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" |
| 16 | }, | 16 | }, |
| 17 | "dependencies": { | 17 | "dependencies": { |
| 18 | "axios": "0.18.1", | 18 | "axios": "0.18.1", |
| 19 | "babel-polyfill": "^6.26.0", | ||
| 19 | "echarts": "^4.7.0", | 20 | "echarts": "^4.7.0", |
| 20 | "element-ui": "2.13.0", | 21 | "element-ui": "2.13.0", |
| 21 | "js-cookie": "2.2.0", | 22 | "js-cookie": "2.2.0", |
| 22 | "normalize.css": "7.0.0", | 23 | "normalize.css": "7.0.0", |
| 23 | "nprogress": "0.2.0", | 24 | "nprogress": "0.2.0", |
| 24 | "path-to-regexp": "2.4.0", | 25 | "path-to-regexp": "2.4.0", |
| 25 | "plop": "^2.6.0", | 26 | "plop": "^2.6.0", |
| 26 | "vue": "2.6.10", | 27 | "vue": "2.6.10", |
| 27 | "vue-router": "3.0.6", | 28 | "vue-router": "3.0.6", |
| 28 | "vuex": "3.1.0" | 29 | "vuex": "3.1.0" |
| 29 | }, | 30 | }, |
| 30 | "devDependencies": { | 31 | "devDependencies": { |
| 31 | "@babel/core": "7.0.0", | 32 | "@babel/core": "7.0.0", |
| 33 | "@babel/preset-env": "^7.9.6", | ||
| 32 | "@babel/register": "7.0.0", | 34 | "@babel/register": "7.0.0", |
| 33 | "@vue/cli-plugin-babel": "3.6.0", | 35 | "@vue/cli-plugin-babel": "3.6.0", |
| 34 | "@vue/cli-plugin-eslint": "^3.9.1", | 36 | "@vue/cli-plugin-eslint": "^3.9.1", |
| 35 | "@vue/cli-plugin-unit-jest": "3.6.3", | 37 | "@vue/cli-plugin-unit-jest": "3.6.3", |
| 36 | "@vue/cli-service": "3.6.0", | 38 | "@vue/cli-service": "3.6.0", |
| 37 | "@vue/test-utils": "1.0.0-beta.29", | 39 | "@vue/test-utils": "1.0.0-beta.29", |
| 38 | "autoprefixer": "^9.5.1", | 40 | "autoprefixer": "^9.5.1", |
| 41 | "babel-cli": "^6.26.0", | ||
| 39 | "babel-core": "7.0.0-bridge.0", | 42 | "babel-core": "7.0.0-bridge.0", |
| 40 | "babel-eslint": "10.0.1", | 43 | "babel-eslint": "10.0.1", |
| 41 | "babel-jest": "23.6.0", | 44 | "babel-jest": "23.6.0", |
| 45 | "babel-plugin-component": "^1.1.1", | ||
| 46 | "babel-preset-env": "^1.7.0", | ||
| 42 | "chalk": "2.4.2", | 47 | "chalk": "2.4.2", |
| 43 | "connect": "3.6.6", | 48 | "connect": "3.6.6", |
| 44 | "eslint": "5.15.3", | 49 | "eslint": "5.15.3", |
| 45 | "eslint-plugin-vue": "5.2.2", | 50 | "eslint-plugin-vue": "5.2.2", |
| 46 | "html-webpack-plugin": "3.2.0", | 51 | "html-webpack-plugin": "3.2.0", |
| 47 | "mockjs": "1.0.1-beta3", | 52 | "mockjs": "1.0.1-beta3", |
| 48 | "node-sass": "^4.9.0", | 53 | "node-sass": "^4.9.0", |
| 49 | "runjs": "^4.3.2", | 54 | "runjs": "^4.3.2", |
| 50 | "sass-loader": "^7.1.0", | 55 | "sass-loader": "^7.1.0", |
| 51 | "script-ext-html-webpack-plugin": "2.1.3", | 56 | "script-ext-html-webpack-plugin": "2.1.3", |
| 52 | "script-loader": "0.7.2", | 57 | "script-loader": "0.7.2", |
| 53 | "serve-static": "^1.13.2", | 58 | "serve-static": "^1.13.2", |
| 54 | "svg-sprite-loader": "4.1.3", | 59 | "svg-sprite-loader": "4.1.3", |
| 55 | "svgo": "1.2.2", | 60 | "svgo": "1.2.2", |
| 61 | "vue-schart": "^2.0.0", | ||
| 56 | "vue-template-compiler": "2.6.10" | 62 | "vue-template-compiler": "2.6.10" |
| 57 | }, | 63 | }, |
| 58 | "engines": { | 64 | "engines": { |
| 59 | "node": ">=8.9", | 65 | "node": ">=8.9", |
| 60 | "npm": ">= 3.0.0" | 66 | "npm": ">= 3.0.0" |
| 61 | }, | 67 | }, |
| 62 | "browserslist": [ | 68 | "browserslist": [ |
| 63 | "> 1%", | 69 | "> 1%", |
| 64 | "last 2 versions" | 70 | "last 2 versions" |
| 65 | ] | 71 | ] |
| 66 | } | 72 | } |
| 67 | 73 |
src/api/admin.js
| 1 | import request from '@/utils/request' | 1 | // import request from '@/utils/request' |
| 2 | |||
| 3 | export function login(data) { | ||
| 4 | console.log('login....', data) | ||
| 5 | return request({ | ||
| 6 | url: '/yp/user/login', | ||
| 7 | method: 'post', | ||
| 8 | data | ||
| 9 | }) | ||
| 10 | } | ||
| 11 | |||
| 12 | export function getInfo(token) { | ||
| 13 | console.log('getInfo....', token) | ||
| 14 | return request({ | ||
| 15 | url: '/yp/user/info', | ||
| 16 | method: 'get', | ||
| 17 | params: { token } | ||
| 18 | }) | ||
| 19 | } | ||
| 20 | |||
| 21 | export function logout() { | ||
| 22 | console.log('logout....') | ||
| 23 | return request({ | ||
| 24 | url: '/yp/user/logout', | ||
| 25 | method: 'post' | ||
| 26 | }) | ||
| 27 | } | ||
| 28 | 2 |
src/api/meta.js
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | export function listMeta(params) { | ||
| 4 | return request({ | ||
| 5 | url: '/yp/meta/list', | ||
| 6 | method: 'get', | ||
| 7 | params | ||
| 8 | }) | ||
| 9 | } | ||
| 10 | |||
| 11 | export function addMeta(params) { | ||
| 12 | return request({ | ||
| 13 | url: '/yp/meta/add', | ||
| 14 | method: 'get', | ||
| 15 | params | ||
| 16 | }) | ||
| 17 | } | ||
| 18 | |||
| 19 | export function delMeta(params) { | ||
| 20 | return request({ | ||
| 21 | url: '/yp/meta/del', | ||
| 22 | method: 'get', | ||
| 23 | params | ||
| 24 | }) | ||
| 25 | } | ||
| 26 | |||
| 27 | export function modiMeta(params) { | ||
| 28 | return request({ | ||
| 29 | url: '/yp/meta/modi', | ||
| 30 | method: 'get', | ||
| 31 | params | ||
| 32 | }) | ||
| 33 | } | ||
| 34 |
src/api/relation.js
| File was created | 1 | import request from '@/utils/request' | |
| 2 | |||
| 3 | export function build(params) { | ||
| 4 | return request({ | ||
| 5 | url: '/yp/relation/build', | ||
| 6 | method: 'get', | ||
| 7 | params | ||
| 8 | }) | ||
| 9 | } | ||
| 10 | |||
| 11 | export function del(params) { | ||
| 12 | return request({ | ||
| 13 | url: '/yp/relation/del', | ||
| 14 | method: 'get', | ||
| 15 | params | ||
| 16 | }) | ||
| 17 | } | ||
| 18 |
src/api/user.js
| 1 | import request from '@/utils/request' | 1 | import request from '@/utils/request' |
| 2 | 2 | ||
| 3 | export function login(data) { | 3 | export function login(data) { |
| 4 | console.log('login....', data) | 4 | console.log('login....', data) |
| 5 | return request({ | 5 | return request({ |
| 6 | url: '/yp/user/login', | 6 | url: '/yp/user/login', |
| 7 | method: 'post', | 7 | method: 'post', |
| 8 | data | 8 | data |
| 9 | }) | 9 | }) |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | export function getInfo(token) { | 12 | export function getInfo(token) { |
| 13 | console.log('getInfo....', token) | 13 | console.log('getInfo....', token) |
| 14 | return request({ | 14 | return request({ |
| 15 | url: '/yp/user/info', | 15 | url: '/yp/user/info', |
| 16 | method: 'get', | 16 | method: 'get', |
| 17 | params: { token } | 17 | params: { token } |
| 18 | }) | 18 | }) |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | export function list(token) { | 21 | export function list(token) { |
| 22 | console.log('listUser....', token) | 22 | console.log('listUser....', token) |
| 23 | return request({ | 23 | return request({ |
| 24 | url: '/yp/user/list', | 24 | url: '/yp/user/list', |
| 25 | method: 'get', | 25 | method: 'get', |
| 26 | params: { token } | 26 | params: { token } |
| 27 | }) | 27 | }) |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | export function add(token) { | ||
| 31 | console.log('addUser....', token) | ||
| 32 | return request({ | ||
| 33 | url: '/yp/user/add', | ||
| 34 | method: 'get', | ||
| 35 | params: { token } | ||
| 36 | }) | ||
| 37 | } | ||
| 38 | |||
| 39 | export function modi(token) { | ||
| 40 | console.log('modiUser....', token) | ||
| 41 | return request({ | ||
| 42 | url: '/yp/user/modi', | ||
| 43 | method: 'get', | ||
| 44 | params: { token } | ||
| 45 | }) | ||
| 46 | } | ||
| 47 | |||
| 30 | export function logout() { | 48 | export function logout() { |
| 31 | console.log('logout....') | 49 | console.log('logout....') |
| 32 | return request({ | 50 | return request({ |
| 33 | url: '/yp/user/logout', | 51 | url: '/yp/user/logout', |
| 34 | method: 'post' | 52 | method: 'post' |
| 35 | }) | 53 | }) |
| 36 | } | 54 | } |
| 37 | 55 |
src/assets/img/img.jpg
6 KB
src/assets/img/login-bg.jpg
68.9 KB
src/common/Header.vue
| File was created | 1 | <template> | |
| 2 | <div class="header"> | ||
| 3 | <!-- 折叠按钮 --> | ||
| 4 | <div class="collapse-btn" @click="collapseChage"> | ||
| 5 | <i v-if="!collapse" class="el-icon-s-fold"></i> | ||
| 6 | <i v-else class="el-icon-s-unfold"></i> | ||
| 7 | </div> | ||
| 8 | <div class="logo">后台管理系统</div> | ||
| 9 | <div class="header-right"> | ||
| 10 | <div class="header-user-con"> | ||
| 11 | <!-- 全屏显示 --> | ||
| 12 | <div class="btn-fullscreen" @click="handleFullScreen"> | ||
| 13 | <el-tooltip effect="dark" :content="fullscreen?`取消全屏`:`全屏`" placement="bottom"> | ||
| 14 | <i class="el-icon-rank"></i> | ||
| 15 | </el-tooltip> | ||
| 16 | </div> | ||
| 17 | <!-- 消息中心 --> | ||
| 18 | <div class="btn-bell"> | ||
| 19 | <el-tooltip | ||
| 20 | effect="dark" | ||
| 21 | :content="message?`有${message}条未读消息`:`消息中心`" | ||
| 22 | placement="bottom" | ||
| 23 | > | ||
| 24 | <router-link to="/tabs"> | ||
| 25 | <i class="el-icon-bell"></i> | ||
| 26 | </router-link> | ||
| 27 | </el-tooltip> | ||
| 28 | <span class="btn-bell-badge" v-if="message"></span> | ||
| 29 | </div> | ||
| 30 | <!-- 用户头像 --> | ||
| 31 | <div class="user-avator"> | ||
| 32 | <img src="../assets/img/img.jpg" /> | ||
| 33 | </div> | ||
| 34 | <!-- 用户名下拉菜单 --> | ||
| 35 | <el-dropdown class="user-name" trigger="click" @command="handleCommand"> | ||
| 36 | <span class="el-dropdown-link"> | ||
| 37 | {{username}} | ||
| 38 | <i class="el-icon-caret-bottom"></i> | ||
| 39 | </span> | ||
| 40 | <el-dropdown-menu slot="dropdown"> | ||
| 41 | <a href="https://github.com/lin-xin/vue-manage-system" target="_blank"> | ||
| 42 | <el-dropdown-item>项目仓库</el-dropdown-item> | ||
| 43 | </a> | ||
| 44 | <el-dropdown-item divided command="loginout">退出登录</el-dropdown-item> | ||
| 45 | </el-dropdown-menu> | ||
| 46 | </el-dropdown> | ||
| 47 | </div> | ||
| 48 | </div> | ||
| 49 | </div> | ||
| 50 | </template> | ||
| 51 | <script> | ||
| 52 | import bus from './bus'; | ||
| 53 | export default { | ||
| 54 | data() { | ||
| 55 | return { | ||
| 56 | collapse: false, | ||
| 57 | fullscreen: false, | ||
| 58 | name: 'linxin', | ||
| 59 | message: 2 | ||
| 60 | }; | ||
| 61 | }, | ||
| 62 | computed: { | ||
| 63 | username() { | ||
| 64 | let username = localStorage.getItem('ms_username'); | ||
| 65 | return username ? username : this.name; | ||
| 66 | } | ||
| 67 | }, | ||
| 68 | methods: { | ||
| 69 | // 用户名下拉菜单选择事件 | ||
| 70 | handleCommand(command) { | ||
| 71 | if (command == 'loginout') { | ||
| 72 | localStorage.removeItem('ms_username'); | ||
| 73 | this.$router.push('/login'); | ||
| 74 | } | ||
| 75 | }, | ||
| 76 | // 侧边栏折叠 | ||
| 77 | collapseChage() { | ||
| 78 | this.collapse = !this.collapse; | ||
| 79 | bus.$emit('collapse', this.collapse); | ||
| 80 | }, | ||
| 81 | // 全屏事件 | ||
| 82 | handleFullScreen() { | ||
| 83 | let element = document.documentElement; | ||
| 84 | if (this.fullscreen) { | ||
| 85 | if (document.exitFullscreen) { | ||
| 86 | document.exitFullscreen(); | ||
| 87 | } else if (document.webkitCancelFullScreen) { | ||
| 88 | document.webkitCancelFullScreen(); | ||
| 89 | } else if (document.mozCancelFullScreen) { | ||
| 90 | document.mozCancelFullScreen(); | ||
| 91 | } else if (document.msExitFullscreen) { | ||
| 92 | document.msExitFullscreen(); | ||
| 93 | } | ||
| 94 | } else { | ||
| 95 | if (element.requestFullscreen) { | ||
| 96 | element.requestFullscreen(); | ||
| 97 | } else if (element.webkitRequestFullScreen) { | ||
| 98 | element.webkitRequestFullScreen(); | ||
| 99 | } else if (element.mozRequestFullScreen) { | ||
| 100 | element.mozRequestFullScreen(); | ||
| 101 | } else if (element.msRequestFullscreen) { | ||
| 102 | // IE11 | ||
| 103 | element.msRequestFullscreen(); | ||
| 104 | } | ||
| 105 | } | ||
| 106 | this.fullscreen = !this.fullscreen; | ||
| 107 | } | ||
| 108 | }, | ||
| 109 | mounted() { | ||
| 110 | if (document.body.clientWidth < 1500) { | ||
| 111 | this.collapseChage(); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | }; | ||
| 115 | </script> | ||
| 116 | <style scoped> | ||
| 117 | .header { | ||
| 118 | position: relative; | ||
| 119 | box-sizing: border-box; | ||
| 120 | width: 100%; | ||
| 121 | height: 70px; | ||
| 122 | font-size: 22px; | ||
| 123 | color: #fff; | ||
| 124 | } | ||
| 125 | .collapse-btn { | ||
| 126 | float: left; | ||
| 127 | padding: 0 21px; | ||
| 128 | cursor: pointer; | ||
| 129 | line-height: 70px; | ||
| 130 | } | ||
| 131 | .header .logo { | ||
| 132 | float: left; | ||
| 133 | width: 250px; | ||
| 134 | line-height: 70px; | ||
| 135 | } | ||
| 136 | .header-right { | ||
| 137 | float: right; | ||
| 138 | padding-right: 50px; | ||
| 139 | } | ||
| 140 | .header-user-con { | ||
| 141 | display: flex; | ||
| 142 | height: 70px; | ||
| 143 | align-items: center; | ||
| 144 | } | ||
| 145 | .btn-fullscreen { | ||
| 146 | transform: rotate(45deg); | ||
| 147 | margin-right: 5px; | ||
| 148 | font-size: 24px; | ||
| 149 | } | ||
| 150 | .btn-bell, | ||
| 151 | .btn-fullscreen { | ||
| 152 | position: relative; | ||
| 153 | width: 30px; | ||
| 154 | height: 30px; | ||
| 155 | text-align: center; | ||
| 156 | border-radius: 15px; | ||
| 157 | cursor: pointer; | ||
| 158 | } | ||
| 159 | .btn-bell-badge { | ||
| 160 | position: absolute; | ||
| 161 | right: 0; | ||
| 162 | top: -2px; | ||
| 163 | width: 8px; | ||
| 164 | height: 8px; | ||
| 165 | border-radius: 4px; | ||
| 166 | background: #f56c6c; | ||
| 167 | color: #fff; | ||
| 168 | } | ||
| 169 | .btn-bell .el-icon-bell { | ||
| 170 | color: #fff; | ||
| 171 | } | ||
| 172 | .user-name { | ||
| 173 | margin-left: 10px; | ||
| 174 | } | ||
| 175 | .user-avator { | ||
| 176 | margin-left: 20px; | ||
| 177 | } | ||
| 178 | .user-avator img { | ||
| 179 | display: block; | ||
| 180 | width: 40px; | ||
| 181 | height: 40px; | ||
| 182 | border-radius: 50%; | ||
| 183 | } | ||
| 184 | .el-dropdown-link { | ||
| 185 | color: #fff; | ||
| 186 | cursor: pointer; | ||
| 187 | } | ||
| 188 | .el-dropdown-menu__item { | ||
| 189 | text-align: center; | ||
| 190 | } | ||
| 191 | </style> |
src/common/Home.vue
| File was created | 1 | <template> | |
| 2 | <div class="wrapper"> | ||
| 3 | <v-head></v-head> | ||
| 4 | <v-sidebar></v-sidebar> | ||
| 5 | <div class="content-box" :class="{'content-collapse':collapse}"> | ||
| 6 | <v-tags></v-tags> | ||
| 7 | <div class="content"> | ||
| 8 | <transition name="move" mode="out-in"> | ||
| 9 | <keep-alive :include="tagsList"> | ||
| 10 | <router-view></router-view> | ||
| 11 | </keep-alive> | ||
| 12 | </transition> | ||
| 13 | <el-backtop target=".content"></el-backtop> | ||
| 14 | </div> | ||
| 15 | </div> | ||
| 16 | </div> | ||
| 17 | </template> | ||
| 18 | |||
| 19 | <script> | ||
| 20 | import vHead from './Header.vue'; | ||
| 21 | import vSidebar from './Sidebar.vue'; | ||
| 22 | import vTags from './Tags.vue'; | ||
| 23 | import bus from './bus'; | ||
| 24 | export default { | ||
| 25 | data() { | ||
| 26 | return { | ||
| 27 | tagsList: [], | ||
| 28 | collapse: false | ||
| 29 | }; | ||
| 30 | }, | ||
| 31 | components: { | ||
| 32 | vHead, | ||
| 33 | vSidebar, | ||
| 34 | vTags | ||
| 35 | }, | ||
| 36 | created() { | ||
| 37 | bus.$on('collapse-content', msg => { | ||
| 38 | this.collapse = msg; | ||
| 39 | }); | ||
| 40 | // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 | ||
| 41 | bus.$on('tags', msg => { | ||
| 42 | let arr = []; | ||
| 43 | for (let i = 0, len = msg.length; i < len; i++) { | ||
| 44 | msg[i].name && arr.push(msg[i].name); | ||
| 45 | } | ||
| 46 | this.tagsList = arr; | ||
| 47 | }); | ||
| 48 | } | ||
| 49 | }; | ||
| 50 | </script> |
src/common/Sidebar.vue
| File was created | 1 | <template> | |
| 2 | <div class="sidebar"> | ||
| 3 | <el-menu | ||
| 4 | class="sidebar-el-menu" | ||
| 5 | :default-active="onRoutes" | ||
| 6 | :collapse="collapse" | ||
| 7 | background-color="#324157" | ||
| 8 | text-color="#bfcbd9" | ||
| 9 | active-text-color="#20a0ff" | ||
| 10 | unique-opened | ||
| 11 | router | ||
| 12 | > | ||
| 13 | <template v-for="item in items"> | ||
| 14 | <template v-if="item.subs"> | ||
| 15 | <el-submenu :index="item.index" :key="item.index"> | ||
| 16 | <template slot="title"> | ||
| 17 | <i :class="item.icon"></i> | ||
| 18 | <span slot="title">{{ item.title }}</span> | ||
| 19 | </template> | ||
| 20 | <template v-for="subItem in item.subs"> | ||
| 21 | <el-submenu | ||
| 22 | v-if="subItem.subs" | ||
| 23 | :index="subItem.index" | ||
| 24 | :key="subItem.index" | ||
| 25 | > | ||
| 26 | <template slot="title">{{ subItem.title }}</template> | ||
| 27 | <el-menu-item | ||
| 28 | v-for="(threeItem,i) in subItem.subs" | ||
| 29 | :key="i" | ||
| 30 | :index="threeItem.index" | ||
| 31 | >{{ threeItem.title }}</el-menu-item> | ||
| 32 | </el-submenu> | ||
| 33 | <el-menu-item | ||
| 34 | v-else | ||
| 35 | :index="subItem.index" | ||
| 36 | :key="subItem.index" | ||
| 37 | >{{ subItem.title }}</el-menu-item> | ||
| 38 | </template> | ||
| 39 | </el-submenu> | ||
| 40 | </template> | ||
| 41 | <template v-else> | ||
| 42 | <el-menu-item :index="item.index" :key="item.index"> | ||
| 43 | <i :class="item.icon"></i> | ||
| 44 | <span slot="title">{{ item.title }}</span> | ||
| 45 | </el-menu-item> | ||
| 46 | </template> | ||
| 47 | </template> | ||
| 48 | </el-menu> | ||
| 49 | </div> | ||
| 50 | </template> | ||
| 51 | |||
| 52 | <script> | ||
| 53 | import bus from './bus'; | ||
| 54 | export default { | ||
| 55 | data() { | ||
| 56 | return { | ||
| 57 | collapse: false, | ||
| 58 | items: [ | ||
| 59 | { | ||
| 60 | icon: 'el-icon-lx-home', | ||
| 61 | index: 'dashboard', | ||
| 62 | title: '系统首页' | ||
| 63 | }, | ||
| 64 | { | ||
| 65 | icon: 'el-icon-lx-cascades', | ||
| 66 | index: 'table', | ||
| 67 | title: '基础表格' | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | icon: 'el-icon-lx-copy', | ||
| 71 | index: 'tabs', | ||
| 72 | title: 'tab选项卡' | ||
| 73 | }, | ||
| 74 | { | ||
| 75 | icon: 'el-icon-lx-calendar', | ||
| 76 | index: '3', | ||
| 77 | title: '表单相关', | ||
| 78 | subs: [ | ||
| 79 | { | ||
| 80 | index: 'form', | ||
| 81 | title: '基本表单' | ||
| 82 | }, | ||
| 83 | { | ||
| 84 | index: '3-2', | ||
| 85 | title: '三级菜单', | ||
| 86 | subs: [ | ||
| 87 | { | ||
| 88 | index: 'editor', | ||
| 89 | title: '富文本编辑器' | ||
| 90 | }, | ||
| 91 | { | ||
| 92 | index: 'markdown', | ||
| 93 | title: 'markdown编辑器' | ||
| 94 | } | ||
| 95 | ] | ||
| 96 | }, | ||
| 97 | { | ||
| 98 | index: 'upload', | ||
| 99 | title: '文件上传' | ||
| 100 | } | ||
| 101 | ] | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | icon: 'el-icon-lx-emoji', | ||
| 105 | index: 'icon', | ||
| 106 | title: '自定义图标' | ||
| 107 | }, | ||
| 108 | { | ||
| 109 | icon: 'el-icon-pie-chart', | ||
| 110 | index: 'charts', | ||
| 111 | title: 'schart图表' | ||
| 112 | }, | ||
| 113 | { | ||
| 114 | icon: 'el-icon-rank', | ||
| 115 | index: '6', | ||
| 116 | title: '拖拽组件', | ||
| 117 | subs: [ | ||
| 118 | { | ||
| 119 | index: 'drag', | ||
| 120 | title: '拖拽列表' | ||
| 121 | }, | ||
| 122 | { | ||
| 123 | index: 'dialog', | ||
| 124 | title: '拖拽弹框' | ||
| 125 | } | ||
| 126 | ] | ||
| 127 | }, | ||
| 128 | { | ||
| 129 | icon: 'el-icon-lx-global', | ||
| 130 | index: 'i18n', | ||
| 131 | title: '国际化功能' | ||
| 132 | }, | ||
| 133 | { | ||
| 134 | icon: 'el-icon-lx-warn', | ||
| 135 | index: '7', | ||
| 136 | title: '错误处理', | ||
| 137 | subs: [ | ||
| 138 | { | ||
| 139 | index: 'permission', | ||
| 140 | title: '权限测试' | ||
| 141 | }, | ||
| 142 | { | ||
| 143 | index: '404', | ||
| 144 | title: '404页面' | ||
| 145 | } | ||
| 146 | ] | ||
| 147 | }, | ||
| 148 | { | ||
| 149 | icon: 'el-icon-lx-redpacket_fill', | ||
| 150 | index: '/donate', | ||
| 151 | title: '支持作者' | ||
| 152 | } | ||
| 153 | ] | ||
| 154 | }; | ||
| 155 | }, | ||
| 156 | computed: { | ||
| 157 | onRoutes() { | ||
| 158 | return this.$route.path.replace('/', ''); | ||
| 159 | } | ||
| 160 | }, | ||
| 161 | created() { | ||
| 162 | // 通过 Event Bus 进行组件间通信,来折叠侧边栏 | ||
| 163 | bus.$on('collapse', msg => { | ||
| 164 | this.collapse = msg; | ||
| 165 | bus.$emit('collapse-content', msg); | ||
| 166 | }); | ||
| 167 | } | ||
| 168 | }; | ||
| 169 | </script> | ||
| 170 | |||
| 171 | <style scoped> | ||
| 172 | .sidebar { | ||
| 173 | display: block; | ||
| 174 | position: absolute; | ||
| 175 | left: 0; | ||
| 176 | top: 70px; | ||
| 177 | bottom: 0; | ||
| 178 | overflow-y: scroll; | ||
| 179 | } | ||
| 180 | .sidebar::-webkit-scrollbar { | ||
| 181 | width: 0; | ||
| 182 | } | ||
| 183 | .sidebar-el-menu:not(.el-menu--collapse) { | ||
| 184 | width: 250px; | ||
| 185 | } | ||
| 186 | .sidebar > ul { | ||
| 187 | height: 100%; | ||
| 188 | } | ||
| 189 | </style> |
src/common/Tags.vue
| File was created | 1 | <template> | |
| 2 | <div class="tags" v-if="showTags"> | ||
| 3 | <ul> | ||
| 4 | <li class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index"> | ||
| 5 | <router-link :to="item.path" class="tags-li-title"> | ||
| 6 | {{item.title}} | ||
| 7 | </router-link> | ||
| 8 | <span class="tags-li-icon" @click="closeTags(index)"><i class="el-icon-close"></i></span> | ||
| 9 | </li> | ||
| 10 | </ul> | ||
| 11 | <div class="tags-close-box"> | ||
| 12 | <el-dropdown @command="handleTags"> | ||
| 13 | <el-button size="mini" type="primary"> | ||
| 14 | 标签选项<i class="el-icon-arrow-down el-icon--right"></i> | ||
| 15 | </el-button> | ||
| 16 | <el-dropdown-menu size="small" slot="dropdown"> | ||
| 17 | <el-dropdown-item command="other">关闭其他</el-dropdown-item> | ||
| 18 | <el-dropdown-item command="all">关闭所有</el-dropdown-item> | ||
| 19 | </el-dropdown-menu> | ||
| 20 | </el-dropdown> | ||
| 21 | </div> | ||
| 22 | </div> | ||
| 23 | </template> | ||
| 24 | |||
| 25 | <script> | ||
| 26 | import bus from './bus'; | ||
| 27 | export default { | ||
| 28 | data() { | ||
| 29 | return { | ||
| 30 | tagsList: [] | ||
| 31 | } | ||
| 32 | }, | ||
| 33 | methods: { | ||
| 34 | isActive(path) { | ||
| 35 | return path === this.$route.fullPath; | ||
| 36 | }, | ||
| 37 | // 关闭单个标签 | ||
| 38 | closeTags(index) { | ||
| 39 | const delItem = this.tagsList.splice(index, 1)[0]; | ||
| 40 | const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]; | ||
| 41 | if (item) { | ||
| 42 | delItem.path === this.$route.fullPath && this.$router.push(item.path); | ||
| 43 | }else{ | ||
| 44 | this.$router.push('/'); | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | // 关闭全部标签 | ||
| 48 | closeAll(){ | ||
| 49 | this.tagsList = []; | ||
| 50 | this.$router.push('/'); | ||
| 51 | }, | ||
| 52 | // 关闭其他标签 | ||
| 53 | closeOther(){ | ||
| 54 | const curItem = this.tagsList.filter(item => { | ||
| 55 | return item.path === this.$route.fullPath; | ||
| 56 | }) | ||
| 57 | this.tagsList = curItem; | ||
| 58 | }, | ||
| 59 | // 设置标签 | ||
| 60 | setTags(route){ | ||
| 61 | const isExist = this.tagsList.some(item => { | ||
| 62 | return item.path === route.fullPath; | ||
| 63 | }) | ||
| 64 | if(!isExist){ | ||
| 65 | if(this.tagsList.length >= 8){ | ||
| 66 | this.tagsList.shift(); | ||
| 67 | } | ||
| 68 | this.tagsList.push({ | ||
| 69 | title: route.meta.title, | ||
| 70 | path: route.fullPath, | ||
| 71 | name: route.matched[1].components.default.name | ||
| 72 | }) | ||
| 73 | } | ||
| 74 | bus.$emit('tags', this.tagsList); | ||
| 75 | }, | ||
| 76 | handleTags(command){ | ||
| 77 | command === 'other' ? this.closeOther() : this.closeAll(); | ||
| 78 | } | ||
| 79 | }, | ||
| 80 | computed: { | ||
| 81 | showTags() { | ||
| 82 | return this.tagsList.length > 0; | ||
| 83 | } | ||
| 84 | }, | ||
| 85 | watch:{ | ||
| 86 | $route(newValue, oldValue){ | ||
| 87 | this.setTags(newValue); | ||
| 88 | } | ||
| 89 | }, | ||
| 90 | created(){ | ||
| 91 | this.setTags(this.$route); | ||
| 92 | // 监听关闭当前页面的标签页 | ||
| 93 | bus.$on('close_current_tags', () => { | ||
| 94 | for (let i = 0, len = this.tagsList.length; i < len; i++) { | ||
| 95 | const item = this.tagsList[i]; | ||
| 96 | if(item.path === this.$route.fullPath){ | ||
| 97 | if(i < len - 1){ | ||
| 98 | this.$router.push(this.tagsList[i+1].path); | ||
| 99 | }else if(i > 0){ | ||
| 100 | this.$router.push(this.tagsList[i-1].path); | ||
| 101 | }else{ | ||
| 102 | this.$router.push('/'); | ||
| 103 | } | ||
| 104 | this.tagsList.splice(i, 1); | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | }) | ||
| 109 | } | ||
| 110 | } | ||
| 111 | </script> | ||
| 112 | |||
| 113 | |||
| 114 | <style> | ||
| 115 | .tags { | ||
| 116 | position: relative; | ||
| 117 | height: 30px; | ||
| 118 | overflow: hidden; | ||
| 119 | background: #fff; | ||
| 120 | padding-right: 120px; | ||
| 121 | box-shadow: 0 5px 10px #ddd; | ||
| 122 | } | ||
| 123 | .tags ul { | ||
| 124 | box-sizing: border-box; | ||
| 125 | width: 100%; | ||
| 126 | height: 100%; | ||
| 127 | } | ||
| 128 | .tags-li { | ||
| 129 | float: left; | ||
| 130 | margin: 3px 5px 2px 3px; | ||
| 131 | border-radius: 3px; | ||
| 132 | font-size: 12px; | ||
| 133 | overflow: hidden; | ||
| 134 | cursor: pointer; | ||
| 135 | height: 23px; | ||
| 136 | line-height: 23px; | ||
| 137 | border: 1px solid #e9eaec; | ||
| 138 | background: #fff; | ||
| 139 | padding: 0 5px 0 12px; | ||
| 140 | vertical-align: middle; | ||
| 141 | color: #666; | ||
| 142 | -webkit-transition: all .3s ease-in; | ||
| 143 | -moz-transition: all .3s ease-in; | ||
| 144 | transition: all .3s ease-in; | ||
| 145 | } | ||
| 146 | .tags-li:not(.active):hover { | ||
| 147 | background: #f8f8f8; | ||
| 148 | } | ||
| 149 | .tags-li.active { | ||
| 150 | color: #fff; | ||
| 151 | } | ||
| 152 | .tags-li-title { | ||
| 153 | float: left; | ||
| 154 | max-width: 80px; | ||
| 155 | overflow: hidden; | ||
| 156 | white-space: nowrap; | ||
| 157 | text-overflow: ellipsis; | ||
| 158 | margin-right: 5px; | ||
| 159 | color: #666; | ||
| 160 | } | ||
| 161 | .tags-li.active .tags-li-title { | ||
| 162 | color: #fff; | ||
| 163 | } | ||
| 164 | .tags-close-box { | ||
| 165 | position: absolute; | ||
| 166 | right: 0; | ||
| 167 | top: 0; | ||
| 168 | box-sizing: border-box; | ||
| 169 | padding-top: 1px; | ||
| 170 | text-align: center; | ||
| 171 | width: 110px; | ||
| 172 | height: 30px; | ||
| 173 | background: #fff; | ||
| 174 | box-shadow: -3px 0 15px 3px rgba(0, 0, 0, .1); | ||
| 175 | z-index: 10; | ||
| 176 | } | ||
| 177 | </style> |
src/common/bus.js
| File was created | 1 | import Vue from 'vue'; | |
| 2 | |||
| 3 | // 使用 Event Bus | ||
| 4 | const bus = new Vue(); | ||
| 5 | |||
| 6 | export default bus; | ||
| 7 |
src/common/directives.js
| File was created | 1 | import Vue from 'vue'; | |
| 2 | |||
| 3 | // v-dialogDrag: 弹窗拖拽属性 | ||
| 4 | Vue.directive('dialogDrag', { | ||
| 5 | bind(el, binding, vnode, oldVnode) { | ||
| 6 | const dialogHeaderEl = el.querySelector('.el-dialog__header'); | ||
| 7 | const dragDom = el.querySelector('.el-dialog'); | ||
| 8 | |||
| 9 | dialogHeaderEl.style.cssText += ';cursor:move;' | ||
| 10 | dragDom.style.cssText += ';top:0px;' | ||
| 11 | |||
| 12 | // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); | ||
| 13 | const sty = (() => { | ||
| 14 | if (window.document.currentStyle) { | ||
| 15 | return (dom, attr) => dom.currentStyle[attr]; | ||
| 16 | } else { | ||
| 17 | return (dom, attr) => getComputedStyle(dom, false)[attr]; | ||
| 18 | } | ||
| 19 | })() | ||
| 20 | |||
| 21 | dialogHeaderEl.onmousedown = (e) => { | ||
| 22 | // 鼠标按下,计算当前元素距离可视区的距离 | ||
| 23 | const disX = e.clientX - dialogHeaderEl.offsetLeft; | ||
| 24 | const disY = e.clientY - dialogHeaderEl.offsetTop; | ||
| 25 | |||
| 26 | const screenWidth = document.body.clientWidth; // body当前宽度 | ||
| 27 | const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) | ||
| 28 | |||
| 29 | const dragDomWidth = dragDom.offsetWidth; // 对话框宽度 | ||
| 30 | const dragDomheight = dragDom.offsetHeight; // 对话框高度 | ||
| 31 | |||
| 32 | const minDragDomLeft = dragDom.offsetLeft; | ||
| 33 | const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; | ||
| 34 | |||
| 35 | const minDragDomTop = dragDom.offsetTop; | ||
| 36 | const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; | ||
| 37 | |||
| 38 | |||
| 39 | // 获取到的值带px 正则匹配替换 | ||
| 40 | let styL = sty(dragDom, 'left'); | ||
| 41 | let styT = sty(dragDom, 'top'); | ||
| 42 | |||
| 43 | // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px | ||
| 44 | if (styL.includes('%')) { | ||
| 45 | styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100); | ||
| 46 | styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100); | ||
| 47 | } else { | ||
| 48 | styL = +styL.replace(/\px/g, ''); | ||
| 49 | styT = +styT.replace(/\px/g, ''); | ||
| 50 | }; | ||
| 51 | |||
| 52 | document.onmousemove = function (e) { | ||
| 53 | // 通过事件委托,计算移动的距离 | ||
| 54 | let left = e.clientX - disX; | ||
| 55 | let top = e.clientY - disY; | ||
| 56 | |||
| 57 | // 边界处理 | ||
| 58 | if (-(left) > minDragDomLeft) { | ||
| 59 | left = -(minDragDomLeft); | ||
| 60 | } else if (left > maxDragDomLeft) { | ||
| 61 | left = maxDragDomLeft; | ||
| 62 | } | ||
| 63 | |||
| 64 | if (-(top) > minDragDomTop) { | ||
| 65 | top = -(minDragDomTop); | ||
| 66 | } else if (top > maxDragDomTop) { | ||
| 67 | top = maxDragDomTop; | ||
| 68 | } | ||
| 69 | |||
| 70 | // 移动当前元素 | ||
| 71 | dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`; | ||
| 72 | }; | ||
| 73 | |||
| 74 | document.onmouseup = function (e) { | ||
| 75 | document.onmousemove = null; | ||
| 76 | document.onmouseup = null; | ||
| 77 | }; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | }) |
src/common/i18n.js
| File was created | 1 | export const messages = { | |
| 2 | 'zh': { | ||
| 3 | i18n: { | ||
| 4 | breadcrumb: '国际化产品', | ||
| 5 | tips: '通过切换语言按钮,来改变当前内容的语言。', | ||
| 6 | btn: '切换英文', | ||
| 7 | title1: '常用用法', | ||
| 8 | p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。', | ||
| 9 | p2: '没有什么比信念更能支撑我们度过艰难的时光了。', | ||
| 10 | p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。', | ||
| 11 | title2: '组件插值', | ||
| 12 | info: 'Element组件需要国际化,请参考 {action}。', | ||
| 13 | value: '文档' | ||
| 14 | } | ||
| 15 | }, | ||
| 16 | 'en': { | ||
| 17 | i18n: { | ||
| 18 | breadcrumb: 'International Products', | ||
| 19 | tips: 'Click on the button to change the current language. ', | ||
| 20 | btn: 'Switch Chinese', | ||
| 21 | title1: 'Common usage', | ||
| 22 | p1: "If you reveal your secrets to the wind you should not blame the wind for revealing them to the trees.", | ||
| 23 | p2: "Nothing can help us endure dark times better than our faith. ", | ||
| 24 | p3: "If you can do what you do best and be happy, you're further along in life than most people.", | ||
| 25 | title2: 'Component interpolation', | ||
| 26 | info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.', | ||
| 27 | value: 'documentation' | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } |
src/layout/components/Navbar.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="navbar"> | 2 | <div class="navbar"> |
| 3 | <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> | 3 | <hamburger |
| 4 | :is-active="sidebar.opened" | ||
| 5 | class="hamburger-container" | ||
| 6 | @toggleClick="toggleSideBar" | ||
| 7 | /> | ||
| 4 | 8 | ||
| 5 | <breadcrumb class="breadcrumb-container" /> | 9 | <breadcrumb class="breadcrumb-container" /> |
| 6 | 10 | ||
| 7 | <div class="right-menu"> | 11 | <div class="right-menu"> |
| 8 | 语言设置 | 12 | <el-menu |
| 9 | <el-dropdown class="avatar-container" trigger="click"> | 13 | :default-active="activeIndex" |
| 10 | <div class="avatar-wrapper"> | 14 | class="el-menu-demo" |
| 11 | <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> | 15 | mode="horizontal" |
| 12 | <i class="el-icon-caret-bottom" /> | 16 | @select="handleSelect" |
| 13 | </div> | 17 | > |
| 14 | <el-dropdown-menu slot="dropdown" class="user-dropdown"> | 18 | <el-menu-item index="1"> |
| 15 | <router-link to="/"> | 19 | <i class="el-icon-bell"></i>通知中心 |
| 16 | <el-dropdown-item> | 20 | <el-badge class="mark" :value="12" /> |
| 17 | Home | 21 | </el-menu-item> |
| 18 | </el-dropdown-item> | 22 | <el-submenu index="2"> |
| 19 | </router-link> | 23 | <template slot="title"> |
| 20 | <router-link to="/seting"> | 24 | <i class="el-icon-custom"></i>个人设置 |
| 21 | <el-dropdown-item> | 25 | </template> |
| 22 | 个人设置 | 26 | <el-menu-item index="2-1">选项1</el-menu-item> |
| 23 | </el-dropdown-item> | 27 | <el-menu-item index="2-2">选项2</el-menu-item> |
| 24 | </router-link> | 28 | <el-menu-item index="2-3">选项3</el-menu-item> |
| 25 | <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> | 29 | </el-submenu> |
| 30 | <el-dropdown class="avatar-container" trigger="click"> | ||
| 31 | <div class="avatar-wrapper"> | ||
| 32 | <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar" /> | ||
| 33 | <i class="el-icon-caret-bottom" /> | ||
| 34 | </div> | ||
| 35 | <el-dropdown-menu slot="dropdown" class="user-dropdown"> | ||
| 36 | <router-link to="/"> | ||
| 37 | <el-dropdown-item>Home</el-dropdown-item> | ||
| 38 | </router-link> | ||
| 39 | <router-link to="/seting"> | ||
| 40 | <el-dropdown-item>个人设置</el-dropdown-item> | ||
| 41 | </router-link> | ||
| 42 | <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> | ||
| 26 | <el-dropdown-item>Github</el-dropdown-item> | 43 | <el-dropdown-item>Github</el-dropdown-item> |
| 27 | </a> --> | 44 | </a>--> |
| 28 | <!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> | 45 | <!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> |
| 29 | <el-dropdown-item>Docs</el-dropdown-item> | 46 | <el-dropdown-item>Docs</el-dropdown-item> |
| 30 | </a> --> | 47 | </a>--> |
| 31 | <el-dropdown-item divided @click.native="logout"> | 48 | <el-dropdown-item divided @click.native="logout"> |
| 32 | <span style="display:block;">退出系统</span> | 49 | <span style="display:block;">退出系统</span> |
| 33 | </el-dropdown-item> | 50 | </el-dropdown-item> |
| 34 | </el-dropdown-menu> | 51 | </el-dropdown-menu> |
| 35 | </el-dropdown> | 52 | </el-dropdown> |
| 53 | <el-menu-item index="3" disabled>ddd</el-menu-item> | ||
| 54 | <el-menu-item index="4"> | ||
| 55 | <a href="https://glass.xiuyetang.com" target="_blank">跳到外部链接</a> | ||
| 56 | </el-menu-item> | ||
| 57 | </el-menu> | ||
| 36 | </div> | 58 | </div> |
| 37 | </div> | 59 | </div> |
| 38 | </template> | 60 | </template> |
| 39 | 61 | ||
| 40 | <script> | 62 | <script> |
| 41 | import { mapGetters } from 'vuex' | 63 | import { mapGetters } from "vuex"; |
| 42 | import Breadcrumb from '@/components/Breadcrumb' | 64 | import Breadcrumb from "@/components/Breadcrumb"; |
| 43 | import Hamburger from '@/components/Hamburger' | 65 | import Hamburger from "@/components/Hamburger"; |
| 44 | 66 | ||
| 45 | export default { | 67 | export default { |
| 46 | components: { | 68 | components: { |
| 47 | Breadcrumb, | 69 | Breadcrumb, |
| 48 | Hamburger | 70 | Hamburger |
| 49 | }, | 71 | }, |
| 50 | computed: { | 72 | computed: { |
| 51 | ...mapGetters([ | 73 | ...mapGetters(["sidebar", "avatar"]) |
| 52 | 'sidebar', | ||
| 53 | 'avatar' | ||
| 54 | ]) | ||
| 55 | }, | 74 | }, |
| 56 | methods: { | 75 | methods: { |
| 57 | toggleSideBar() { | 76 | toggleSideBar() { |
| 58 | this.$store.dispatch('app/toggleSideBar') | 77 | this.$store.dispatch("app/toggleSideBar"); |
| 59 | }, | 78 | }, |
| 60 | async logout() { | 79 | async logout() { |
| 61 | await this.$store.dispatch('user/logout') | 80 | await this.$store.dispatch("user/logout"); |
| 62 | this.$router.push(`/login?redirect=${this.$route.fullPath}`) | 81 | this.$router.push(`/login?redirect=${this.$route.fullPath}`); |
| 63 | } | 82 | } |
| 64 | } | 83 | } |
| 65 | } | 84 | }; |
| 66 | </script> | 85 | </script> |
| 67 | 86 | ||
| 68 | <style lang="scss" scoped> | 87 | <style lang="scss" scoped> |
| 88 | .item { | ||
| 89 | margin-top: 10px; | ||
| 90 | margin-right: 20px; | ||
| 91 | } | ||
| 69 | .navbar { | 92 | .navbar { |
| 70 | height: 50px; | 93 | height: 50px; |
| 71 | overflow: hidden; | 94 | overflow: hidden; |
| 72 | position: relative; | 95 | position: relative; |
| 73 | background: #fff; | 96 | background: #fff; |
| 74 | box-shadow: 0 1px 4px rgba(0,21,41,.08); | 97 | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); |
| 75 | 98 | ||
| 76 | .hamburger-container { | 99 | .hamburger-container { |
| 77 | line-height: 46px; | 100 | line-height: 46px; |
| 78 | height: 100%; | 101 | height: 100%; |
| 79 | float: left; | 102 | float: left; |
| 80 | cursor: pointer; | 103 | cursor: pointer; |
| 81 | transition: background .3s; | 104 | transition: background 0.3s; |
| 82 | -webkit-tap-highlight-color:transparent; | 105 | -webkit-tap-highlight-color: transparent; |
| 83 | 106 | ||
| 84 | &:hover { | 107 | &:hover { |
| 85 | background: rgba(0, 0, 0, .025) | 108 | background: rgba(0, 0, 0, 0.025); |
| 86 | } | 109 | } |
| 87 | } | 110 | } |
| 88 | 111 | ||
| 89 | .breadcrumb-container { | 112 | .breadcrumb-container { |
| 90 | float: left; | 113 | float: left; |
| 91 | } | 114 | } |
| 92 | 115 | ||
| 93 | .right-menu { | 116 | .right-menu { |
| 94 | float: right; | 117 | float: right; |
| 95 | height: 100%; | 118 | height: 100%; |
| 96 | line-height: 50px; | 119 | line-height: 50px; |
| 97 | 120 | ||
| 98 | &:focus { | 121 | &:focus { |
| 99 | outline: none; | 122 | outline: none; |
| 100 | } | 123 | } |
| 101 | 124 | ||
| 102 | .right-menu-item { | 125 | .right-menu-item { |
| 103 | display: inline-block; | 126 | display: inline-block; |
| 104 | padding: 0 8px; | 127 | padding: 0 8px; |
| 105 | height: 100%; | 128 | height: 100%; |
| 106 | font-size: 18px; | 129 | font-size: 18px; |
| 107 | color: #5a5e66; | 130 | color: #5a5e66; |
| 108 | vertical-align: text-bottom; | 131 | vertical-align: text-bottom; |
| 109 | 132 | ||
| 110 | &.hover-effect { | 133 | &.hover-effect { |
| 111 | cursor: pointer; | 134 | cursor: pointer; |
| 112 | transition: background .3s; | 135 | transition: background 0.3s; |
| 113 | 136 | ||
| 114 | &:hover { | 137 | &:hover { |
| 115 | background: rgba(0, 0, 0, .025) | 138 | background: rgba(0, 0, 0, 0.025); |
| 116 | } | 139 | } |
| 117 | } | 140 | } |
| 118 | } | 141 | } |
| 119 | 142 | ||
| 120 | .avatar-container { | 143 | .avatar-container { |
| 121 | margin-right: 30px; | 144 | margin-right: 30px; |
| 122 | 145 | ||
| 123 | .avatar-wrapper { | 146 | .avatar-wrapper { |
| 124 | margin-top: 5px; | 147 | margin-top: 5px; |
| 125 | position: relative; | 148 | position: relative; |
| 126 | 149 | ||
| 127 | .user-avatar { | 150 | .user-avatar { |
| 128 | cursor: pointer; | 151 | cursor: pointer; |
| 129 | width: 40px; | 152 | width: 40px; |
| 130 | height: 40px; | 153 | height: 40px; |
| 131 | border-radius: 10px; | 154 | border-radius: 10px; |
| 132 | } | 155 | } |
| 133 | 156 | ||
| 134 | .el-icon-caret-bottom { | 157 | .el-icon-caret-bottom { |
| 135 | cursor: pointer; | 158 | cursor: pointer; |
| 136 | position: absolute; | 159 | position: absolute; |
| 137 | right: -20px; | 160 | right: -20px; |
| 138 | top: 25px; | 161 | top: 25px; |
| 139 | font-size: 12px; | 162 | font-size: 12px; |
| 140 | } | 163 | } |
| 141 | } | 164 | } |
| 142 | } | 165 | } |
| 143 | } | 166 | } |
src/layout/components/index.js
| 1 | // export { default as Navbar } from '../../common/Header' | ||
| 1 | export { default as Navbar } from './Navbar' | 2 | export { default as Navbar } from './Navbar' |
| 2 | export { default as Sidebar } from './Sidebar' | 3 | export { default as Sidebar } from './Sidebar' |
| 3 | export { default as AppMain } from './AppMain' | 4 | export { default as AppMain } from './AppMain' |
| 4 | 5 |
src/main.js
| 1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
| 2 | 2 | ||
| 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets |
| 4 | 4 | ||
| 5 | import ElementUI from 'element-ui' | 5 | import ElementUI from 'element-ui' |
| 6 | import 'element-ui/lib/theme-chalk/index.css' | 6 | import 'element-ui/lib/theme-chalk/index.css' |
| 7 | import locale from 'element-ui/lib/locale/lang/en' // lang i18n | 7 | // import locale from 'element-ui/lib/locale/lang/en' // lang i18n |
| 8 | // import local_zh from 'element-ui/lib/locale/lang/zh-CN' // 在node_module里面 | 8 | // import local_zh from 'element-ui/lib/locale/lang/zh-CN' // 在node_module里面 |
| 9 | 9 | ||
| 10 | import '@/styles/index.scss' // global css | 10 | import '@/styles/index.scss' // global css |
| 11 | 11 | ||
| 12 | import App from './App' | 12 | import App from './App' |
| 13 | import store from './store' | 13 | import store from './store' |
| 14 | import router from './router' | 14 | import router from './router' |
| 15 | 15 | ||
| 16 | import '@/icons' // icon | 16 | import '@/icons' // icon |
| 17 | import '@/permission' // permission control | 17 | import '@/permission' // permission control |
| 18 | 18 | ||
| 19 | /** | 19 | /** |
| 20 | * If you don't want to use mock-server | 20 | * If you don't want to use mock-server |
| 21 | * you want to use MockJs for mock api | 21 | * you want to use MockJs for mock api |
| 22 | * you can execute: mockXHR() | 22 | * you can execute: mockXHR() |
| 23 | * | 23 | * |
| 24 | * Currently MockJs will be used in the production environment, | 24 | * Currently MockJs will be used in the production environment, |
| 25 | * please remove it before going online ! ! ! | 25 | * please remove it before going online ! ! ! |
| 26 | */ | 26 | */ |
| 27 | if (process.env.NODE_ENV === 'production') { | 27 | if (process.env.NODE_ENV === 'production') { |
| 28 | const { mockXHR } = require('../mock') | 28 | const { mockXHR } = require('../mock') |
| 29 | mockXHR() | 29 | mockXHR() |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | Vue.use(ElementUI, { size: 'small', zIndex: 3000 }) | ||
| 32 | // set ElementUI lang to EN | 33 | // set ElementUI lang to EN |
| 33 | Vue.use(ElementUI, { locale }) | 34 | // Vue.use(ElementUI, { locale }) |
| 34 | // 如果想要中文版 element-ui,按如下方式声明 | 35 | // 如果想要中文版 element-ui,按如下方式声明 |
| 35 | // Vue.use(ElementUI, {local_zh}) | 36 | // Vue.use(ElementUI, {local_zh}) |
| 36 | |||
| 37 | Vue.config.productionTip = false | 37 | Vue.config.productionTip = false |
| 38 | 38 | ||
| 39 | new Vue({ | 39 | new Vue({ |
| 40 | el: '#app', | 40 | el: '#app', |
| 41 | router, | 41 | router, |
| 42 | store, | 42 | store, |
| 43 | render: h => h(App) | 43 | render: h => h(App) |
| 44 | }) | 44 | }) |
src/router/index.js
| 1 | import Vue from 'vue' | 1 | import Vue from 'vue' |
| 2 | import Router from 'vue-router' | 2 | import Router from 'vue-router' |
| 3 | 3 | ||
| 4 | Vue.use(Router) | 4 | Vue.use(Router) |
| 5 | 5 | ||
| 6 | /* Layout */ | 6 | /* Layout */ |
| 7 | import Layout from '@/layout' | 7 | import Layout from '@/layout' |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | * Note: sub-menu only appear when route children.length >= 1 | 10 | * Note: sub-menu only appear when route children.length >= 1 |
| 11 | * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html | 11 | * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html |
| 12 | * | 12 | * |
| 13 | * hidden: true if set true, item will not show in the sidebar(default is false) | 13 | * hidden: true if set true, item will not show in the sidebar(default is false) |
| 14 | * alwaysShow: true if set true, will always show the root menu | 14 | * alwaysShow: true if set true, will always show the root menu |
| 15 | * if not set alwaysShow, when item has more than one children route, | 15 | * if not set alwaysShow, when item has more than one children route, |
| 16 | * it will becomes nested mode, otherwise not show the root menu | 16 | * it will becomes nested mode, otherwise not show the root menu |
| 17 | * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb | 17 | * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb |
| 18 | * name:'router-name' the name is used by <keep-alive> (must set!!!) | 18 | * name:'router-name' the name is used by <keep-alive> (must set!!!) |
| 19 | * meta : { | 19 | * meta : { |
| 20 | roles: ['admin','editor'] control the page roles (you can set multiple roles) | 20 | roles: ['admin','editor'] control the page roles (you can set multiple roles) |
| 21 | title: 'title' the name show in sidebar and breadcrumb (recommend set) | 21 | title: 'title' the name show in sidebar and breadcrumb (recommend set) |
| 22 | icon: 'svg-name' the icon show in the sidebar | 22 | icon: 'svg-name' the icon show in the sidebar |
| 23 | breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) | 23 | breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) |
| 24 | activeMenu: '/example/list' if set path, the sidebar will highlight the path you set | 24 | activeMenu: '/example/list' if set path, the sidebar will highlight the path you set |
| 25 | } | 25 | } |
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * constantRoutes | 29 | * constantRoutes |
| 30 | * a base page that does not have permission requirements | 30 | * a base page that does not have permission requirements |
| 31 | * all roles can be accessed | 31 | * all roles can be accessed |
| 32 | */ | 32 | */ |
| 33 | export const constantRoutes = [ | 33 | export const constantRoutes = [{ |
| 34 | { | ||
| 35 | path: '/login', | 34 | path: '/login', |
| 36 | component: () => import('@/views/login/index'), | 35 | component: () => import('@/views/login/index'), |
| 37 | hidden: true | 36 | hidden: true |
| 38 | }, | 37 | }, |
| 39 | 38 | ||
| 40 | { | 39 | { |
| 41 | path: '/404', | 40 | path: '/404', |
| 42 | component: () => import('@/views/404'), | 41 | component: () => import('@/views/404'), |
| 43 | hidden: true | 42 | hidden: true |
| 44 | }, | 43 | }, |
| 45 | 44 | ||
| 46 | { | 45 | { |
| 47 | path: '/', | 46 | path: '/', |
| 48 | component: Layout, | 47 | component: Layout, |
| 49 | redirect: '/dashboard', | 48 | redirect: '/dashboard', |
| 50 | children: [{ | 49 | children: [{ |
| 51 | path: 'dashboard', | 50 | path: 'dashboard', |
| 52 | name: 'Dashboard', | 51 | name: 'Dashboard', |
| 53 | component: () => import('@/views/dashboard/index'), | 52 | component: () => import('@/views/dashboard/index'), |
| 54 | meta: { title: '中控台', icon: 'dashboard' } | 53 | meta: { |
| 54 | title: '中控台', | ||
| 55 | icon: 'dashboard' | ||
| 56 | } | ||
| 55 | }] | 57 | }] |
| 56 | }, | 58 | }, |
| 57 | { | 59 | { |
| 58 | path: '/user', | 60 | path: '/user', |
| 59 | component: Layout, | 61 | component: Layout, |
| 60 | redirect: '/user/list', | 62 | redirect: '/user/list', |
| 61 | name: 'user', | 63 | name: 'user', |
| 62 | meta: { title: '用户管理', icon: 'example' }, | 64 | meta: { |
| 63 | children: [ | 65 | title: '用户管理', |
| 64 | { | 66 | icon: 'example' |
| 67 | }, | ||
| 68 | children: [{ | ||
| 65 | path: 'user', | 69 | path: 'user', |
| 66 | name: 'User', | 70 | name: 'User', |
| 67 | component: () => import('@/views/table/index'), | 71 | component: () => import('@/views/table/index'), |
| 68 | meta: { title: '用户列表', icon: 'table' } | 72 | meta: { |
| 73 | title: '用户列表', | ||
| 74 | icon: 'table' | ||
| 75 | } | ||
| 69 | }, | 76 | }, |
| 70 | { | 77 | { |
| 71 | path: 'tree', | 78 | path: 'tree', |
| 72 | name: 'Table', | 79 | name: 'Table', |
| 73 | component: () => import('@/views/tree/index'), | 80 | component: () => import('@/views/tree/index'), |
| 74 | meta: { title: 'Tree', icon: 'tree' } | 81 | meta: { |
| 82 | title: 'Tree', | ||
| 83 | icon: 'tree' | ||
| 84 | } | ||
| 75 | } | 85 | } |
| 76 | ] | 86 | ] |
| 77 | }, | 87 | }, |
| 78 | { | 88 | { |
| 79 | path: '/example', | 89 | path: '/example', |
| 80 | component: Layout, | 90 | component: Layout, |
| 81 | redirect: '/example/table', | 91 | redirect: '/example/table', |
| 82 | name: 'Example', | 92 | name: 'Example', |
| 83 | meta: { title: 'E1111xample', icon: 'example' }, | 93 | meta: { |
| 84 | children: [ | 94 | title: '商家管理', |
| 85 | { | 95 | icon: 'example' |
| 96 | }, | ||
| 97 | children: [{ | ||
| 86 | path: 'table', | 98 | path: 'table', |
| 87 | name: 'Table', | 99 | name: 'Table', |
| 88 | component: () => import('@/views/table/index'), | 100 | component: () => import('@/views/table/index'), |
| 89 | meta: { title: 'Table', icon: 'table' } | 101 | meta: { |
| 102 | title: 'Table', | ||
| 103 | icon: 'table' | ||
| 104 | } | ||
| 90 | }, | 105 | }, |
| 91 | { | 106 | { |
| 92 | path: 'tree', | 107 | path: 'tree', |
| 93 | name: 'Tree', | 108 | name: 'Tree', |
| 94 | component: () => import('@/views/tree/index'), | 109 | component: () => import('@/views/tree/index'), |
| 95 | meta: { title: 'Tree', icon: 'tree' } | 110 | meta: { |
| 111 | title: 'Tree', | ||
| 112 | icon: 'tree' | ||
| 113 | } | ||
| 96 | } | 114 | } |
| 97 | ] | 115 | ] |
| 98 | }, | 116 | }, |
| 99 | |||
| 100 | { | 117 | { |
| 101 | path: '/form', | 118 | path: '/example', |
| 102 | component: Layout, | 119 | component: Layout, |
| 103 | children: [ | 120 | redirect: '/example/table', |
| 121 | name: 'Example', | ||
| 122 | meta: { | ||
| 123 | title: '产品管理', | ||
| 124 | icon: 'example' | ||
| 125 | }, | ||
| 126 | children: [{ | ||
| 127 | path: 'table', | ||
| 128 | name: 'Table', | ||
| 129 | component: () => import('@/views/table/index'), | ||
| 130 | meta: { | ||
| 131 | title: 'Table', | ||
| 132 | icon: 'table' | ||
| 133 | } | ||
| 134 | }, | ||
| 104 | { | 135 | { |
| 105 | path: 'index', | 136 | path: 'tree', |
| 106 | name: 'Form', | 137 | name: 'Tree', |
| 107 | component: () => import('@/views/form/index'), | 138 | component: () => import('@/views/tree/index'), |
| 108 | meta: { title: 'Form', icon: 'form' } | 139 | meta: { |
| 140 | title: 'Tree', | ||
| 141 | icon: 'tree' | ||
| 142 | } | ||
| 109 | } | 143 | } |
| 110 | ] | 144 | ] |
| 111 | } | 145 | }, |
| 112 | ] | ||
| 113 | |||
| 114 | /** | ||
| 115 | * asyncRoutes | ||
| 116 | * the routes that need to be dynamically loaded based on user roles | ||
| 117 | */ | ||
| 118 | export const asyncRoutes = [ | ||
| 119 | { | 146 | { |
| 120 | path: '/nested', | 147 | path: '/example', |
| 121 | component: Layout, | 148 | component: Layout, |
| 122 | redirect: '/nested/menu1', | 149 | redirect: '/example/table', |
| 123 | name: 'Nested', | 150 | name: 'Example', |
| 124 | meta: { | 151 | meta: { |
| 125 | title: 'Nested', | 152 | title: '元管理', |
| 126 | icon: 'nested' | 153 | icon: 'example' |
| 127 | }, | 154 | }, |
| 128 | children: [ | 155 | children: [{ |
| 129 | { | 156 | path: 'table', |
| 130 | path: 'menu1', | 157 | name: 'Table', |
| 131 | component: () => import('@/views/nested/menu1/index'), // Parent router-view | 158 | component: () => import('@/views/table/index'), |
| 132 | name: 'Menu1', | 159 | meta: { |
| 133 | meta: { title: 'Menu1' }, | 160 | title: 'Table', |
| 134 | children: [ | 161 | icon: 'table' |
| 135 | { | 162 | } |
| 136 | path: 'menu1-1', | ||
| 137 | component: () => import('@/views/nested/menu1/menu1-1'), | ||
| 138 | name: 'Menu1-1', | ||
| 139 | meta: { title: 'Menu1-1' } | ||
| 140 | }, | ||
| 141 | { | ||
| 142 | path: 'menu1-2', | ||
| 143 | component: () => import('@/views/nested/menu1/menu1-2'), | ||
| 144 | name: 'Menu1-2', | ||
| 145 | meta: { title: 'Menu1-2' }, | ||
| 146 | children: [ | ||
| 147 | { | ||
| 148 | path: 'menu1-2-1', | ||
| 149 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), | ||
| 150 | name: 'Menu1-2-1', | ||
| 151 | meta: { title: 'Menu1-2-1' } | ||
| 152 | }, | ||
| 153 | { | ||
| 154 | path: 'menu1-2-2', | ||
| 155 | component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), | ||
| 156 | name: 'Menu1-2-2', | ||
| 157 | meta: { title: 'Menu1-2-2' } | ||
| 158 | } | ||
| 159 | ] | ||
| 160 | }, | ||
| 161 | { | ||
| 162 | path: 'menu1-3', | ||
| 163 | component: () => import('@/views/nested/menu1/menu1-3'), | ||
| 164 | name: 'Menu1-3', | ||
| 165 | meta: { title: 'Menu1-3' } | ||
| 166 | } | ||
| 167 | ] | ||
| 168 | }, | 163 | }, |
| 169 | { | 164 | { |
| 170 | path: 'menu2', | 165 | path: 'tree', |
| 171 | component: () => import('@/views/nested/menu2/index'), | 166 | name: 'Tree', |
| 172 | meta: { title: 'menu2' } | 167 | component: () => import('@/views/tree/index'), |
| 168 | meta: { | ||
| 169 | title: 'Tree', | ||
| 170 | icon: 'tree' | ||
| 171 | } | ||
| 173 | } | 172 | } |
| 174 | ] | 173 | ] |
| 175 | }, | 174 | }, |
| 176 | |||
| 177 | { | 175 | { |
| 178 | path: 'external-link', | 176 | path: '/example', |
| 177 | component: Layout, | ||
| 178 | redirect: '/example/table', | ||
| 179 | name: 'Example', | ||
| 180 | meta: { | ||
| 181 | title: '交易管理', | ||
| 182 | icon: 'example' | ||
| 183 | }, | ||
| 184 | children: [{ | ||
| 185 | path: 'table', | ||
| 186 | name: 'Table', | ||
| 187 | component: () => import('@/views/table/index'), | ||
| 188 | meta: { | ||
| 189 | title: 'Table', | ||
| 190 | icon: 'table' | ||
| 191 | } | ||
| 192 | }, | ||
| 193 | { | ||
| 194 | path: 'tree', | ||
| 195 | name: 'Tree', | ||
| 196 | component: () => import('@/views/tree/index'), | ||
| 197 | meta: { | ||
| 198 | title: 'Tree', | ||
| 199 | icon: 'tree' | ||
| 200 | } | ||
| 201 | } | ||
| 202 | ] | ||
| 203 | }, { | ||
| 204 | path: '/example', | ||
| 179 | component: Layout, | 205 | component: Layout, |
| 180 | children: [ | 206 | redirect: '/example/table', |
| 207 | name: 'Example', | ||
| 208 | meta: { | ||
| 209 | title: '推荐系统', | ||
| 210 | icon: 'example' | ||
| 211 | }, | ||
| 212 | children: [{ | ||
| 213 | path: 'table', | ||
| 214 | name: 'Table', | ||
| 215 | component: () => import('@/views/table/index'), | ||
| 216 | meta: { | ||
| 217 | title: 'Table', | ||
| 218 | icon: 'table' | ||
| 219 | } | ||
| 220 | }, | ||
| 221 | { | ||
| 222 | path: 'tree', | ||
| 223 | name: 'Tree', | ||
| 224 | component: () => import('@/views/tree/index'), | ||
| 225 | meta: { | ||
| 226 | title: 'Tree', | ||
| 227 | icon: 'tree' | ||
| 228 | } | ||
| 229 | } | ||
| 230 | ] | ||
| 231 | }, { | ||
| 232 | path: '/system', | ||
| 233 | component: Layout, | ||
| 234 | redirect: '/system/table', | ||
| 235 | name: 'System', | ||
| 236 | meta: { | ||
| 237 | title: '系统设置', | ||
| 238 | icon: 'example' | ||
| 239 | }, | ||
| 240 | children: [{ | ||
| 241 | path: 'table', | ||
| 242 | name: 'Table', | ||
| 243 | component: () => import('@/views/table/index'), | ||
| 244 | meta: { | ||
| 245 | title: '行业设置', | ||
| 246 | icon: 'table' | ||
| 247 | } | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | path: 'tree', | ||
| 251 | name: 'Tree', | ||
| 252 | component: () => import('@/views/tree/index'), | ||
| 253 | meta: { | ||
| 254 | title: '语言设置', | ||
| 255 | icon: 'tree' | ||
| 256 | } | ||
| 257 | }, | ||
| 258 | { | ||
| 259 | path: 'tree', | ||
| 260 | name: 'Tree', | ||
| 261 | component: () => import('@/views/tree/index'), | ||
| 262 | meta: { | ||
| 263 | title: '货币设置', | ||
| 264 | icon: 'tree' | ||
| 265 | } | ||
| 266 | }, | ||
| 267 | { | ||
| 268 | path: 'tree', | ||
| 269 | name: 'Tree', | ||
| 270 | component: () => import('@/views/tree/index'), | ||
| 271 | meta: { | ||
| 272 | title: '站点类型设置', | ||
| 273 | icon: 'tree' | ||
| 274 | } | ||
| 275 | }, | ||
| 276 | { | ||
| 277 | path: 'tree', | ||
| 278 | name: 'Tree', | ||
| 279 | component: () => import('@/views/tree/index'), | ||
| 280 | meta: { | ||
| 281 | title: '模版设置', | ||
| 282 | icon: 'tree' | ||
| 283 | } | ||
| 284 | }, | ||
| 181 | { | 285 | { |
| 182 | path: 'https://panjiachen.github.io/vue-element-admin-site/#/', | 286 | path: 'tree', |
| 183 | meta: { title: 'External Link', icon: 'link' } | 287 | name: 'Tree', |
| 288 | component: () => import('@/views/tree/index'), | ||
| 289 | meta: { | ||
| 290 | title: '权限设置', | ||
| 291 | icon: 'tree' | ||
| 292 | } | ||
| 184 | } | 293 | } |
| 185 | ] | 294 | ] |
| 186 | }, | 295 | }, |
| 296 | { | ||
| 297 | path: '/form', | ||
| 298 | component: Layout, |
src/views/403.vue
| File was created | 1 | <template> | |
| 2 | <div class="error-page"> | ||
| 3 | <div class="error-code"> | ||
| 4 | 4 | ||
| 5 | <span>0</span>3 | ||
| 6 | </div> | ||
| 7 | <div class="error-desc">啊哦~ 你没有权限访问该页面哦</div> | ||
| 8 | <div class="error-handle"> | ||
| 9 | <router-link to="/"> | ||
| 10 | <el-button type="primary" size="large">返回首页</el-button> | ||
| 11 | </router-link> | ||
| 12 | <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> | ||
| 13 | </div> | ||
| 14 | </div> | ||
| 15 | </template> | ||
| 16 | |||
| 17 | <script> | ||
| 18 | export default { | ||
| 19 | methods: { | ||
| 20 | goBack() { | ||
| 21 | this.$router.go(-1); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | }; | ||
| 25 | </script> | ||
| 26 | |||
| 27 | |||
| 28 | <style scoped> | ||
| 29 | .error-page { | ||
| 30 | display: flex; | ||
| 31 | justify-content: center; | ||
| 32 | align-items: center; | ||
| 33 | flex-direction: column; | ||
| 34 | width: 100%; | ||
| 35 | height: 100%; | ||
| 36 | background: #f3f3f3; | ||
| 37 | box-sizing: border-box; | ||
| 38 | } | ||
| 39 | .error-code { | ||
| 40 | line-height: 1; | ||
| 41 | font-size: 250px; | ||
| 42 | font-weight: bolder; | ||
| 43 | color: #f02d2d; | ||
| 44 | } | ||
| 45 | .error-code span { | ||
| 46 | color: #00a854; | ||
| 47 | } | ||
| 48 | .error-desc { | ||
| 49 | font-size: 30px; | ||
| 50 | color: #777; | ||
| 51 | } | ||
| 52 | .error-handle { | ||
| 53 | margin-top: 30px; | ||
| 54 | padding-bottom: 200px; | ||
| 55 | } | ||
| 56 | .error-btn { | ||
| 57 | margin-left: 100px; | ||
| 58 | } | ||
| 59 | </style> |
src/views/404.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="wscn-http404-container"> | 2 | <div class="wscn-http404-container"> |
| 3 | <div class="wscn-http404"> | 3 | <div class="wscn-http404"> |
| 4 | <div class="pic-404"> | 4 | <div class="pic-404"> |
| 5 | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404"> | 5 | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" /> |
| 6 | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404"> | 6 | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| 7 | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404"> | 7 | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| 8 | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> | 8 | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| 9 | </div> | 9 | </div> |
| 10 | <div class="bullshit"> | 10 | <div class="bullshit"> |
| 11 | <div class="bullshit__oops">OOPS!</div> | 11 | <div class="bullshit__oops">OOPS!</div> |
| 12 | <div class="bullshit__info">All rights reserved | 12 | <div class="bullshit__info"> |
| 13 | <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a> | 13 | All rights reserved |
| 14 | <a | ||
| 15 | style="color:#20a0ff" | ||
| 16 | href="https://wallstreetcn.com" | ||
| 17 | target="_blank" | ||
| 18 | >wallstreetcn</a> | ||
| 14 | </div> | 19 | </div> |
| 15 | <div class="bullshit__headline">{{ message }}</div> | 20 | <div class="bullshit__headline">{{ message }}</div> |
| 16 | <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div> | 21 | <div |
| 17 | <a href="" class="bullshit__return-home">Back to home</a> | 22 | class="bullshit__info" |
| 23 | >Please check that the URL you entered is correct, or click the button below to return to the homepage.</div> | ||
| 24 | <a href class="bullshit__return-home">Back to home</a> | ||
| 18 | </div> | 25 | </div> |
| 19 | </div> | 26 | </div> |
| 20 | </div> | 27 | </div> |
| 21 | </template> | 28 | </template> |
| 22 | 29 | ||
| 23 | <script> | 30 | <script> |
| 24 | |||
| 25 | export default { | 31 | export default { |
| 26 | name: 'Page404', | 32 | name: "Page404", |
| 27 | computed: { | 33 | computed: { |
| 28 | message() { | 34 | message() { |
| 29 | return 'The webmaster said that you can not enter this page...' | 35 | return "The webmaster said that you can not enter this page..."; |
| 30 | } | 36 | } |
| 31 | } | 37 | } |
| 32 | } | 38 | }; |
| 33 | </script> | 39 | </script> |
| 34 | 40 | ||
| 35 | <style lang="scss" scoped> | 41 | <style lang="scss" scoped> |
| 36 | .wscn-http404-container{ | 42 | .wscn-http404-container { |
| 37 | transform: translate(-50%,-50%); | 43 | transform: translate(-50%, -50%); |
| 38 | position: absolute; | 44 | position: absolute; |
| 39 | top: 40%; | 45 | top: 40%; |
| 40 | left: 50%; | 46 | left: 50%; |
| 41 | } | 47 | } |
| 42 | .wscn-http404 { | 48 | .wscn-http404 { |
| 43 | position: relative; | 49 | position: relative; |
| 44 | width: 1200px; | 50 | width: 1200px; |
| 45 | padding: 0 50px; | 51 | padding: 0 50px; |
| 46 | overflow: hidden; | 52 | overflow: hidden; |
| 47 | .pic-404 { | 53 | .pic-404 { |
| 48 | position: relative; | 54 | position: relative; |
| 49 | float: left; | 55 | float: left; |
| 50 | width: 600px; | 56 | width: 600px; |
| 51 | overflow: hidden; | 57 | overflow: hidden; |
| 52 | &__parent { | 58 | &__parent { |
| 53 | width: 100%; | 59 | width: 100%; |
| 54 | } | 60 | } |
| 55 | &__child { | 61 | &__child { |
| 56 | position: absolute; | 62 | position: absolute; |
| 57 | &.left { | 63 | &.left { |
| 58 | width: 80px; | 64 | width: 80px; |
| 59 | top: 17px; | 65 | top: 17px; |
| 60 | left: 220px; | 66 | left: 220px; |
| 61 | opacity: 0; | 67 | opacity: 0; |
| 62 | animation-name: cloudLeft; | 68 | animation-name: cloudLeft; |
| 63 | animation-duration: 2s; | 69 | animation-duration: 2s; |
| 64 | animation-timing-function: linear; | 70 | animation-timing-function: linear; |
| 65 | animation-fill-mode: forwards; | 71 | animation-fill-mode: forwards; |
| 66 | animation-delay: 1s; | 72 | animation-delay: 1s; |
| 67 | } | 73 | } |
| 68 | &.mid { | 74 | &.mid { |
| 69 | width: 46px; | 75 | width: 46px; |
| 70 | top: 10px; | 76 | top: 10px; |
| 71 | left: 420px; | 77 | left: 420px; |
| 72 | opacity: 0; | 78 | opacity: 0; |
| 73 | animation-name: cloudMid; | 79 | animation-name: cloudMid; |
| 74 | animation-duration: 2s; | 80 | animation-duration: 2s; |
| 75 | animation-timing-function: linear; | 81 | animation-timing-function: linear; |
| 76 | animation-fill-mode: forwards; | 82 | animation-fill-mode: forwards; |
| 77 | animation-delay: 1.2s; | 83 | animation-delay: 1.2s; |
| 78 | } | 84 | } |
| 79 | &.right { | 85 | &.right { |
| 80 | width: 62px; | 86 | width: 62px; |
| 81 | top: 100px; | 87 | top: 100px; |
| 82 | left: 500px; | 88 | left: 500px; |
| 83 | opacity: 0; | 89 | opacity: 0; |
| 84 | animation-name: cloudRight; | 90 | animation-name: cloudRight; |
| 85 | animation-duration: 2s; | 91 | animation-duration: 2s; |
| 86 | animation-timing-function: linear; | 92 | animation-timing-function: linear; |
| 87 | animation-fill-mode: forwards; | 93 | animation-fill-mode: forwards; |
| 88 | animation-delay: 1s; | 94 | animation-delay: 1s; |
| 89 | } | 95 | } |
| 90 | @keyframes cloudLeft { | 96 | @keyframes cloudLeft { |
| 91 | 0% { | 97 | 0% { |
| 92 | top: 17px; | 98 | top: 17px; |
| 93 | left: 220px; | 99 | left: 220px; |
| 94 | opacity: 0; | 100 | opacity: 0; |
| 95 | } | 101 | } |
| 96 | 20% { | 102 | 20% { |
| 97 | top: 33px; | 103 | top: 33px; |
| 98 | left: 188px; | 104 | left: 188px; |
| 99 | opacity: 1; | 105 | opacity: 1; |
| 100 | } | 106 | } |
| 101 | 80% { | 107 | 80% { |
| 102 | top: 81px; | 108 | top: 81px; |
| 103 | left: 92px; | 109 | left: 92px; |
| 104 | opacity: 1; | 110 | opacity: 1; |
| 105 | } | 111 | } |
| 106 | 100% { | 112 | 100% { |
| 107 | top: 97px; | 113 | top: 97px; |
| 108 | left: 60px; | 114 | left: 60px; |
| 109 | opacity: 0; | 115 | opacity: 0; |
| 110 | } | 116 | } |
| 111 | } | 117 | } |
| 112 | @keyframes cloudMid { | 118 | @keyframes cloudMid { |
| 113 | 0% { | 119 | 0% { |
| 114 | top: 10px; | 120 | top: 10px; |
| 115 | left: 420px; | 121 | left: 420px; |
| 116 | opacity: 0; | 122 | opacity: 0; |
| 117 | } | 123 | } |
| 118 | 20% { | 124 | 20% { |
| 119 | top: 40px; | 125 | top: 40px; |
| 120 | left: 360px; | 126 | left: 360px; |
| 121 | opacity: 1; | 127 | opacity: 1; |
| 122 | } | 128 | } |
| 123 | 70% { | 129 | 70% { |
| 124 | top: 130px; | 130 | top: 130px; |
| 125 | left: 180px; | 131 | left: 180px; |
| 126 | opacity: 1; | 132 | opacity: 1; |
| 127 | } | 133 | } |
| 128 | 100% { | 134 | 100% { |
| 129 | top: 160px; | 135 | top: 160px; |
| 130 | left: 120px; | 136 | left: 120px; |
| 131 | opacity: 0; | 137 | opacity: 0; |
| 132 | } | 138 | } |
| 133 | } | 139 | } |
| 134 | @keyframes cloudRight { | 140 | @keyframes cloudRight { |
| 135 | 0% { | 141 | 0% { |
| 136 | top: 100px; | 142 | top: 100px; |
| 137 | left: 500px; | 143 | left: 500px; |
| 138 | opacity: 0; | 144 | opacity: 0; |
| 139 | } | 145 | } |
| 140 | 20% { | 146 | 20% { |
| 141 | top: 120px; | 147 | top: 120px; |
| 142 | left: 460px; | 148 | left: 460px; |
| 143 | opacity: 1; | 149 | opacity: 1; |
| 144 | } | 150 | } |
| 145 | 80% { | 151 | 80% { |
| 146 | top: 180px; | 152 | top: 180px; |
| 147 | left: 340px; | 153 | left: 340px; |
| 148 | opacity: 1; | 154 | opacity: 1; |
| 149 | } | 155 | } |
| 150 | 100% { | 156 | 100% { |
| 151 | top: 200px; | 157 | top: 200px; |
| 152 | left: 300px; | 158 | left: 300px; |
| 153 | opacity: 0; | 159 | opacity: 0; |
| 154 | } | 160 | } |
| 155 | } | 161 | } |
| 156 | } | 162 | } |
| 157 | } | 163 | } |
| 158 | .bullshit { | 164 | .bullshit { |
| 159 | position: relative; | 165 | position: relative; |
| 160 | float: left; | 166 | float: left; |
| 161 | width: 300px; | 167 | width: 300px; |
| 162 | padding: 30px 0; | 168 | padding: 30px 0; |
| 163 | overflow: hidden; | 169 | overflow: hidden; |
| 164 | &__oops { | 170 | &__oops { |
| 165 | font-size: 32px; | 171 | font-size: 32px; |
| 166 | font-weight: bold; | 172 | font-weight: bold; |
| 167 | line-height: 40px; | 173 | line-height: 40px; |
| 168 | color: #1482f0; | 174 | color: #1482f0; |
| 169 | opacity: 0; | 175 | opacity: 0; |
| 170 | margin-bottom: 20px; | 176 | margin-bottom: 20px; |
| 171 | animation-name: slideUp; | 177 | animation-name: slideUp; |
| 172 | animation-duration: 0.5s; | 178 | animation-duration: 0.5s; |
| 173 | animation-fill-mode: forwards; | 179 | animation-fill-mode: forwards; |
| 174 | } | 180 | } |
| 175 | &__headline { | 181 | &__headline { |
| 176 | font-size: 20px; | 182 | font-size: 20px; |
| 177 | line-height: 24px; | 183 | line-height: 24px; |
| 178 | color: #222; | 184 | color: #222; |
| 179 | font-weight: bold; | 185 | font-weight: bold; |
| 180 | opacity: 0; | 186 | opacity: 0; |
| 181 | margin-bottom: 10px; | 187 | margin-bottom: 10px; |
| 182 | animation-name: slideUp; | 188 | animation-name: slideUp; |
| 183 | animation-duration: 0.5s; | 189 | animation-duration: 0.5s; |
| 184 | animation-delay: 0.1s; | 190 | animation-delay: 0.1s; |
| 185 | animation-fill-mode: forwards; | 191 | animation-fill-mode: forwards; |
| 186 | } | 192 | } |
| 187 | &__info { | 193 | &__info { |
| 188 | font-size: 13px; | 194 | font-size: 13px; |
| 189 | line-height: 21px; | 195 | line-height: 21px; |
| 190 | color: grey; | 196 | color: grey; |
| 191 | opacity: 0; | 197 | opacity: 0; |
| 192 | margin-bottom: 30px; | 198 | margin-bottom: 30px; |
| 193 | animation-name: slideUp; | 199 | animation-name: slideUp; |
| 194 | animation-duration: 0.5s; | 200 | animation-duration: 0.5s; |
| 195 | animation-delay: 0.2s; | 201 | animation-delay: 0.2s; |
| 196 | animation-fill-mode: forwards; | 202 | animation-fill-mode: forwards; |
| 197 | } | 203 | } |
| 198 | &__return-home { | 204 | &__return-home { |
| 199 | display: block; | 205 | display: block; |
| 200 | float: left; | 206 | float: left; |
| 201 | width: 110px; | 207 | width: 110px; |
| 202 | height: 36px; | 208 | height: 36px; |
| 203 | background: #1482f0; | 209 | background: #1482f0; |
| 204 | border-radius: 100px; | 210 | border-radius: 100px; |
| 205 | text-align: center; | 211 | text-align: center; |
| 206 | color: #ffffff; | 212 | color: #ffffff; |
| 207 | opacity: 0; | 213 | opacity: 0; |
| 208 | font-size: 14px; | 214 | font-size: 14px; |
| 209 | line-height: 36px; | 215 | line-height: 36px; |
| 210 | cursor: pointer; | 216 | cursor: pointer; |
| 211 | animation-name: slideUp; | 217 | animation-name: slideUp; |
| 212 | animation-duration: 0.5s; | 218 | animation-duration: 0.5s; |
| 213 | animation-delay: 0.3s; | 219 | animation-delay: 0.3s; |
| 214 | animation-fill-mode: forwards; | 220 | animation-fill-mode: forwards; |
| 215 | } | 221 | } |
| 216 | @keyframes slideUp { | 222 | @keyframes slideUp { |
| 217 | 0% { | 223 | 0% { |
| 218 | transform: translateY(60px); | 224 | transform: translateY(60px); |
| 219 | opacity: 0; | 225 | opacity: 0; |
| 220 | } | 226 | } |
| 221 | 100% { | 227 | 100% { |
| 222 | transform: translateY(0); | 228 | transform: translateY(0); |
| 223 | opacity: 1; | 229 | opacity: 1; |
| 224 | } | 230 | } |
| 225 | } | 231 | } |
| 226 | } | 232 | } |
| 227 | } | 233 | } |
| 228 | </style> | 234 | </style> |
src/views/502.vue
| File was created | 1 | <template> | |
| 2 | <div class="error-page"> | ||
| 3 | <div class="error-code"> | ||
| 4 | 5 | ||
| 5 | <span>0</span>2 | ||
| 6 | </div> | ||
| 7 | <div class="error-desc">啊哦~ 系统出了故障!</div> | ||
| 8 | <div class="error-handle"> | ||
| 9 | <router-link to="/"> | ||
| 10 | <el-button type="primary" size="large">返回首页</el-button> | ||
| 11 | </router-link> | ||
| 12 | <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> | ||
| 13 | </div> | ||
| 14 | </div> | ||
| 15 | </template> | ||
| 16 | |||
| 17 | <script> | ||
| 18 | export default { | ||
| 19 | methods: { | ||
| 20 | goBack() { | ||
| 21 | this.$router.go(-1); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | }; | ||
| 25 | </script> | ||
| 26 | <style scoped> | ||
| 27 | .error-page { | ||
| 28 | display: flex; | ||
| 29 | justify-content: center; | ||
| 30 | align-items: center; | ||
| 31 | flex-direction: column; | ||
| 32 | width: 100%; | ||
| 33 | height: 100%; | ||
| 34 | background: #f3f3f3; | ||
| 35 | box-sizing: border-box; | ||
| 36 | } | ||
| 37 | .error-code { | ||
| 38 | line-height: 1; | ||
| 39 | font-size: 250px; | ||
| 40 | font-weight: bolder; | ||
| 41 | color: #f02d2d; | ||
| 42 | } | ||
| 43 | .error-code span { | ||
| 44 | color: #00a854; | ||
| 45 | } | ||
| 46 | .error-desc { | ||
| 47 | font-size: 30px; | ||
| 48 | color: #777; | ||
| 49 | } | ||
| 50 | .error-handle { | ||
| 51 | margin-top: 30px; | ||
| 52 | padding-bottom: 200px; | ||
| 53 | } | ||
| 54 | .error-btn { | ||
| 55 | margin-left: 100px; | ||
| 56 | } | ||
| 57 | </style> |
src/views/dashboard/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="dashboard-container"> | 2 | <div> |
| 3 | <div class="dashboard-text">用户名: {{ name }}</div> | 3 | <el-row :gutter="20"> |
| 4 | <div class="dashboard-text">角色: <span v-for="role in roles" :key="role">{{ role }}</span></div> | 4 | <el-col :span="8"> |
| 5 | <el-card shadow="hover" class="mgb20" style="height:252px;"> | ||
| 6 | <div class="user-info"> | ||
| 7 | <img src="../../assets/img/img.jpg" class="user-avator" alt /> | ||
| 8 | <div class="user-info-cont"> | ||
| 9 | <div class="user-info-name">{{name}}</div> | ||
| 10 | <div>{{role}}</div> | ||
| 11 | </div> | ||
| 12 | </div> | ||
| 13 | <div class="user-info-list"> | ||
| 14 | 上次登录时间: | ||
| 15 | <span>2019-11-01</span> | ||
| 16 | </div> | ||
| 17 | <div class="user-info-list"> | ||
| 18 | 上次登录地点: | ||
| 19 | <span>东莞</span> | ||
| 20 | </div> | ||
| 21 | </el-card> | ||
| 22 | <el-card shadow="hover" style="height:252px;"> | ||
| 23 | <div slot="header" class="clearfix"> | ||
| 24 | <span>语言详情</span> | ||
| 25 | </div>Vue | ||
| 26 | <el-progress :percentage="71.3" color="#42b983"></el-progress>JavaScript | ||
| 27 | <el-progress :percentage="24.1" color="#f1e05a"></el-progress>CSS | ||
| 28 | <el-progress :percentage="13.7"></el-progress>HTML | ||
| 29 | <el-progress :percentage="5.9" color="#f56c6c"></el-progress> | ||
| 30 | </el-card> | ||
| 31 | </el-col> | ||
| 32 | <el-col :span="16"> | ||
| 33 | <el-row :gutter="20" class="mgb20"> | ||
| 34 | <el-col :span="8"> | ||
| 35 | <el-card shadow="hover" :body-style="{padding: '0px'}"> | ||
| 36 | <div class="grid-content grid-con-1"> | ||
| 37 | <i class="el-icon-lx-people grid-con-icon"></i> | ||
| 38 | <div class="grid-cont-right"> | ||
| 39 | <div class="grid-num">1234</div> | ||
| 40 | <div>用户访问量</div> | ||
| 41 | </div> | ||
| 42 | </div> | ||
| 43 | </el-card> | ||
| 44 | </el-col> | ||
| 45 | <el-col :span="8"> | ||
| 46 | <el-card shadow="hover" :body-style="{padding: '0px'}"> | ||
| 47 | <div class="grid-content grid-con-2"> | ||
| 48 | <i class="el-icon-lx-notice grid-con-icon"></i> | ||
| 49 | <div class="grid-cont-right"> | ||
| 50 | <div class="grid-num">321</div> | ||
| 51 | <div>系统消息</div> | ||
| 52 | </div> | ||
| 53 | </div> | ||
| 54 | </el-card> | ||
| 55 | </el-col> | ||
| 56 | <el-col :span="8"> | ||
| 57 | <el-card shadow="hover" :body-style="{padding: '0px'}"> | ||
| 58 | <div class="grid-content grid-con-3"> | ||
| 59 | <i class="el-icon-lx-goods grid-con-icon"></i> | ||
| 60 | <div class="grid-cont-right"> | ||
| 61 | <div class="grid-num">5000</div> | ||
| 62 | <div>数量</div> | ||
| 63 | </div> | ||
| 64 | </div> | ||
| 65 | </el-card> | ||
| 66 | </el-col> | ||
| 67 | </el-row> | ||
| 68 | <el-card shadow="hover" style="height:403px;"> | ||
| 69 | <div slot="header" class="clearfix"> | ||
| 70 | <span>待办事项</span> | ||
| 71 | <el-button style="float: right; padding: 3px 0" type="text" @click="addAction">添加</el-button> | ||
| 72 | </div> | ||
| 73 | <el-table :show-header="false" :data="todoList" style="width:100%;"> | ||
| 74 | <el-table-column width="40"> | ||
| 75 | <template slot-scope="scope"> | ||
| 76 | <el-checkbox v-model="scope.row.status"></el-checkbox> | ||
| 77 | </template> | ||
| 78 | </el-table-column> | ||
| 79 | <el-table-column> | ||
| 80 | <template slot-scope="scope"> | ||
| 81 | <div | ||
| 82 | class="todo-item" | ||
| 83 | :class="{'todo-item-del': scope.row.status}" | ||
| 84 | >{{scope.row.title}}</div> | ||
| 85 | </template> | ||
| 86 | </el-table-column> | ||
| 87 | <el-table-column width="60"> | ||
| 88 | <template> | ||
| 89 | <i class="el-icon-edit" @click="modiAction"></i> | ||
| 90 | <i class="el-icon-delete" @click="delAction"></i> | ||
| 91 | </template> | ||
| 92 | </el-table-column> | ||
| 93 | </el-table> | ||
| 94 | </el-card> | ||
| 95 | </el-col> | ||
| 96 | </el-row> | ||
| 97 | <el-row :gutter="20"> | ||
| 98 | <el-col :span="12"> | ||
| 99 | <el-card shadow="hover"> | ||
| 100 | <schart ref="bar" class="schart" canvasId="bar" :options="options"></schart> | ||
| 101 | </el-card> | ||
| 102 | </el-col> | ||
| 103 | <el-col :span="12"> | ||
| 104 | <el-card shadow="hover"> | ||
| 105 | <schart ref="line" class="schart" canvasId="line" :options="options2"></schart> | ||
| 106 | </el-card> | ||
| 107 | </el-col> | ||
| 108 | </el-row> | ||
| 5 | </div> | 109 | </div> |
| 6 | </template> | 110 | </template> |
| 7 | 111 | ||
| 8 | <script> | 112 | <script> |
| 9 | import { mapGetters } from 'vuex' | 113 | import { mapGetters } from "vuex"; |
| 114 | import Vue from "vue"; | ||
| 115 | import { | ||
| 116 | Pagination, | ||
| 117 | Dialog, | ||
| 118 | Autocomplete, | ||
| 119 | Dropdown, | ||
| 120 | DropdownMenu, | ||
| 121 | DropdownItem, | ||
| 122 | Menu, | ||
| 123 | Submenu, | ||
| 124 | MenuItem, | ||
| 125 | MenuItemGroup, | ||
| 126 | Input, | ||
| 127 | InputNumber, | ||
| 128 | Radio, | ||
| 129 | RadioGroup, | ||
| 130 | RadioButton, | ||
| 131 | Checkbox, | ||
| 132 | CheckboxButton, | ||
| 133 | CheckboxGroup, | ||
| 134 | Switch, | ||
| 135 | Select, | ||
| 136 | Option, | ||
| 137 | OptionGroup, | ||
| 138 | Button, | ||
| 139 | ButtonGroup, | ||
| 140 | Table, | ||
| 141 | TableColumn, | ||
| 142 | DatePicker, | ||
| 143 | TimeSelect, | ||
| 144 | TimePicker, | ||
| 145 | Popover, | ||
| 146 | Tooltip, | ||
| 147 | Breadcrumb, | ||
| 148 | BreadcrumbItem, | ||
| 149 | Form, | ||
| 150 | FormItem, | ||
| 151 | Tabs, | ||
| 152 | TabPane, | ||
| 153 | Tag, | ||
| 154 | Tree, | ||
| 155 | Alert, | ||
| 156 | Slider, | ||
| 157 | Icon, | ||
| 158 | Row, | ||
| 159 | Col, | ||
| 160 | Upload, | ||
| 161 | Progress, | ||
| 162 | Spinner, | ||
| 163 | Badge, | ||
| 164 | Card, | ||
| 165 | Rate, | ||
| 166 | Steps, | ||
| 167 | Step, | ||
| 168 | Carousel, | ||
| 169 | CarouselItem, | ||
| 170 | Collapse, | ||
| 171 | CollapseItem, | ||
| 172 | Cascader, | ||
| 173 | ColorPicker, | ||
| 174 | Transfer, | ||
| 175 | Container, | ||
| 176 | Header, | ||
| 177 | Aside, | ||
| 178 | Main, | ||
| 179 | Footer, | ||
| 180 | Timeline, | ||
| 181 | TimelineItem, | ||
| 182 | Link, | ||
| 183 | Divider, | ||
| 184 | Image, | ||
| 185 | Calendar, | ||
| 186 | Backtop, | ||
| 187 | PageHeader, | ||
| 188 | CascaderPanel, | ||
| 189 | Loading, | ||
| 190 | MessageBox, | ||
| 191 | Message, | ||
| 192 | Notification | ||
| 193 | } from "element-ui"; | ||
| 10 | // import ElementUI from 'element-ui' | 194 | // import ElementUI from 'element-ui' |
| 195 | Vue.prototype.$ELEMENT = { size: "small", zIndex: 3000 }; | ||
| 196 | Vue.use(Pagination); | ||
| 197 | Vue.use(Dialog); | ||
| 198 | Vue.use(Autocomplete); | ||
| 199 | Vue.use(Dropdown); | ||
| 200 | Vue.use(DropdownMenu); | ||
| 201 | Vue.use(DropdownItem); | ||
| 202 | Vue.use(Menu); | ||
| 203 | Vue.use(Submenu); | ||
| 204 | Vue.use(MenuItem); | ||
| 205 | Vue.use(MenuItemGroup); | ||
| 206 | Vue.use(Input); | ||
| 207 | Vue.use(InputNumber); | ||
| 208 | Vue.use(Radio); | ||
| 209 | Vue.use(RadioGroup); | ||
| 210 | Vue.use(RadioButton); | ||
| 211 | Vue.use(Checkbox); | ||
| 212 | Vue.use(CheckboxButton); | ||
| 213 | Vue.use(CheckboxGroup); | ||
| 214 | Vue.use(Switch); | ||
| 215 | Vue.use(Select); | ||
| 216 | Vue.use(Option); | ||
| 217 | Vue.use(OptionGroup); | ||
| 218 | Vue.use(Button); | ||
| 219 | Vue.use(ButtonGroup); | ||
| 220 | Vue.use(Table); | ||
| 221 | Vue.use(TableColumn); | ||
| 222 | Vue.use(DatePicker); | ||
| 223 | Vue.use(TimeSelect); | ||
| 224 | Vue.use(TimePicker); | ||
| 225 | Vue.use(Popover); | ||
| 226 | Vue.use(Tooltip); | ||
| 227 | Vue.use(Breadcrumb); | ||
| 228 | Vue.use(BreadcrumbItem); | ||
| 229 | Vue.use(Form); | ||
| 230 | Vue.use(FormItem); | ||
| 231 | Vue.use(Tabs); | ||
| 232 | Vue.use(TabPane); | ||
| 233 | Vue.use(Tag); | ||
| 234 | Vue.use(Tree); | ||
| 235 | Vue.use(Alert); | ||
| 236 | Vue.use(Slider); | ||
| 237 | Vue.use(Icon); | ||
| 238 | Vue.use(Row); | ||
| 239 | Vue.use(Col); | ||
| 240 | Vue.use(Upload); | ||
| 241 | Vue.use(Progress); | ||
| 242 | Vue.use(Spinner); | ||
| 243 | Vue.use(Badge); | ||
| 244 | Vue.use(Card); | ||
| 245 | Vue.use(Rate); | ||
| 246 | Vue.use(Steps); | ||
| 247 | Vue.use(Step); | ||
| 248 | Vue.use(Carousel); | ||
| 249 | Vue.use(CarouselItem); | ||
| 250 | Vue.use(Collapse); | ||
| 251 | Vue.use(CollapseItem); | ||
| 252 | Vue.use(Cascader); | ||
| 253 | Vue.use(ColorPicker); | ||
| 254 | Vue.use(Transfer); | ||
| 255 | Vue.use(Container); | ||
| 256 | Vue.use(Header); | ||
| 257 | Vue.use(Aside); | ||
| 258 | Vue.use(Main); | ||
| 259 | Vue.use(Footer); | ||
| 260 | Vue.use(Timeline); | ||
| 261 | Vue.use(TimelineItem); | ||
| 262 | Vue.use(Link); | ||
| 263 | Vue.use(Divider); | ||
| 264 | Vue.use(Image); | ||
| 265 | Vue.use(Calendar); | ||
| 266 | Vue.use(Backtop); | ||
| 267 | Vue.use(PageHeader); | ||
| 268 | Vue.use(CascaderPanel); | ||
| 269 | Vue.use(Loading.directive); | ||
| 270 | |||
| 271 | import Schart from "vue-schart"; | ||
| 272 | import bus from "../../common/bus"; | ||
| 273 | |||
| 11 | // 按需引入 引入 ECharts 主模块 | 274 | // 按需引入 引入 ECharts 主模块 |
| 12 | // var echarts = require('echarts/lib/echarts') | 275 | // var echarts = require('echarts/lib/echarts') |
| 13 | // 引入柱状图 | 276 | // 引入柱状图 |
| 14 | // require('echarts/lib/chart/bar') | 277 | // require('echarts/lib/chart/bar') |
| 15 | // 引入提示框和标题组件 | 278 | // 引入提示框和标题组件 |
| 16 | // require('echarts/lib/component/tooltip') | 279 | // require('echarts/lib/component/tooltip') |
| 17 | // require('echarts/lib/component/title') | 280 | // require('echarts/lib/component/title') |
| 18 | // 全部引入 | 281 | // 全部引入 |
| 19 | // var echarts = require('echarts') | 282 | // var echarts = require('echarts') |
| 20 | 283 | ||
| 21 | export default { | 284 | export default { |
| 22 | name: 'Dashboard', | 285 | name: "Dashboard", |
| 286 | data() { | ||
| 287 | return { | ||
| 288 | name: localStorage.getItem("ms_username"), | ||
| 289 | todoList: [ | ||
| 290 | { | ||
| 291 | title: "今天要修复100个bug", | ||
| 292 | status: true | ||
| 293 | }, | ||
| 294 | { | ||
| 295 | title: "今天要写100行代码加几个bug吧", | ||
| 296 | status: true | ||
| 297 | } | ||
| 298 | ], | ||
| 299 | data: [ | ||
| 300 | { | ||
| 301 | name: "2018/09/04", | ||
| 302 | value: 1083 | ||
| 303 | }, | ||
| 304 | { | ||
| 305 | name: "2018/09/10", | ||
| 306 | value: 1065 | ||
| 307 | } | ||
| 308 | ], | ||
| 309 | options: { | ||
| 310 | type: "bar", | ||
| 311 | title: { | ||
| 312 | text: "最近一周各品类销售图" | ||
| 313 | }, | ||
| 314 | xRorate: 25, | ||
| 315 | labels: ["周一", "周二", "周三", "周四", "周五"], | ||
| 316 | datasets: [ | ||
| 317 | { | ||
| 318 | label: "百货", | ||
| 319 | data: [164, 178, 190, 135, 160] | ||
| 320 | }, | ||
| 321 | { | ||
| 322 | label: "食品", | ||
| 323 | data: [144, 198, 150, 235, 120] | ||
| 324 | } | ||
| 325 | ] | ||
| 326 | }, | ||
| 327 | options2: { | ||
| 328 | type: "line", | ||
| 329 | title: { | ||
| 330 | text: "最近几个月各品类销售趋势图" | ||
| 331 | }, | ||
| 332 | labels: ["6月", "7月", "8月", "9月", "10月"], | ||
| 333 | datasets: [ | ||
| 334 | { | ||
| 335 | label: "百货", | ||
| 336 | data: [164, 178, 150, 135, 160] | ||
| 337 | }, | ||
| 338 | { | ||
| 339 | label: "食品", | ||
| 340 | data: [74, 118, 200, 235, 90] | ||
| 341 | } | ||
| 342 | ] | ||
| 343 | } | ||
| 344 | }; | ||
| 345 | }, | ||
| 346 | components: { | ||
| 347 | Schart | ||
| 348 | }, | ||
| 23 | computed: { | 349 | computed: { |
| 24 | ...mapGetters([ | 350 | // ...mapGetters(["name", "roles"]) |
| 25 | 'name', | 351 | role() { |
| 26 | 'roles' | 352 | return this.name === "admin" ? "超级管理员" : "普通用户"; |
| 27 | ]) | 353 | } |
| 354 | }, | ||
| 355 | methods: { | ||
| 356 | addAction(){ | ||
| 357 | this.$prompt("请输入内容", "提示", { | ||
| 358 | confirmButtonText: "确定", | ||
| 359 | cancelButtonText: "取消", | ||
| 360 | inputErrorMessage: "内容不能为空" | ||
| 361 | }) | ||
| 362 | .then(({ value }) => { | ||
| 363 | this.$message({ | ||
| 364 | type: "success", | ||
| 365 | message: "你的邮箱是: " + value | ||
| 366 | }); | ||
| 367 | }) | ||
| 368 | .catch(() => { | ||
| 369 | this.$message({ | ||
| 370 | type: "info", | ||
| 371 | message: "取消输入" | ||
| 372 | }); | ||
| 373 | }); | ||
| 374 | }, | ||
| 375 | modiAction() { | ||
| 376 | // this.$prompt("请输入邮箱", "提示", { | ||
| 377 | // confirmButtonText: "确定", | ||
| 378 | // cancelButtonText: "取消", | ||
| 379 | // inputPattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/, | ||
| 380 | // inputErrorMessage: "邮箱格式不正确" | ||
| 381 | // }) | ||
| 382 | this.$prompt("请输入内容", "提示", { | ||
| 383 | confirmButtonText: "确定", | ||
| 384 | cancelButtonText: "取消", | ||
| 385 | inputErrorMessage: "内容不能为空" | ||
| 386 | }) | ||
| 387 | .then(({ value }) => { | ||
| 388 | this.$message({ | ||
| 389 | type: "success", | ||
| 390 | message: "你的邮箱是: " + value | ||
| 391 | }); | ||
| 392 | }) | ||
| 393 | .catch(() => { | ||
| 394 | this.$message({ | ||
| 395 | type: "info", | ||
| 396 | message: "取消输入" | ||
| 397 | }); | ||
| 398 | }); | ||
| 399 | }, | ||
| 400 | delAction() { | ||
| 401 | this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", { | ||
| 402 | confirmButtonText: "确定", | ||
| 403 | cancelButtonText: "取消", | ||
| 404 | type: "warning" | ||
| 405 | }) | ||
| 406 | .then(() => { | ||
| 407 | this.$message({ | ||
| 408 | type: "success", | ||
| 409 | message: "删除成功!" | ||
| 410 | }); | ||
| 411 | }) | ||
| 412 | .catch(() => { | ||
| 413 | this.$message({ | ||
| 414 | type: "info", | ||
| 415 | message: "已取消删除" | ||
| 416 | }); | ||
| 417 | }); | ||
| 418 | }, | ||
| 419 | changeDate() { | ||
| 420 | const now = new Date().getTime(); | ||
| 421 | this.data.forEach((item, index) => { | ||
| 422 | const date = new Date(now - (6 - index) * 86400000); | ||
| 423 | item.name = `${date.getFullYear()}/${date.getMonth() + | ||
| 424 | 1}/${date.getDate()}`; | ||
| 425 | }); | ||
| 426 | } | ||
| 28 | } | 427 | } |
| 29 | } | 428 | }; |
| 30 | </script> | 429 | </script> |
| 31 | 430 | ||
| 32 | <style lang="scss" scoped> | 431 | <style scoped> |
| 33 | .dashboard { | 432 | .el-row { |
| 34 | &-container { | 433 | margin-bottom: 20px; |
| 35 | margin: 30px; | 434 | } |
| 36 | } | 435 | .grid-content { |
| 37 | &-text { | 436 | display: flex; |
| 38 | font-size: 30px; | 437 | align-items: center; |
| 39 | line-height: 46px; | 438 | height: 100px; |
| 40 | } | 439 | } |
| 440 | .grid-cont-right { | ||
| 441 | flex: 1; | ||
| 442 | text-align: center; | ||
| 443 | font-size: 14px; | ||
| 444 | color: #999; | ||
| 445 | } | ||
| 446 | .grid-num { | ||
| 447 | font-size: 30px; | ||
| 448 | font-weight: bold; | ||
| 449 | } | ||
| 450 | .grid-con-icon { | ||
| 451 | font-size: 50px; | ||
| 452 | width: 100px; | ||
| 453 | height: 100px; | ||
| 454 | text-align: center; | ||
| 455 | line-height: 100px; | ||
| 456 | color: #fff; | ||
| 457 | } | ||
| 458 | .grid-con-1 .grid-con-icon { | ||
| 459 | background: rgb(45, 140, 240); | ||
| 460 | } | ||
| 461 | .grid-con-1 .grid-num { | ||
| 462 | color: rgb(45, 140, 240); | ||
| 463 | } | ||
| 464 | .grid-con-2 .grid-con-icon { | ||
| 465 | background: rgb(100, 213, 114); | ||
| 466 | } | ||
| 467 | .grid-con-2 .grid-num { | ||
| 468 | color: rgb(45, 140, 240); | ||
| 469 | } | ||
| 470 | .grid-con-3 .grid-con-icon { | ||
| 471 | background: rgb(242, 94, 67); | ||
| 472 | } | ||
| 473 | .grid-con-3 .grid-num { | ||
| 474 | color: rgb(242, 94, 67); | ||
| 475 | } | ||
| 476 | .user-info { | ||
| 477 | display: flex; | ||
| 478 | align-items: center; | ||
| 479 | padding-bottom: 20px; | ||
| 480 | border-bottom: 2px solid #ccc; | ||
| 481 | margin-bottom: 20px; | ||
| 482 | } | ||
| 483 | .user-avator { | ||
| 484 | width: 120px; | ||
| 485 | height: 120px; | ||
| 486 | border-radius: 50%; | ||
| 487 | } | ||
| 488 | .user-info-cont { | ||
| 489 | padding-left: 50px; | ||
| 490 | flex: 1; | ||
| 491 | font-size: 14px; | ||
| 492 | color: #999; | ||
| 493 | } | ||
| 494 | .user-info-cont div:first-child { | ||
| 495 | font-size: 30px; | ||
| 496 | color: #222; | ||
| 497 | } | ||
| 498 | .user-info-list { | ||
| 499 | font-size: 14px; | ||
| 500 | color: #999; | ||
| 501 | line-height: 25px; | ||
| 502 | } | ||
| 503 | .user-info-list span { | ||
| 504 | margin-left: 70px; | ||
| 505 | } | ||
| 506 | .mgb20 { | ||
| 507 | margin-bottom: 20px; | ||
| 508 | } | ||
| 509 | .todo-item { | ||
| 510 | font-size: 14px; | ||
| 511 | } | ||
| 512 | .todo-item-del { | ||
| 513 | text-decoration: line-through; | ||
| 514 | color: #999; | ||
| 515 | } | ||
| 516 | .schart { | ||
| 517 | width: 100%; | ||
| 518 | height: 300px; | ||
| 41 | } | 519 | } |
| 42 | </style> | 520 | </style> |
| 43 | 521 |
src/views/form/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="app-container"> | 2 | <div class="app-container"> |
| 3 | <el-form ref="form" :model="form" label-width="120px"> | 3 | <el-form ref="form" :model="form" label-width="120px"> |
| 4 | <el-form-item label="Activity name"> | 4 | <el-form-item label="Activity name"> |
| 5 | <el-input v-model="form.name" /> | 5 | <el-input v-model="form.name" /> |
| 6 | </el-form-item> | 6 | </el-form-item> |
| 7 | <el-form-item label="Activity zone"> | 7 | <el-form-item label="Activity zone"> |
| 8 | <el-select v-model="form.region" placeholder="please select your zone"> | 8 | <el-select v-model="form.region" placeholder="please select your zone"> |
| 9 | <el-option label="Zone one" value="shanghai" /> | 9 | <el-option label="Zone one" value="shanghai" /> |
| 10 | <el-option label="Zone two" value="beijing" /> | 10 | <el-option label="Zone two" value="beijing" /> |
| 11 | </el-select> | 11 | </el-select> |
| 12 | </el-form-item> | 12 | </el-form-item> |
| 13 | <el-form-item label="Activity time"> | 13 | <el-form-item label="Activity time"> |
| 14 | <el-col :span="11"> | 14 | <el-col :span="11"> |
| 15 | <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" /> | 15 | <el-date-picker |
| 16 | v-model="form.date1" | ||
| 17 | type="date" | ||
| 18 | placeholder="Pick a date" | ||
| 19 | style="width: 100%;" | ||
| 20 | /> | ||
| 16 | </el-col> | 21 | </el-col> |
| 17 | <el-col :span="2" class="line">-</el-col> | 22 | <el-col :span="2" class="line">-</el-col> |
| 18 | <el-col :span="11"> | 23 | <el-col :span="11"> |
| 19 | <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" /> | 24 | <el-time-picker |
| 25 | v-model="form.date2" | ||
| 26 | type="fixed-time" | ||
| 27 | placeholder="Pick a time" | ||
| 28 | style="width: 100%;" | ||
| 29 | /> | ||
| 20 | </el-col> | 30 | </el-col> |
| 21 | </el-form-item> | 31 | </el-form-item> |
| 22 | <el-form-item label="Instant delivery"> | 32 | <el-form-item label="Instant delivery"> |
| 23 | <el-switch v-model="form.delivery" /> | 33 | <el-switch v-model="form.delivery" /> |
| 24 | </el-form-item> | 34 | </el-form-item> |
| 25 | <el-form-item label="Activity type"> | 35 | <el-form-item label="Activity type"> |
| 26 | <el-checkbox-group v-model="form.type"> | 36 | <el-checkbox-group v-model="form.type"> |
| 27 | <el-checkbox label="Online activities" name="type" /> | 37 | <el-checkbox label="Online activities" name="type" /> |
| 28 | <el-checkbox label="Promotion activities" name="type" /> | 38 | <el-checkbox label="Promotion activities" name="type" /> |
| 29 | <el-checkbox label="Offline activities" name="type" /> | 39 | <el-checkbox label="Offline activities" name="type" /> |
| 30 | <el-checkbox label="Simple brand exposure" name="type" /> | 40 | <el-checkbox label="Simple brand exposure" name="type" /> |
| 31 | </el-checkbox-group> | 41 | </el-checkbox-group> |
| 32 | </el-form-item> | 42 | </el-form-item> |
| 33 | <el-form-item label="Resources"> | 43 | <el-form-item label="Resources"> |
| 34 | <el-radio-group v-model="form.resource"> | 44 | <el-radio-group v-model="form.resource"> |
| 35 | <el-radio label="Sponsor" /> | 45 | <el-radio label="Sponsor" /> |
| 36 | <el-radio label="Venue" /> | 46 | <el-radio label="Venue" /> |
| 37 | </el-radio-group> | 47 | </el-radio-group> |
| 38 | </el-form-item> | 48 | </el-form-item> |
| 39 | <el-form-item label="Activity form"> | 49 | <el-form-item label="Activity form"> |
| 40 | <el-input v-model="form.desc" type="textarea" /> | 50 | <el-input v-model="form.desc" type="textarea" /> |
| 41 | </el-form-item> | 51 | </el-form-item> |
| 42 | <el-form-item> | 52 | <el-form-item> |
| 43 | <el-button type="primary" @click="onSubmit">Create</el-button> | 53 | <el-button type="primary" @click="onSubmit">Create</el-button> |
| 44 | <el-button @click="onCancel">Cancel</el-button> | 54 | <el-button @click="onCancel">Cancel</el-button> |
| 45 | </el-form-item> | 55 | </el-form-item> |
| 46 | </el-form> | 56 | </el-form> |
| 47 | </div> | 57 | </div> |
| 48 | </template> | 58 | </template> |
| 49 | 59 | ||
| 50 | <script> | 60 | <script> |
| 51 | export default { | 61 | export default { |
| 52 | data() { | 62 | data() { |
| 53 | return { | 63 | return { |
| 54 | form: { | 64 | form: { |
| 55 | name: '', | 65 | name: "", |
| 56 | region: '', | 66 | region: "", |
| 57 | date1: '', | 67 | date1: "", |
| 58 | date2: '', | 68 | date2: "", |
| 59 | delivery: false, | 69 | delivery: false, |
| 60 | type: [], | 70 | type: [], |
| 61 | resource: '', | 71 | resource: "", |
| 62 | desc: '' | 72 | desc: "" |
| 63 | } | 73 | } |
| 64 | } | 74 | }; |
| 65 | }, | 75 | }, |
| 66 | methods: { | 76 | methods: { |
| 67 | onSubmit() { | 77 | onSubmit() { |
| 68 | this.$message('submit!') | 78 | this.$message("submit!"); |
| 69 | }, | 79 | }, |
| 70 | onCancel() { | 80 | onCancel() { |
| 71 | this.$message({ | 81 | this.$message({ |
| 72 | message: 'cancel!', | 82 | message: "cancel!", |
| 73 | type: 'warning' | 83 | type: "warning" |
| 74 | }) | 84 | }); |
| 75 | } | 85 | } |
| 76 | } | 86 | } |
| 77 | } | 87 | }; |
| 78 | </script> | 88 | </script> |
| 79 | 89 | ||
| 80 | <style scoped> | 90 | <style scoped> |
| 81 | .line{ | 91 | .line { |
| 82 | text-align: center; | 92 | text-align: center; |
| 83 | } | 93 | } |
| 84 | </style> | 94 | </style> |
| 85 | 95 | ||
| 86 | 96 |
src/views/nested/menu1/menu1-1/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div style="padding:30px;"> | 2 | <div style="padding:30px;"> |
| 3 | <el-alert :closable="false" title="menu 1-1" type="success"> | 3 | <el-alert :closable="false" title="menu 1-1" type="success"> |
| 4 | <router-view /> | 4 | <router-view /> |
| 5 | </el-alert> | 5 | </el-alert> |
| 6 | </div> | 6 | </div> |
| 7 | </template> | 7 | </template> |
| 8 | <template functional> | ||
| 9 | <div style="padding:30px;"> | ||
| 10 | <el-alert :closable="false" title="menu 1-2-1" type="warning" /> | ||
| 11 | </div> | ||
| 12 | </template> |
src/views/table/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="app-container"> | 2 | <div class="app-container"> |
| 3 | <el-table | 3 | <el-table |
| 4 | v-loading="listLoading" | 4 | v-loading="listLoading" |
| 5 | :data="list" | 5 | :data="list" |
| 6 | element-loading-text="Loading" | 6 | element-loading-text="Loading" |
| 7 | border | 7 | border |
| 8 | fit | 8 | fit |
| 9 | highlight-current-row | 9 | highlight-current-row |
| 10 | > | 10 | > |
| 11 | <el-table-column align="center" label="ID" width="95"> | 11 | <el-table-column align="center" label="用户id"> |
| 12 | <template slot-scope="scope"> | 12 | <template slot-scope="scope">{{ scope.$index }}</template> |
| 13 | {{ scope.$index }} | 13 | </el-table-column> |
| 14 | </template> | 14 | |
| 15 | <el-table-column label="openid"> | ||
| 16 | <template slot-scope="scope">{{ scope.row.openid }}</template> | ||
| 15 | </el-table-column> | 17 | </el-table-column> |
| 16 | <el-table-column label="Title"> | 18 | |
| 19 | <el-table-column label="昵称" width="110" align="center"> | ||
| 17 | <template slot-scope="scope"> | 20 | <template slot-scope="scope"> |
| 18 | {{ scope.row.title }} | 21 | <span>{{ scope.row.username }}</span> |
| 19 | </template> | 22 | </template> |
| 20 | </el-table-column> | 23 | </el-table-column> |
| 21 | <el-table-column label="Author" width="110" align="center"> | 24 | |
| 25 | <el-table-column label="头像" width="110" align="center"> | ||
| 26 | <template slot-scope="scope">{{ scope.row.avatar }}</template> | ||
| 27 | </el-table-column> | ||
| 28 | |||
| 29 | <el-table-column class-name="status-col" label="状态" align="center"> | ||
| 22 | <template slot-scope="scope"> | 30 | <template slot-scope="scope"> |
| 23 | <span>{{ scope.row.author }}</span> | 31 | <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag> |
| 24 | </template> | 32 | </template> |
| 25 | </el-table-column> | 33 | </el-table-column> |
| 26 | <el-table-column label="Pageviews" width="110" align="center"> | 34 | |
| 35 | <el-table-column align="center" prop="created_at" label="注册时间"> | ||
| 27 | <template slot-scope="scope"> | 36 | <template slot-scope="scope"> |
| 28 | {{ scope.row.pageviews }} | 37 | <i class="el-icon-time" /> |
| 38 | <span>{{ scope.row.create_at }}</span> | ||
| 29 | </template> | 39 | </template> |
| 30 | </el-table-column> | 40 | </el-table-column> |
| 31 | <el-table-column class-name="status-col" label="Status" width="110" align="center"> | 41 | <el-table-column align="center" prop="created_at" label="成交记录"> |
| 32 | <template slot-scope="scope"> | 42 | <template slot-scope="scope"> |
| 33 | <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag> | 43 | <i class="el-icon-time" /> |
| 44 | <span>{{ scope.row.pageviews }}</span> | ||
| 34 | </template> | 45 | </template> |
| 35 | </el-table-column> | 46 | </el-table-column> |
| 36 | <el-table-column align="center" prop="created_at" label="Display_time" width="200"> | 47 | <el-table-column align="center" prop="created_at" label="引流图"> |
| 37 | <template slot-scope="scope"> | 48 | <template slot-scope="scope"> |
| 38 | <i class="el-icon-time" /> | 49 | <span> |
| 39 | <span>{{ scope.row.display_time }}</span> | 50 | <el-button type="primary">子用户{{scope.row.pageviews}}</el-button> |
| 51 | </span> | ||
| 40 | </template> | 52 | </template> |
| 41 | </el-table-column> | 53 | </el-table-column> |
| 42 | </el-table> | 54 | </el-table> |
| 55 | <el-pagination background layout="prev, pager, next" :total="100"></el-pagination> | ||
| 43 | </div> | 56 | </div> |
| 44 | </template> | 57 | </template> |
| 45 | 58 | ||
| 46 | <script> | 59 | <script> |
| 47 | import { getList } from '@/api/table' | 60 | import { getList } from "@/api/table"; |
| 48 | 61 | ||
| 49 | export default { | 62 | export default { |
| 50 | filters: { | 63 | filters: { |
| 51 | statusFilter(status) { | 64 | statusFilter(status) { |
| 52 | const statusMap = { | 65 | const statusMap = { |
| 53 | published: 'success', | 66 | published: "success", |
| 54 | draft: 'gray', | 67 | draft: "gray", |
| 55 | deleted: 'danger' | 68 | deleted: "danger" |
| 56 | } | 69 | }; |
| 57 | return statusMap[status] | 70 | return statusMap[status]; |
| 58 | } | 71 | } |
| 59 | }, | 72 | }, |
| 60 | data() { | 73 | data() { |
| 61 | return { | 74 | return { |
| 62 | list: null, | 75 | list: null, |
| 63 | listLoading: true | 76 | listLoading: true |
| 64 | } | 77 | }; |
| 65 | }, | 78 | }, |
| 66 | created() { | 79 | created() { |
| 67 | this.fetchData() | 80 | this.fetchData(); |
| 68 | }, | 81 | }, |
| 69 | methods: { | 82 | methods: { |
| 70 | fetchData() { | 83 | fetchData() { |
| 71 | this.listLoading = true | 84 | this.listLoading = true; |
| 72 | getList().then(response => { | 85 | getList().then(response => { |
| 73 | console.log('----getList---', response) | 86 | console.log("----getList---", response); |
| 74 | this.list = response.data.items | 87 | this.list = response.data.items; |
| 75 | this.listLoading = false | 88 | this.listLoading = false; |
| 76 | }) | 89 | }); |
| 77 | } | 90 | } |
| 78 | } | 91 | } |
| 79 | } | 92 | }; |
| 80 | </script> | 93 | </script> |
| 81 | 94 |