Merge Request #4
← To merge requests
From
adam:master
into
jp:master
Commits (1)
Showing
7 changed files
Show diff stats
mock/mock-server.js
1 | const chokidar = require('chokidar') | 1 | const chokidar = require('chokidar') |
2 | const bodyParser = require('body-parser') | 2 | const bodyParser = require('body-parser') |
3 | const chalk = require('chalk') | 3 | const chalk = require('chalk') |
4 | const path = require('path') | 4 | const path = require('path') |
5 | 5 | ||
6 | const mockDir = path.join(process.cwd(), 'mock') | 6 | const mockDir = path.join(process.cwd(), 'mock') |
7 | 7 | ||
8 | function registerRoutes(app) { | 8 | function registerRoutes(app) { |
9 | let mockLastIndex | 9 | let mockLastIndex |
10 | const { default: mocks } = require('./index.js') | 10 | const { default: mocks } = require('./index.js') |
11 | for (const mock of mocks) { | 11 | for (const mock of mocks) { |
12 | app[mock.type](mock.url, mock.response) | 12 | app[mock.type](mock.url, mock.response) |
13 | mockLastIndex = app._router.stack.length | 13 | mockLastIndex = app._router.stack.length |
14 | } | 14 | } |
15 | const mockRoutesLength = Object.keys(mocks).length | 15 | const mockRoutesLength = Object.keys(mocks).length |
16 | return { | 16 | return { |
17 | mockRoutesLength: mockRoutesLength, | 17 | mockRoutesLength: mockRoutesLength, |
18 | mockStartIndex: mockLastIndex - mockRoutesLength | 18 | mockStartIndex: mockLastIndex - mockRoutesLength |
19 | } | 19 | } |
20 | } | 20 | } |
21 | 21 | ||
22 | function unregisterRoutes() { | 22 | function unregisterRoutes() { |
23 | Object.keys(require.cache).forEach(i => { | 23 | Object.keys(require.cache).forEach(i => { |
24 | if (i.includes(mockDir)) { | 24 | if (i.includes(mockDir)) { |
25 | delete require.cache[require.resolve(i)] | 25 | delete require.cache[require.resolve(i)] |
26 | } | 26 | } |
27 | }) | 27 | }) |
28 | } | 28 | } |
29 | 29 | ||
30 | module.exports = app => { | 30 | module.exports = app => { |
31 | // es6 polyfill | 31 | // es6 polyfill |
32 | require('@babel/register') | 32 | require('@babel/register') |
33 | 33 | ||
34 | // parse app.body | 34 | // parse app.body |
35 | // https://expressjs.com/en/4x/api.html#req.body | 35 | // https://expressjs.com/en/4x/api.html#req.body |
36 | app.use(bodyParser.json()) | 36 | app.use(bodyParser.json()) |
37 | app.use(bodyParser.urlencoded({ | 37 | app.use(bodyParser.urlencoded({ |
38 | extended: true | 38 | extended: true |
39 | })) | 39 | })) |
40 | 40 | ||
41 | const mockRoutes = registerRoutes(app) | 41 | const mockRoutes = registerRoutes(app) |
42 | var mockRoutesLength = mockRoutes.mockRoutesLength | 42 | var mockRoutesLength = mockRoutes.mockRoutesLength |
43 | var mockStartIndex = mockRoutes.mockStartIndex | 43 | var mockStartIndex = mockRoutes.mockStartIndex |
44 | 44 | ||
45 | // watch files, hot reload mock server | 45 | // watch files, hot reload mock server |
46 | chokidar.watch(mockDir, { | 46 | chokidar.watch(mockDir, { |
47 | ignored: /mock-server/, | 47 | ignored: /mock-server/, |
48 | ignoreInitial: true | 48 | ignoreInitial: true |
49 | }).on('all', (event, path) => { | 49 | }).on('all', (event, path) => { |
50 | if (event === 'change' || event === 'add') { | 50 | if (event === 'change' || event === 'add') { |
51 | try { | 51 | try { |
52 | // remove mock routes stack | 52 | // remove mock routes stack |
53 | app._router.stack.splice(mockStartIndex, mockRoutesLength) | 53 | app._router.stack.splice(mockStartIndex, mockRoutesLength) |
54 | 54 | ||
55 | // clear routes cache | 55 | // clear routes cache |
56 | unregisterRoutes() | 56 | unregisterRoutes() |
57 | 57 | ||
58 | const mockRoutes = registerRoutes(app) | 58 | const mockRoutes = registerRoutes(app) |
59 | mockRoutesLength = mockRoutes.mockRoutesLength | 59 | mockRoutesLength = mockRoutes.mockRoutesLength |
60 | mockStartIndex = mockRoutes.mockStartIndex | 60 | mockStartIndex = mockRoutes.mockStartIndex |
61 | 61 | ||
62 | console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) | 62 | console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) |
63 | } catch (error) { | 63 | } catch (error) { |
64 | console.log(chalk.redBright(error)) | 64 | console.error(chalk.redBright(error)) |
65 | } | 65 | } |
66 | } | 66 | } |
67 | }) | 67 | }) |
68 | } | 68 | } |
69 | 69 |
mock/user.js
1 | |||
2 | const tokens = { | 1 | const tokens = { |
3 | admin: { | 2 | admin: { |
4 | token: 'admin-token' | 3 | token: 'admin-token' |
5 | }, | 4 | }, |
6 | assistant: { | 5 | assistant: { |
7 | token: 'assistant-token' | 6 | token: 'assistant-token' |
8 | }, | 7 | }, |
9 | editor: { | 8 | runner: { |
10 | token: 'editor-token' | 9 | token: 'runner-token' |
11 | }, | 10 | }, |
12 | shoper: { | 11 | shoper: { |
13 | token: 'shoper-token' | 12 | token: 'shoper-token' |
14 | } | 13 | } |
15 | } | 14 | } |
16 | 15 | ||
17 | const users = { | 16 | const users = { |
18 | 'admin-token': {//管理员 | 17 | 'admin-token': { //管理员 |
19 | roles: ['admin'], | 18 | roles: ['admin'], |
20 | introduction: 'I am a super administrator', | 19 | introduction: 'I am a super administrator', |
21 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | 20 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
22 | name: 'Super Admin' | 21 | name: 'Super Admin' |
23 | }, | 22 | }, |
24 | 'assistant-token': {//管理员助理 | 23 | 'assistant-token': { //管理员助理 |
25 | roles: ['assistant'], | 24 | roles: ['assistant'], |
26 | introduction: 'I am a assistant of administrator', | 25 | introduction: 'I am a assistant of administrator', |
27 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | 26 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
28 | name: 'Super Admin' | 27 | name: 'assistant Admin' |
29 | }, | 28 | }, |
30 | 'editor-token': {//运营人员 | 29 | 'runner-token': { //运营人员 |
31 | roles: ['editor'], | 30 | roles: ['runner'], |
32 | introduction: 'I am an editor', | 31 | introduction: 'I am an runner', |
33 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | 32 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
34 | name: 'Normal Editor' | 33 | name: 'Normal runner' |
35 | }, | 34 | }, |
36 | 'shoper-token': {//供应商 | 35 | 'shoper-token': { //供应商 |
37 | roles: ['shoper'], | 36 | roles: ['shoper'], |
38 | introduction: 'I am an shoper', | 37 | introduction: 'I am an shoper', |
39 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', | 38 | avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
40 | name: 'Normal Editor' | 39 | name: 'Normal shoper' |
41 | } | 40 | } |
42 | } | 41 | } |
43 | 42 | ||
44 | export default [ | 43 | export default [{ // user login |
45 | // user login | ||
46 | { | ||
47 | url: '/yp/user/login', | 44 | url: '/yp/user/login', |
48 | type: 'post', | 45 | type: 'post', |
49 | response: config => { | 46 | response: config => { |
50 | const { username } = config.body | 47 | console.log('config-------->', config.body); |
51 | const token = tokens[username] | 48 | const { |
52 | // mock error | 49 | username, |
53 | if (!token) { | 50 | password |
51 | } = config.body; | ||
52 | if (username == 'admin' && password == '111111') { | ||
53 | const token = tokens[username]; | ||
54 | if (!token) { | ||
55 | return { | ||
56 | code: 60204, | ||
57 | message: 'Account and password are incorrect.' | ||
58 | } | ||
59 | } else { | ||
60 | return { | ||
61 | code: 20000, | ||
62 | data: token | ||
63 | } | ||
64 | } | ||
65 | } else { | ||
54 | return { | 66 | return { |
55 | code: 60204, | 67 | code: 60204, |
56 | message: 'Account and password are incorrect.' | 68 | message: 'Account and password are incorrect.' |
57 | } | 69 | } |
58 | } | 70 | } |
59 | |||
60 | return { | ||
61 | code: 20000, | ||
62 | data: token | ||
63 | } | ||
64 | } | 71 | } |
65 | }, | 72 | }, |
66 | 73 | ||
67 | // get user info | 74 | // get user info |
68 | { | 75 | { |
69 | url: '/yp/user/info\.*', | 76 | url: '/yp/user/info\.*', |
70 | type: 'get', | 77 | type: 'get', |
71 | response: config => { | 78 | response: config => { |
72 | const { token } = config.query | 79 | const { |
80 | token | ||
81 | } = config.query | ||
73 | const info = users[token] | 82 | const info = users[token] |
74 | 83 | ||
75 | // mock error | 84 | // mock error |
76 | if (!info) { | 85 | if (!info) { |
77 | return { | 86 | return { |
78 | code: 50008, | 87 | code: 50008, |
79 | message: 'Login failed, unable to get user details.' | 88 | message: 'Login failed, unable to get user details.' |
80 | } | 89 | } |
81 | } | 90 | } |
82 | 91 | ||
83 | return { | 92 | return { |
84 | code: 20000, | 93 | code: 20000, |
85 | data: info | 94 | data: info |
86 | } | 95 | } |
87 | } | 96 | } |
88 | }, | 97 | }, |
89 | 98 | ||
90 | // user logout | 99 | // user logout |
91 | { | 100 | { |
92 | url: '/yp/user/logout', | 101 | url: '/yp/user/logout', |
93 | type: 'post', | 102 | type: 'post', |
94 | response: _ => { | 103 | response: _ => { |
src/api/user.js
1 | import request from '@/utils/request' | 1 | import request from '@/utils/request' |
2 | // var qs = require('Qs'); | ||
2 | 3 | ||
3 | export function login(data) { | 4 | export function login(data) { |
4 | console.log('login....', data) | 5 | console.log('login.1111...', data) |
5 | return request({ | 6 | return request({ |
6 | url: '/yp/user/login', | 7 | // url: '/yp/user/login', |
8 | url: '/yp.user.login.php', | ||
7 | method: 'post', | 9 | method: 'post', |
8 | data | 10 | headers: { |
9 | }) | 11 | 'Content-type': 'application/x-www-form-urlencoded' |
12 | }, | ||
13 | data, | ||
14 | // responseType: 'text/plain', | ||
15 | // onDownloadProgress: false, | ||
16 | // onUploadProgress: true, | ||
17 | // proxy: {} | ||
18 | }); | ||
10 | } | 19 | } |
11 | 20 | ||
12 | export function getInfo(token) { | 21 | export function getInfo(token) { |
13 | console.log('getInfo....', token) | 22 | console.log('getInfo....', token) |
14 | return request({ | 23 | return request({ |
15 | url: '/yp/user/info', | 24 | url: '/yp/user/info', |
16 | method: 'get', | 25 | method: 'get', |
17 | params: { token } | 26 | params: { |
27 | token | ||
28 | } | ||
18 | }) | 29 | }) |
19 | } | 30 | } |
20 | 31 | ||
21 | export function list(token) { | 32 | export function list(token) { |
22 | console.log('listUser....', token) | 33 | console.log('listUser....', token) |
23 | return request({ | 34 | return request({ |
24 | url: '/yp/user/list', | 35 | url: '/yp/user/list', |
25 | method: 'get', | 36 | method: 'get', |
26 | params: { token } | 37 | params: { |
38 | token | ||
39 | } | ||
27 | }) | 40 | }) |
28 | } | 41 | } |
29 | 42 | ||
30 | export function add(token) { | 43 | export function add(token) { |
31 | console.log('addUser....', token) | 44 | console.log('addUser....', token) |
32 | return request({ | 45 | return request({ |
33 | url: '/yp/user/add', | 46 | url: '/yp/user/add', |
34 | method: 'get', | 47 | method: 'get', |
35 | params: { token } | 48 | params: { |
49 | token | ||
50 | } | ||
36 | }) | 51 | }) |
37 | } | 52 | } |
38 | 53 | ||
39 | export function modi(token) { | 54 | export function modi(token) { |
40 | console.log('modiUser....', token) | 55 | console.log('modiUser....', token) |
41 | return request({ | 56 | return request({ |
42 | url: '/yp/user/modi', | 57 | url: '/yp/user/modi', |
43 | method: 'get', | 58 | method: 'get', |
44 | params: { token } | 59 | params: { |
60 | token | ||
61 | } | ||
45 | }) | 62 | }) |
46 | } | 63 | } |
47 | 64 | ||
48 | export function logout() { | 65 | export function logout() { |
49 | console.log('logout....') | 66 | console.log('logout....') |
50 | return request({ | 67 | return request({ |
51 | url: '/yp/user/logout', | 68 | url: '/yp/user/logout', |
52 | method: 'post' | 69 | method: 'post' |
53 | }) | 70 | }) |
54 | } | 71 | } |
55 | 72 |
src/store/modules/user.js
1 | import { login, logout, getInfo } from '@/api/user' | 1 | import { login, logout, getInfo } from '@/api/user' |
2 | import { getToken, setToken, removeToken } from '@/utils/auth' | 2 | import { getToken, setToken, removeToken } from '@/utils/auth' |
3 | import { resetRouter } from '@/router' | 3 | import { resetRouter } from '@/router' |
4 | 4 | ||
5 | const getDefaultState = () => { | 5 | const getDefaultState = () => { |
6 | return { | 6 | return { |
7 | token: getToken(), | 7 | token: getToken(), |
8 | name: '', | 8 | name: '', |
9 | avatar: '', | 9 | avatar: '', |
10 | roles: [] | 10 | roles: [] |
11 | } | 11 | } |
12 | } | 12 | } |
13 | 13 | ||
14 | const state = getDefaultState() | 14 | const state = getDefaultState() |
15 | 15 | ||
16 | const mutations = { | 16 | const mutations = { |
17 | RESET_STATE: (state) => { | 17 | RESET_STATE: (state) => { |
18 | Object.assign(state, getDefaultState()) | 18 | Object.assign(state, getDefaultState()) |
19 | }, | 19 | }, |
20 | SET_TOKEN: (state, token) => { | 20 | SET_TOKEN: (state, token) => { |
21 | state.token = token | 21 | state.token = token |
22 | }, | 22 | }, |
23 | SET_NAME: (state, name) => { | 23 | SET_NAME: (state, name) => { |
24 | state.name = name | 24 | state.name = name |
25 | }, | 25 | }, |
26 | SET_AVATAR: (state, avatar) => { | 26 | SET_AVATAR: (state, avatar) => { |
27 | state.avatar = avatar | 27 | state.avatar = avatar |
28 | }, | 28 | }, |
29 | SET_ROLES: (state, roles) => { | 29 | SET_ROLES: (state, roles) => { |
30 | state.roles = roles | 30 | state.roles = roles |
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | const actions = { | 34 | const actions = { |
35 | // user login | 35 | // user login |
36 | login({ commit }, userInfo) { | 36 | login({ commit }, userInfo) { |
37 | const { username, password } = userInfo | 37 | const { username, password } = userInfo |
38 | return new Promise((resolve, reject) => { | 38 | return new Promise((resolve, reject) => { |
39 | login({ username: username.trim(), password: password }).then(response => { | 39 | login({ username: username.trim(), password: password }).then(response => { |
40 | const { data } = response | 40 | const { data } = response |
41 | console.log('action------->login------->处理', data); | ||
41 | commit('SET_TOKEN', data.token) | 42 | commit('SET_TOKEN', data.token) |
42 | setToken(data.token) | 43 | setToken(data.token) |
43 | resolve() | 44 | resolve() |
44 | }).catch(error => { | 45 | }).catch(error => { |
45 | reject(error) | 46 | reject(error) |
46 | }) | 47 | }) |
47 | }) | 48 | }) |
48 | }, | 49 | }, |
49 | 50 | ||
50 | // get user info | 51 | // get user info |
51 | getInfo({ commit, state }) { | 52 | getInfo({ commit, state }) { |
52 | return new Promise((resolve, reject) => { | 53 | return new Promise((resolve, reject) => { |
53 | getInfo(state.token).then(response => { | 54 | getInfo(state.token).then(response => { |
54 | const { data } = response | 55 | const { data } = response |
55 | |||
56 | if (!data) { | 56 | if (!data) { |
57 | reject('Verification failed, please Login again.') | 57 | reject('Verification failed, please Login again.') |
58 | } | 58 | } |
59 | |||
60 | const { roles, name, avatar } = data | 59 | const { roles, name, avatar } = data |
61 | |||
62 | // roles must be a non-empty array | 60 | // roles must be a non-empty array |
63 | if (!roles || roles.length <= 0) { | 61 | if (!roles || roles.length <= 0) { |
64 | reject('getInfo: roles must be a non-null array!') | 62 | reject('getInfo: roles must be a non-null array!') |
65 | } | 63 | } |
66 | |||
67 | commit('SET_ROLES', roles) | 64 | commit('SET_ROLES', roles) |
68 | commit('SET_NAME', name) | 65 | commit('SET_NAME', name) |
69 | commit('SET_AVATAR', avatar) | 66 | commit('SET_AVATAR', avatar) |
70 | resolve(data) | 67 | resolve(data) |
71 | }).catch(error => { | 68 | }).catch(error => { |
72 | reject(error) | 69 | reject(error) |
73 | }) | 70 | }) |
74 | }) | 71 | }) |
75 | }, | 72 | }, |
76 | 73 | ||
77 | // user logout | 74 | // user logout |
78 | logout({ commit, state }) { | 75 | logout({ commit, state }) { |
79 | return new Promise((resolve, reject) => { | 76 | return new Promise((resolve, reject) => { |
80 | logout(state.token).then(() => { | 77 | logout(state.token).then(() => { |
81 | removeToken() // must remove token first | 78 | removeToken() // must remove token first |
82 | resetRouter() | 79 | resetRouter() |
83 | commit('RESET_STATE') | 80 | commit('RESET_STATE') |
84 | resolve() | 81 | resolve() |
85 | }).catch(error => { | 82 | }).catch(error => { |
86 | reject(error) | 83 | reject(error) |
87 | }) | 84 | }) |
88 | }) | 85 | }) |
89 | }, | 86 | }, |
90 | 87 | ||
91 | // remove token | 88 | // remove token |
92 | resetToken({ commit }) { | 89 | resetToken({ commit }) { |
93 | return new Promise(resolve => { | 90 | return new Promise(resolve => { |
94 | removeToken() // must remove token first | 91 | removeToken() // must remove token first |
95 | commit('RESET_STATE') | 92 | commit('RESET_STATE') |
96 | resolve() | 93 | resolve() |
97 | }) | 94 | }) |
98 | } | 95 | } |
99 | } | 96 | } |
100 | 97 | ||
101 | export default { | 98 | export default { |
102 | namespaced: true, | 99 | namespaced: true, |
103 | state, | 100 | state, |
104 | mutations, | 101 | mutations, |
105 | actions | 102 | actions |
106 | } | 103 | } |
107 | 104 |
src/utils/request.js
1 | import axios from 'axios' | 1 | import axios from 'axios' |
2 | import { MessageBox, Message } from 'element-ui' | 2 | import { |
3 | MessageBox, | ||
4 | Message | ||
5 | } from 'element-ui' | ||
3 | import store from '@/store' | 6 | import store from '@/store' |
4 | import { getToken } from '@/utils/auth' | 7 | import { |
8 | getToken | ||
9 | } from '@/utils/auth' | ||
5 | 10 | ||
6 | // create an axios instance | 11 | // create an axios instance |
7 | // 创建axios实例 | 12 | // 创建axios实例 |
8 | const service = axios.create({ | 13 | const service = axios.create({ |
14 | // baseURL: '', // url = base url + request url | ||
9 | baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url | 15 | baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url |
10 | // withCredentials: true, // send cookies when cross-domain requests | 16 | // withCredentials: true, // send cookies when cross-domain requests |
11 | timeout: 5000 // request timeout | 17 | timeout: 5000, // request timeout |
18 | headers: { | ||
19 | 'Content-Type': 'application/x-www-form-urlencoded' | ||
20 | } | ||
12 | }) | 21 | }) |
13 | 22 | ||
14 | // request interceptor | 23 | // request interceptor |
15 | // request拦截器 | 24 | // request拦截器 |
16 | service.interceptors.request.use( | 25 | service.interceptors.request.use( |
17 | config => { | 26 | config => { |
18 | // do something before request is sent | 27 | // do something before request is sent |
19 | console.log('do something before request is sent') | 28 | // console.log('do something before request is sent') |
20 | if (store.getters.token) { | 29 | if (store.getters.token) { |
21 | console.log('[X-Token] is a custom headers key') | 30 | // console.log('[X-Token] is a custom headers key') |
22 | // let each request carry token | 31 | // let each request carry token |
23 | // ['X-Token'] is a custom headers key | 32 | // ['X-Token'] is a custom headers key |
24 | // please modify it according to the actual situation | 33 | // please modify it according to the actual situation |
25 | config.headers['X-Token'] = getToken() | 34 | config.headers['X-Token'] = getToken(); |
35 | config.headers['Content-Type'] = 'application/x-www-form-urlencoded'; | ||
36 | // var token = getToken() | ||
37 | // Object.assign(config.headers, { 'token': token }) | ||
26 | } | 38 | } |
27 | return config | 39 | return config |
28 | }, | 40 | }, |
29 | error => { | 41 | error => { |
30 | console.log('do something with request error') | 42 | // console.log('do something with request error') |
31 | // do something with request error | 43 | // do something with request error |
32 | console.log(error) // for debug | 44 | console.error(error) // for debug |
33 | return Promise.reject(error) | 45 | return Promise.reject(error) |
34 | } | 46 | } |
35 | ) | 47 | ) |
36 | 48 | ||
37 | // response interceptor | 49 | // response interceptor |
38 | // respone拦截器 | 50 | // respone拦截器 |
39 | service.interceptors.response.use( | 51 | service.interceptors.response.use( |
40 | /** | 52 | /** |
41 | * If you want to get http information such as headers or status | 53 | * If you want to get http information such as headers or status |
42 | * Please return response => response | 54 | * Please return response => response |
43 | */ | 55 | */ |
44 | 56 | ||
45 | /** | 57 | /** |
46 | * Determine the request status by custom code | 58 | * Determine the request status by custom code |
47 | * Here is just an example | 59 | * Here is just an example |
48 | * You can also judge the status by HTTP Status Code | 60 | * You can also judge the status by HTTP Status Code |
49 | */ | 61 | */ |
50 | response => { | 62 | response => { |
51 | const res = response.data | 63 | const res = response.data |
64 | console.log('返回的数据-------->', res); | ||
52 | /** | 65 | /** |
53 | * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页 | 66 | * 下面的注释为通过response自定义code来标示请求状态,当code返回如下情况为权限有问题,登出并返回到登录页 |
54 | * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中 | 67 | * 如通过xmlhttprequest 状态码标识 逻辑可写在下面error中 |
55 | */ | 68 | */ |
56 | console.log('if the custom code is not 20000, it is judged as an error.') | 69 | // console.log('if the custom code is not 20000, it is judged as an error.') |
57 | // if the custom code is not 20000, it is judged as an error. | ||
58 | if (res.code !== 20000) { | 70 | if (res.code !== 20000) { |
59 | Message({ | 71 | Message({ |
60 | message: res.message || 'Error', | 72 | message: res.message || 'Error', |
61 | type: 'error', | 73 | type: 'error', |
62 | duration: 5 * 1000 | 74 | duration: 5 * 1000 |
63 | }) | 75 | }) |
64 | 76 | ||
65 | // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; | ||
66 | // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; | 77 | // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; |
67 | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { | 78 | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { |
68 | // to re-login | 79 | // to re-login |
69 | // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { | 80 | // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { |
70 | MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { | 81 | MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { |
71 | // confirmButtonText: 'Re-Login', | 82 | // confirmButtonText: 'Re-Login', |
72 | confirmButtonText: '重新登录', | 83 | confirmButtonText: '重新登录', |
73 | // cancelButtonText: 'Cancel', | 84 | // cancelButtonText: 'Cancel', |
74 | cancelButtonText: '取消', | 85 | cancelButtonText: '取消', |
75 | type: 'warning' | 86 | type: 'warning' |
76 | }).then(() => { | 87 | }).then(() => { |
77 | store.dispatch('user/resetToken').then(() => { | 88 | store.dispatch('user/resetToken').then(() => { |
78 | location.reload()// 为了重新实例化vue-router对象 避免bug | 89 | location.reload() // 为了重新实例化vue-router对象 避免bug |
79 | }) | 90 | }) |
80 | }) | 91 | }) |
81 | } | 92 | } |
82 | return Promise.reject(new Error(res.message || 'Error')) | 93 | return Promise.reject(new Error(res.message || 'Error')) |
83 | } else { | 94 | } else { |
84 | return res | 95 | // const token = res.data.token; |
96 | console.log('进入20000号判断-------->', res); | ||
97 | return res; | ||
85 | } | 98 | } |
86 | }, | 99 | }, |
87 | error => { | 100 | error => { |
88 | console.log('err' + error) // for debug | 101 | console.error('===============发生错误!!!!!===============' + error) // for debug |
89 | Message({ | 102 | Message({ |
90 | message: error.message, | 103 | message: error.message, |
91 | type: 'error', | 104 | type: 'error', |
92 | duration: 5 * 1000 | 105 | duration: 5 * 1000 |
93 | }) | 106 | }) |
94 | return Promise.reject(error) | 107 | return Promise.reject(error) |
95 | } | 108 | } |
96 | ) | 109 | ) |
97 | 110 |
src/views/login/index.vue
1 | <template> | 1 | <template> |
2 | <div class="login-container"> | 2 | <div class="login-container"> |
3 | <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> | 3 | <el-form |
4 | 4 | ref="loginForm" | |
5 | :model="loginForm" | ||
6 | :rules="loginRules" | ||
7 | class="login-form" | ||
8 | auto-complete="on" | ||
9 | label-position="left" | ||
10 | > | ||
5 | <div class="title-container"> | 11 | <div class="title-container"> |
6 | <h3 class="title">Login Form</h3> | 12 | <h3 class="title">鱼皮系统</h3> |
7 | </div> | 13 | </div> |
8 | 14 | ||
9 | <el-form-item prop="username"> | 15 | <el-form-item prop="username"> |
10 | <span class="svg-container"> | 16 | <span class="svg-container"> |
11 | <svg-icon icon-class="user" /> | 17 | <svg-icon icon-class="user" /> |
12 | </span> | 18 | </span> |
13 | <el-input | 19 | <el-input |
14 | ref="username" | 20 | ref="username" |
15 | v-model="loginForm.username" | 21 | v-model="loginForm.username" |
16 | placeholder="Username" | 22 | placeholder="Username" |
17 | name="username" | 23 | name="username" |
18 | type="text" | 24 | type="text" |
19 | tabindex="1" | 25 | tabindex="1" |
20 | auto-complete="on" | 26 | auto-complete="on" |
21 | /> | 27 | /> |
22 | </el-form-item> | 28 | </el-form-item> |
23 | 29 | ||
24 | <el-form-item prop="password"> | 30 | <el-form-item prop="password"> |
25 | <span class="svg-container"> | 31 | <span class="svg-container"> |
26 | <svg-icon icon-class="password" /> | 32 | <svg-icon icon-class="password" /> |
27 | </span> | 33 | </span> |
28 | <el-input | 34 | <el-input |
29 | :key="passwordType" | 35 | :key="passwordType" |
30 | ref="password" | 36 | ref="password" |
31 | v-model="loginForm.password" | 37 | v-model="loginForm.password" |
32 | :type="passwordType" | 38 | :type="passwordType" |
33 | placeholder="Password" | 39 | placeholder="Password" |
34 | name="password" | 40 | name="password" |
35 | tabindex="2" | 41 | tabindex="2" |
36 | auto-complete="on" | 42 | auto-complete="on" |
37 | @keyup.enter.native="handleLogin" | 43 | @keyup.enter.native="handleLogin" |
38 | /> | 44 | /> |
39 | <span class="show-pwd" @click="showPwd"> | 45 | <span class="show-pwd" @click="showPwd"> |
40 | <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> | 46 | <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> |
41 | </span> | 47 | </span> |
42 | </el-form-item> | 48 | </el-form-item> |
43 | <!-- <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">reg</el-button> --> | 49 | <!-- <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">reg</el-button> --> |
44 | <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button> | 50 | <el-button |
51 | :loading="loading" | ||
52 | type="primary" | ||
53 | style="width:100%;margin-bottom:30px;" | ||
54 | @click.native.prevent="handleLogin" | ||
55 | >Login</el-button> | ||
45 | 56 | ||
46 | <div class="tips"> | 57 | <div class="tips"> |
47 | <span style="margin-right:20px;">username: admin</span> | 58 | <span style="margin-right:20px;">username: admin</span> |
48 | <span> password: any</span> | 59 | <span>password: any</span> |
49 | </div> | 60 | </div> |
50 | |||
51 | </el-form> | 61 | </el-form> |
52 | </div> | 62 | </div> |
53 | </template> | 63 | </template> |
54 | 64 | ||
55 | <script> | 65 | <script> |
56 | import { validUsername } from '@/utils/validate' | 66 | import { validUsername } from "@/utils/validate"; |
57 | 67 | ||
58 | export default { | 68 | export default { |
59 | name: 'Login', | 69 | name: "Login", |
60 | data() { | 70 | data() { |
61 | const validateUsername = (rule, value, callback) => { | 71 | const validateUsername = (rule, value, callback) => { |
62 | if (!validUsername(value)) { | 72 | if (!validUsername(value)) { |
63 | callback(new Error('Please enter the correct user name')) | 73 | callback(new Error("Please enter the correct user name")); |
64 | } else { | 74 | } else { |
65 | callback() | 75 | callback(); |
66 | } | 76 | } |
67 | } | 77 | }; |
68 | const validatePassword = (rule, value, callback) => { | 78 | const validatePassword = (rule, value, callback) => { |
69 | if (value.length < 6) { | 79 | if (value.length < 6) { |
70 | callback(new Error('The password can not be less than 6 digits')) | 80 | callback(new Error("The password can not be less than 6 digits")); |
71 | } else { | 81 | } else { |
72 | callback() | 82 | callback(); |
73 | } | 83 | } |
74 | } | 84 | }; |
75 | return { | 85 | return { |
76 | loginForm: { | 86 | loginForm: { |
77 | username: 'admin', | 87 | username: "admin", |
78 | password: '111111' | 88 | password: "111111" |
79 | }, | 89 | }, |
80 | loginRules: { | 90 | loginRules: { |
81 | username: [{ required: true, trigger: 'blur', validator: validateUsername }], | 91 | username: [ |
82 | password: [{ required: true, trigger: 'blur', validator: validatePassword }] | 92 | { required: true, trigger: "blur", validator: validateUsername } |
93 | ], | ||
94 | password: [ | ||
95 | { required: true, trigger: "blur", validator: validatePassword } | ||
96 | ] | ||
83 | }, | 97 | }, |
84 | loading: false, | 98 | loading: false, |
85 | passwordType: 'password', | 99 | passwordType: "password", |
86 | redirect: undefined | 100 | redirect: undefined |
87 | } | 101 | }; |
88 | }, | 102 | }, |
89 | watch: { | 103 | watch: { |
90 | $route: { | 104 | $route: { |
91 | handler: function(route) { | 105 | handler: function(route) { |
92 | this.redirect = route.query && route.query.redirect | 106 | this.redirect = route.query && route.query.redirect; |
93 | }, | 107 | }, |
94 | immediate: true | 108 | immediate: true |
95 | } | 109 | } |
96 | }, | 110 | }, |
97 | methods: { | 111 | methods: { |
98 | showPwd() { | 112 | showPwd() { |
99 | if (this.passwordType === 'password') { | 113 | if (this.passwordType === "password") { |
100 | this.passwordType = '' | 114 | this.passwordType = ""; |
101 | } else { | 115 | } else { |
102 | this.passwordType = 'password' | 116 | this.passwordType = "password"; |
103 | } | 117 | } |
104 | this.$nextTick(() => { | 118 | this.$nextTick(() => { |
105 | this.$refs.password.focus() | 119 | this.$refs.password.focus(); |
106 | }) | 120 | }); |
107 | }, | 121 | }, |
108 | handleLogin() { | 122 | handleLogin() { |
109 | this.$refs.loginForm.validate(valid => { | 123 | this.$refs.loginForm.validate(valid => { |
110 | if (valid) { | 124 | if (valid) { |
111 | this.loading = true | 125 | this.loading = true; |
112 | this.$store.dispatch('user/login', this.loginForm).then(() => { | 126 | this.$store |
113 | this.$router.push({ path: this.redirect || '/' }) | 127 | .dispatch("user/login", this.loginForm) |
114 | this.loading = false | 128 | .then(() => { |
115 | }).catch(() => { | 129 | this.$router.push({ path: this.redirect || "/" }); |
116 | this.loading = false | 130 | this.loading = false; |
117 | }) | 131 | console.log('this.redirect', this.$router); |
132 | }) | ||
133 | .catch(res => { | ||
134 | console.log("res error------------>", res); | ||
135 | this.loading = false; | ||
136 | }); | ||
118 | } else { | 137 | } else { |
119 | console.log('error submit!!') | 138 | console.log("error submit!!"); |
120 | return false | 139 | return false; |
121 | } | 140 | } |
122 | }) | 141 | }); |
123 | } | 142 | } |
124 | } | 143 | } |
125 | } | 144 | }; |
126 | </script> | 145 | </script> |
127 | 146 | ||
128 | <style lang="scss"> | 147 | <style lang="scss"> |
129 | /* 修复input 背景不协调 和光标变色 */ | 148 | /* 修复input 背景不协调 和光标变色 */ |
130 | /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ | 149 | /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ |
131 | 150 | ||
132 | $bg:#283443; | 151 | $bg: #283443; |
133 | $light_gray:#fff; | 152 | $light_gray: #fff; |
134 | $cursor: #fff; | 153 | $cursor: #fff; |
135 | 154 | ||
136 | @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { | 155 | @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { |
137 | .login-container .el-input input { | 156 | .login-container .el-input input { |
138 | color: $cursor; | 157 | color: $cursor; |
139 | } | 158 | } |
140 | } | 159 | } |
141 | 160 | ||
142 | /* reset element-ui css */ | 161 | /* reset element-ui css */ |
143 | .login-container { | 162 | .login-container { |
144 | .el-input { | 163 | .el-input { |
145 | display: inline-block; | 164 | display: inline-block; |
146 | height: 47px; | 165 | height: 47px; |
147 | width: 85%; | 166 | width: 85%; |
148 | 167 | ||
149 | input { | 168 | input { |
150 | background: transparent; | 169 | background: transparent; |
151 | border: 0px; | 170 | border: 0px; |
152 | -webkit-appearance: none; | 171 | -webkit-appearance: none; |
153 | border-radius: 0px; | 172 | border-radius: 0px; |
154 | padding: 12px 5px 12px 15px; | 173 | padding: 12px 5px 12px 15px; |
155 | color: $light_gray; | 174 | color: $light_gray; |
156 | height: 47px; | 175 | height: 47px; |
157 | caret-color: $cursor; | 176 | caret-color: $cursor; |
158 | 177 | ||
159 | &:-webkit-autofill { | 178 | &:-webkit-autofill { |
160 | box-shadow: 0 0 0px 1000px $bg inset !important; | 179 | box-shadow: 0 0 0px 1000px $bg inset !important; |
161 | -webkit-text-fill-color: $cursor !important; | 180 | -webkit-text-fill-color: $cursor !important; |
162 | } | 181 | } |
163 | } | 182 | } |
164 | } | 183 | } |
165 | 184 | ||
166 | .el-form-item { | 185 | .el-form-item { |
167 | border: 1px solid rgba(255, 255, 255, 0.1); | 186 | border: 1px solid rgba(255, 255, 255, 0.1); |
168 | background: rgba(0, 0, 0, 0.1); | 187 | background: rgba(0, 0, 0, 0.1); |
169 | border-radius: 5px; | 188 | border-radius: 5px; |
170 | color: #454545; | 189 | color: #454545; |
171 | } | 190 | } |
172 | } | 191 | } |
173 | </style> | 192 | </style> |
174 | 193 | ||
175 | <style lang="scss" scoped> | 194 | <style lang="scss" scoped> |
176 | $bg:#2d3a4b; | 195 | $bg: #2d3a4b; |
177 | $dark_gray:#889aa4; | 196 | $dark_gray: #889aa4; |
178 | $light_gray:#eee; | 197 | $light_gray: #eee; |
179 | 198 | ||
180 | .login-container { | 199 | .login-container { |
181 | min-height: 100%; | 200 | min-height: 100%; |
182 | width: 100%; | 201 | width: 100%; |
183 | background-color: $bg; | 202 | background-color: $bg; |
184 | overflow: hidden; | 203 | overflow: hidden; |
185 | 204 | ||
186 | .login-form { | 205 | .login-form { |
187 | position: relative; | 206 | position: relative; |
188 | width: 520px; | 207 | width: 520px; |
189 | max-width: 100%; | 208 | max-width: 100%; |
190 | padding: 160px 35px 0; | 209 | padding: 160px 35px 0; |
191 | margin: 0 auto; | 210 | margin: 0 auto; |
192 | overflow: hidden; | 211 | overflow: hidden; |
193 | } | 212 | } |
194 | 213 | ||
195 | .tips { | 214 | .tips { |
196 | font-size: 14px; | 215 | font-size: 14px; |
197 | color: #fff; | 216 | color: #fff; |
198 | margin-bottom: 10px; | 217 | margin-bottom: 10px; |
199 | 218 | ||
200 | span { | 219 | span { |
201 | &:first-of-type { | 220 | &:first-of-type { |
202 | margin-right: 16px; | 221 | margin-right: 16px; |
203 | } | 222 | } |
204 | } | 223 | } |
205 | } | 224 | } |
206 | 225 | ||
207 | .svg-container { | 226 | .svg-container { |
208 | padding: 6px 5px 6px 15px; | 227 | padding: 6px 5px 6px 15px; |
209 | color: $dark_gray; | 228 | color: $dark_gray; |
210 | vertical-align: middle; | 229 | vertical-align: middle; |
211 | width: 30px; | 230 | width: 30px; |
212 | display: inline-block; | 231 | display: inline-block; |
213 | } | 232 | } |
214 | 233 | ||
215 | .title-container { | 234 | .title-container { |
216 | position: relative; | 235 | position: relative; |
217 | 236 | ||
218 | .title { | 237 | .title { |
219 | font-size: 26px; | 238 | font-size: 26px; |
220 | color: $light_gray; | 239 | color: $light_gray; |
221 | margin: 0px auto 40px auto; | 240 | margin: 0px auto 40px auto; |
222 | text-align: center; | 241 | text-align: center; |
223 | font-weight: bold; | 242 | font-weight: bold; |
224 | } | 243 | } |
225 | } | 244 | } |
226 | 245 | ||
227 | .show-pwd { | 246 | .show-pwd { |
228 | position: absolute; | 247 | position: absolute; |
229 | right: 10px; | 248 | right: 10px; |
230 | top: 7px; | 249 | top: 7px; |
231 | font-size: 16px; | 250 | font-size: 16px; |
232 | color: $dark_gray; | 251 | color: $dark_gray; |
233 | cursor: pointer; | 252 | cursor: pointer; |
234 | user-select: none; | 253 | user-select: none; |
235 | } | 254 | } |
236 | } | 255 | } |
237 | </style> | 256 | </style> |
vue.config.js
1 | 'use strict' | 1 | 'use strict' |
2 | const path = require('path') | 2 | const path = require('path') |
3 | const defaultSettings = require('./src/settings.js') | 3 | const defaultSettings = require('./src/settings.js') |
4 | 4 | ||
5 | function resolve(dir) { | 5 | function resolve(dir) { |
6 | return path.join(__dirname, dir) | 6 | return path.join(__dirname, dir) |
7 | } | 7 | } |
8 | 8 | ||
9 | const name = defaultSettings.title || 'vue Admin Template' // page title | 9 | const name = defaultSettings.title || 'vue Admin Template' // page title |
10 | 10 | ||
11 | // If your port is set to 80, | 11 | // If your port is set to 80, |
12 | // use administrator privileges to execute the command line. | 12 | // use administrator privileges to execute the command line. |
13 | // For example, Mac: sudo npm run | 13 | // For example, Mac: sudo npm run |
14 | // You can change the port by the following methods: | 14 | // You can change the port by the following methods: |
15 | // port = 9528 npm run dev OR npm run dev --port = 9528 | 15 | // port = 9528 npm run dev OR npm run dev --port = 9528 |
16 | const port = process.env.port || process.env.npm_config_port || 9528 // dev port | 16 | const port = process.env.port || process.env.npm_config_port || 9528 // dev port |
17 | 17 | ||
18 | // All configuration item explanations can be find in https://cli.vuejs.org/config/ | 18 | // All configuration item explanations can be find in https://cli.vuejs.org/config/ |
19 | module.exports = { | 19 | module.exports = { |
20 | /** | 20 | /** |
21 | * You will need to set publicPath if you plan to deploy your site under a sub path, | 21 | * You will need to set publicPath if you plan to deploy your site under a sub path, |
22 | * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, | 22 | * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, |
23 | * then publicPath should be set to "/bar/". | 23 | * then publicPath should be set to "/bar/". |
24 | * In most cases please use '/' !!! | 24 | * In most cases please use '/' !!! |
25 | * Detail: https://cli.vuejs.org/config/#publicpath | 25 | * Detail: https://cli.vuejs.org/config/#publicpath |
26 | */ | 26 | */ |
27 | publicPath: '/', | 27 | publicPath: '/', |
28 | outputDir: 'dist', | 28 | outputDir: 'dist', |
29 | assetsDir: 'static', | 29 | assetsDir: 'static', |
30 | lintOnSave: process.env.NODE_ENV === 'development', | 30 | lintOnSave: process.env.NODE_ENV === 'development', |
31 | productionSourceMap: false, | 31 | productionSourceMap: false, |
32 | devServer: { | 32 | devServer: { |
33 | port: port, | 33 | port: port, |
34 | open: true, | 34 | open: true, |
35 | overlay: { | 35 | overlay: { |
36 | warnings: false, | 36 | warnings: false, |
37 | errors: true | 37 | errors: true |
38 | }, | 38 | }, |
39 | before: require('./mock/mock-server.js') | 39 | before: require('./mock/mock-server.js') |
40 | }, | 40 | }, |
41 | configureWebpack: { | 41 | configureWebpack: { |
42 | // provide the app's title in webpack's name field, so that | 42 | // provide the app's title in webpack's name field, so that |
43 | // it can be accessed in index.html to inject the correct title. | 43 | // it can be accessed in index.html to inject the correct title. |
44 | name: name, | 44 | name: name, |
45 | resolve: { | 45 | resolve: { |
46 | alias: { | 46 | alias: { |
47 | '@': resolve('src') | 47 | '@': resolve('src') |
48 | } | 48 | } |
49 | } | 49 | } |
50 | }, | 50 | }, |
51 | chainWebpack(config) { | 51 | chainWebpack(config) { |
52 | config.plugins.delete('preload') // TODO: need test | 52 | config.plugins.delete('preload') // TODO: need test |
53 | config.plugins.delete('prefetch') // TODO: need test | 53 | config.plugins.delete('prefetch') // TODO: need test |
54 | 54 | ||
55 | // set svg-sprite-loader | 55 | // set svg-sprite-loader |
56 | config.module | 56 | config.module |
57 | .rule('svg') | 57 | .rule('svg') |
58 | .exclude.add(resolve('src/icons')) | 58 | .exclude.add(resolve('src/icons')) |
59 | .end() | 59 | .end() |
60 | config.module | 60 | config.module |
61 | .rule('icons') | 61 | .rule('icons') |
62 | .test(/\.svg$/) | 62 | .test(/\.svg$/) |
63 | .include.add(resolve('src/icons')) | 63 | .include.add(resolve('src/icons')) |
64 | .end() | 64 | .end() |
65 | .use('svg-sprite-loader') | 65 | .use('svg-sprite-loader') |
66 | .loader('svg-sprite-loader') | 66 | .loader('svg-sprite-loader') |
67 | .options({ | 67 | .options({ |
68 | symbolId: 'icon-[name]' | 68 | symbolId: 'icon-[name]' |
69 | }) | 69 | }) |
70 | .end() | 70 | .end() |
71 | 71 | ||
72 | // set preserveWhitespace | 72 | // set preserveWhitespace |
73 | config.module | 73 | config.module |
74 | .rule('vue') | 74 | .rule('vue') |
75 | .use('vue-loader') | 75 | .use('vue-loader') |
76 | .loader('vue-loader') | 76 | .loader('vue-loader') |
77 | .tap(options => { | 77 | .tap(options => { |
78 | options.compilerOptions.preserveWhitespace = true | 78 | options.compilerOptions.preserveWhitespace = true |
79 | return options | 79 | return options |
80 | }) | 80 | }) |
81 | .end() | 81 | .end() |
82 | 82 | ||
83 | config | 83 | config |
84 | // https://webpack.js.org/configuration/devtool/#development | 84 | // https://webpack.js.org/configuration/devtool/#development |
85 | .when(process.env.NODE_ENV === 'development', | 85 | .when(process.env.NODE_ENV === 'development', |
86 | config => config.devtool('cheap-source-map') | 86 | config => config.devtool('cheap-source-map') |
87 | ) | 87 | ) |
88 | 88 | ||
89 | config | 89 | config |
90 | .when(process.env.NODE_ENV !== 'development', | 90 | .when(process.env.NODE_ENV !== 'development', |
91 | config => { | 91 | config => { |
92 | config | 92 | config |
93 | .plugin('ScriptExtHtmlWebpackPlugin') | 93 | .plugin('ScriptExtHtmlWebpackPlugin') |
94 | .after('html') | 94 | .after('html') |
95 | .use('script-ext-html-webpack-plugin', [{ | 95 | .use('script-ext-html-webpack-plugin', [{ |
96 | // `runtime` must same as runtimeChunk name. default is `runtime` | 96 | // `runtime` must same as runtimeChunk name. default is `runtime` |
97 | inline: /runtime\..*\.js$/ | 97 | inline: /runtime\..*\.js$/ |
98 | }]) | 98 | }]) |
99 | .end() | 99 | .end() |
100 | config | 100 | config |
101 | .optimization.splitChunks({ | 101 | .optimization.splitChunks({ |
102 | chunks: 'all', | 102 | chunks: 'all', |
103 | cacheGroups: { | 103 | cacheGroups: { |
104 | libs: { | 104 | libs: { |
105 | name: 'chunk-libs', | 105 | name: 'chunk-libs', |
106 | test: /[\\/]node_modules[\\/]/, | 106 | test: /[\\/]node_modules[\\/]/, |
107 | priority: 10, | 107 | priority: 10, |
108 | chunks: 'initial' // only package third parties that are initially dependent | 108 | chunks: 'initial' // only package third parties that are initially dependent |
109 | }, | 109 | }, |
110 | elementUI: { | 110 | elementUI: { |
111 | name: 'chunk-elementUI', // split elementUI into a single package | 111 | name: 'chunk-elementUI', // split elementUI into a single package |
112 | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app | 112 | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app |
113 | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm | 113 | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm |
114 | }, | 114 | }, |
115 | commons: { | 115 | commons: { |
116 | name: 'chunk-commons', | 116 | name: 'chunk-commons', |
117 | test: resolve('src/components'), // can customize your rules | 117 | test: resolve('src/components'), // can customize your rules |
118 | minChunks: 3, // minimum common number | 118 | minChunks: 3, // minimum common number |
119 | priority: 5, | 119 | priority: 5, |
120 | reuseExistingChunk: true | 120 | reuseExistingChunk: true |
121 | } | 121 | } |
122 | } | 122 | } |
123 | }) | 123 | }) |
124 | config.optimization.runtimeChunk('single') | 124 | config.optimization.runtimeChunk('single') |
125 | } | 125 | } |
126 | ) | 126 | ) |
127 | } | 127 | } |
128 | } | 128 | } |
129 | 129 |