Merge Request #3

Merged
Created by Adam

Master

Assignee: None
Milestone: None

Merged by Adam

Commits (1)
1 participants
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
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
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
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
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
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
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
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>
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
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,
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>
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>
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