tianyunperfect há 2 anos atrás
pai
commit
d775faf8ba
78 ficheiros alterados com 1372 adições e 1351 exclusões
  1. 2 1
      .gitignore
  2. 0 21
      element-demo/LICENSE
  3. 5 18
      element-demo/README-zh.md
  4. 9 5
      element-demo/README.md
  5. 11 11
      element-demo/babel.config.js
  6. 21 21
      element-demo/build/index.js
  7. 22 22
      element-demo/jest.config.js
  8. 7 2
      element-demo/jsconfig.json
  9. 38 38
      element-demo/mock/index.js
  10. 55 55
      element-demo/mock/mock-server.js
  11. 20 20
      element-demo/mock/table.js
  12. 59 59
      element-demo/mock/table1.js
  13. 67 68
      element-demo/mock/user.js
  14. 15 15
      element-demo/mock/utils.js
  15. 2 5
      element-demo/package.json
  16. 4 4
      element-demo/postcss.config.js
  17. 10 9
      element-demo/public/index.html
  18. 1 1
      element-demo/src/App.vue
  19. 5 5
      element-demo/src/api/table.js
  20. 20 20
      element-demo/src/api/table1.js
  21. 14 14
      element-demo/src/api/user.js
  22. 6 4
      element-demo/src/components/Breadcrumb/index.vue
  23. 8 7
      element-demo/src/components/Hamburger/index.vue
  24. 4 4
      element-demo/src/components/SvgIcon/index.vue
  25. 0 0
      element-demo/src/icons/svg/dashboard.svg
  26. 3 1
      element-demo/src/icons/svg/example.svg
  27. 6 1
      element-demo/src/icons/svg/eye-open.svg
  28. 3 1
      element-demo/src/icons/svg/eye.svg
  29. 0 0
      element-demo/src/icons/svg/form.svg
  30. 5 1
      element-demo/src/icons/svg/link.svg
  31. 3 1
      element-demo/src/icons/svg/nested.svg
  32. 3 1
      element-demo/src/icons/svg/password.svg
  33. 4 1
      element-demo/src/icons/svg/table.svg
  34. 3 1
      element-demo/src/icons/svg/tree.svg
  35. 4 1
      element-demo/src/icons/svg/user.svg
  36. 4 4
      element-demo/src/icons/svgo.yml
  37. 3 2
      element-demo/src/layout/components/AppMain.vue
  38. 5 5
      element-demo/src/layout/components/Navbar.vue
  39. 22 22
      element-demo/src/layout/components/Sidebar/FixiOSBug.js
  40. 2 2
      element-demo/src/layout/components/Sidebar/Item.vue
  41. 2 2
      element-demo/src/layout/components/Sidebar/Link.vue
  42. 13 12
      element-demo/src/layout/components/Sidebar/SidebarItem.vue
  43. 12 12
      element-demo/src/layout/components/Sidebar/index.vue
  44. 3 3
      element-demo/src/layout/components/index.js
  45. 40 38
      element-demo/src/layout/index.vue
  46. 34 34
      element-demo/src/layout/mixin/ResizeHandler.js
  47. 7 7
      element-demo/src/main.js
  48. 44 44
      element-demo/src/permission.js
  49. 77 77
      element-demo/src/router/index.js
  50. 11 11
      element-demo/src/settings.js
  51. 3 3
      element-demo/src/store/index.js
  52. 23 23
      element-demo/src/store/modules/app.js
  53. 11 11
      element-demo/src/store/modules/settings.js
  54. 58 58
      element-demo/src/store/modules/user.js
  55. 9 8
      element-demo/src/styles/sidebar.scss
  56. 7 7
      element-demo/src/styles/variables.scss
  57. 3 3
      element-demo/src/utils/auth.js
  58. 4 4
      element-demo/src/utils/get-page-title.js
  59. 86 84
      element-demo/src/utils/index.js
  60. 62 62
      element-demo/src/utils/request.js
  61. 3 3
      element-demo/src/utils/validate.js
  62. 19 3
      element-demo/src/views/404.vue
  63. 1 0
      element-demo/src/views/dashboard/index.vue
  64. 14 14
      element-demo/src/views/form/index.vue
  65. 8 8
      element-demo/src/views/table/index.vue
  66. 44 43
      element-demo/src/views/table1/index.vue
  67. 3 3
      element-demo/tests/unit/.eslintrc.js
  68. 80 80
      element-demo/tests/unit/components/Breadcrumb.spec.js
  69. 16 15
      element-demo/tests/unit/components/Hamburger.spec.js
  70. 18 17
      element-demo/tests/unit/components/SvgIcon.spec.js
  71. 26 26
      element-demo/tests/unit/utils/formatTime.spec.js
  72. 11 10
      element-demo/tests/unit/utils/param2Obj.spec.js
  73. 31 31
      element-demo/tests/unit/utils/parseTime.spec.js
  74. 14 14
      element-demo/tests/unit/utils/validate.spec.js
  75. 0 0
      element-demo/tmp.js
  76. 100 99
      element-demo/vue.config.js
  77. 0 9
      layui-demo/layui-demo.iml
  78. 0 0
      layui-demo/tmp.js

+ 2 - 1
.gitignore

@@ -1,3 +1,4 @@
 node_modules
 package-lock.json
-.idea
+.idea
+dist

+ 0 - 21
element-demo/LICENSE

@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017-present PanJiaChen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.

+ 5 - 18
element-demo/README-zh.md

@@ -6,11 +6,14 @@
 
 [国内访问](https://panjiachen.gitee.io/vue-admin-template)
 
-目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`。
+目前版本为 `v4.0+` 基于 `vue-cli`
+进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0)
+,它不依赖 `vue-cli`。
 
 ## Extra
 
-如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+如果你想要根据用户角色来动态生成侧边栏和
+router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
 
 ## 相关项目
 
@@ -79,22 +82,6 @@ npm run lint -- --fix
 
 更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
 
-## 购买贴纸
-
-你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。
-
-## Demo
-
-![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
-
-## Browsers support
-
-Modern browsers and Internet Explorer 10+.
-
-| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
-| --------- | --------- | --------- | --------- |
-| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
-
 ## License
 
 [MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.

+ 9 - 5
element-demo/README.md

@@ -6,8 +6,8 @@ English | [简体中文](./README-zh.md)
 
 **Live demo:** http://panjiachen.github.io/vue-admin-template
 
-
-**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
+**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch
+to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
 
 ## Build Setup
 
@@ -53,7 +53,8 @@ npm run lint
 npm run lint -- --fix
 ```
 
-Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
+Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more
+information
 
 ## Demo
 
@@ -61,9 +62,12 @@ Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/gui
 
 ## Extra
 
-If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+If you want router permission && generate menu by user roles , you can use this
+branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
 
-For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
+For `typescript` version, you can
+use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (
+Credits: [@Armour](https://github.com/Armour))
 
 ## Related Project
 

+ 11 - 11
element-demo/babel.config.js

@@ -1,14 +1,14 @@
 module.exports = {
-  presets: [
-    // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
-    '@vue/cli-plugin-babel/preset'
-  ],
-  'env': {
-    'development': {
-      // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
-      // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
-      // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
-      'plugins': ['dynamic-import-node']
+    presets: [
+        // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
+        '@vue/cli-plugin-babel/preset'
+    ],
+    'env': {
+        'development': {
+            // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
+            // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
+            // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
+            'plugins': ['dynamic-import-node']
+        }
     }
-  }
 }

+ 21 - 21
element-demo/build/index.js

@@ -1,35 +1,35 @@
-const { run } = require('runjs')
+const {run} = require('runjs')
 const chalk = require('chalk')
 const config = require('../vue.config.js')
 const rawArgv = process.argv.slice(2)
 const args = rawArgv.join(' ')
 
 if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
-  const report = rawArgv.includes('--report')
+    const report = rawArgv.includes('--report')
 
-  run(`vue-cli-service build ${args}`)
+    run(`vue-cli-service build ${args}`)
 
-  const port = 9526
-  const publicPath = config.publicPath
+    const port = 9526
+    const publicPath = config.publicPath
 
-  var connect = require('connect')
-  var serveStatic = require('serve-static')
-  const app = connect()
+    var connect = require('connect')
+    var serveStatic = require('serve-static')
+    const app = connect()
 
-  app.use(
-    publicPath,
-    serveStatic('./dist', {
-      index: ['index.html', '/']
-    })
-  )
+    app.use(
+        publicPath,
+        serveStatic('./dist', {
+            index: ['index.html', '/']
+        })
+    )
 
-  app.listen(port, function () {
-    console.log(chalk.green(`> Preview at  http://localhost:${port}${publicPath}`))
-    if (report) {
-      console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}report.html`))
-    }
+    app.listen(port, function () {
+        console.log(chalk.green(`> Preview at  http://localhost:${port}${publicPath}`))
+        if (report) {
+            console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}report.html`))
+        }
 
-  })
+    })
 } else {
-  run(`vue-cli-service build ${args}`)
+    run(`vue-cli-service build ${args}`)
 }

+ 22 - 22
element-demo/jest.config.js

@@ -1,24 +1,24 @@
 module.exports = {
-  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
-  transform: {
-    '^.+\\.vue$': 'vue-jest',
-    '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
-      'jest-transform-stub',
-    '^.+\\.jsx?$': 'babel-jest'
-  },
-  moduleNameMapper: {
-    '^@/(.*)$': '<rootDir>/src/$1'
-  },
-  snapshotSerializers: ['jest-serializer-vue'],
-  testMatch: [
-    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
-  ],
-  collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
-  coverageDirectory: '<rootDir>/tests/unit/coverage',
-  // 'collectCoverage': true,
-  'coverageReporters': [
-    'lcov',
-    'text-summary'
-  ],
-  testURL: 'http://localhost/'
+    moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
+    transform: {
+        '^.+\\.vue$': 'vue-jest',
+        '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
+            'jest-transform-stub',
+        '^.+\\.jsx?$': 'babel-jest'
+    },
+    moduleNameMapper: {
+        '^@/(.*)$': '<rootDir>/src/$1'
+    },
+    snapshotSerializers: ['jest-serializer-vue'],
+    testMatch: [
+        '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
+    ],
+    collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
+    coverageDirectory: '<rootDir>/tests/unit/coverage',
+    // 'collectCoverage': true,
+    'coverageReporters': [
+        'lcov',
+        'text-summary'
+    ],
+    testURL: 'http://localhost/'
 }

+ 7 - 2
element-demo/jsconfig.json

@@ -2,8 +2,13 @@
   "compilerOptions": {
     "baseUrl": "./",
     "paths": {
-        "@/*": ["src/*"]
+      "@/*": [
+        "src/*"
+      ]
     }
   },
-  "exclude": ["node_modules", "dist"]
+  "exclude": [
+    "node_modules",
+    "dist"
+  ]
 }

+ 38 - 38
element-demo/mock/index.js

@@ -1,59 +1,59 @@
 const Mock = require('mockjs')
-const { param2Obj } = require('./utils')
+const {param2Obj} = require('./utils')
 
 const user = require('./user')
 const table = require('./table')
 const table1 = require('./table1')
 
 const mocks = [
-  ...user,
-  ...table,
-  ...table1
+    ...user,
+    ...table,
+    ...table1
 ]
 
 // for front mock
 // please use it cautiously, it will redefine XMLHttpRequest,
 // which will cause many of your third-party libraries to be invalidated(like progress event).
 function mockXHR() {
-  // mock patch
-  // https://github.com/nuysoft/Mock/issues/300
-  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
-  Mock.XHR.prototype.send = function() {
-    if (this.custom.xhr) {
-      this.custom.xhr.withCredentials = this.withCredentials || false
-
-      if (this.responseType) {
-        this.custom.xhr.responseType = this.responseType
-      }
+    // mock patch
+    // https://github.com/nuysoft/Mock/issues/300
+    Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
+    Mock.XHR.prototype.send = function () {
+        if (this.custom.xhr) {
+            this.custom.xhr.withCredentials = this.withCredentials || false
+
+            if (this.responseType) {
+                this.custom.xhr.responseType = this.responseType
+            }
+        }
+        this.proxy_send(...arguments)
     }
-    this.proxy_send(...arguments)
-  }
-
-  function XHR2ExpressReqWrap(respond) {
-    return function(options) {
-      let result = null
-      if (respond instanceof Function) {
-        const { body, type, url } = options
-        // https://expressjs.com/en/4x/api.html#req
-        result = respond({
-          method: type,
-          body: JSON.parse(body),
-          query: param2Obj(url)
-        })
-      } else {
-        result = respond
-      }
-      return Mock.mock(result)
+
+    function XHR2ExpressReqWrap(respond) {
+        return function (options) {
+            let result = null
+            if (respond instanceof Function) {
+                const {body, type, url} = options
+                // https://expressjs.com/en/4x/api.html#req
+                result = respond({
+                    method: type,
+                    body: JSON.parse(body),
+                    query: param2Obj(url)
+                })
+            } else {
+                result = respond
+            }
+            return Mock.mock(result)
+        }
     }
-  }
 
-  for (const i of mocks) {
-    Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
-  }
+    for (const i of mocks) {
+        Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
+    }
 }
 
 module.exports = {
-  mocks,
-  mockXHR
+    mocks,
+    mockXHR
 }
 

+ 55 - 55
element-demo/mock/mock-server.js

@@ -7,75 +7,75 @@ const Mock = require('mockjs')
 const mockDir = path.join(process.cwd(), 'mock')
 
 function registerRoutes(app) {
-  let mockLastIndex
-  const { mocks } = require('./index.js')
-  const mocksForServer = mocks.map(route => {
-    return responseFake(route.url, route.type, route.response)
-  })
-  for (const mock of mocksForServer) {
-    app[mock.type](mock.url, mock.response)
-    mockLastIndex = app._router.stack.length
-  }
-  const mockRoutesLength = Object.keys(mocksForServer).length
-  return {
-    mockRoutesLength: mockRoutesLength,
-    mockStartIndex: mockLastIndex - mockRoutesLength
-  }
+    let mockLastIndex
+    const {mocks} = require('./index.js')
+    const mocksForServer = mocks.map(route => {
+        return responseFake(route.url, route.type, route.response)
+    })
+    for (const mock of mocksForServer) {
+        app[mock.type](mock.url, mock.response)
+        mockLastIndex = app._router.stack.length
+    }
+    const mockRoutesLength = Object.keys(mocksForServer).length
+    return {
+        mockRoutesLength: mockRoutesLength,
+        mockStartIndex: mockLastIndex - mockRoutesLength
+    }
 }
 
 function unregisterRoutes() {
-  Object.keys(require.cache).forEach(i => {
-    if (i.includes(mockDir)) {
-      delete require.cache[require.resolve(i)]
-    }
-  })
+    Object.keys(require.cache).forEach(i => {
+        if (i.includes(mockDir)) {
+            delete require.cache[require.resolve(i)]
+        }
+    })
 }
 
 // for mock server
 const responseFake = (url, type, respond) => {
-  return {
-    url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
-    type: type || 'get',
-    response(req, res) {
-      console.log('request invoke:' + req.path)
-      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
+    return {
+        url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
+        type: type || 'get',
+        response(req, res) {
+            console.log('request invoke:' + req.path)
+            res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
+        }
     }
-  }
 }
 
 module.exports = app => {
-  // parse app.body
-  // https://expressjs.com/en/4x/api.html#req.body
-  app.use(bodyParser.json())
-  app.use(bodyParser.urlencoded({
-    extended: true
-  }))
+    // parse app.body
+    // https://expressjs.com/en/4x/api.html#req.body
+    app.use(bodyParser.json())
+    app.use(bodyParser.urlencoded({
+        extended: true
+    }))
 
-  const mockRoutes = registerRoutes(app)
-  var mockRoutesLength = mockRoutes.mockRoutesLength
-  var mockStartIndex = mockRoutes.mockStartIndex
+    const mockRoutes = registerRoutes(app)
+    var mockRoutesLength = mockRoutes.mockRoutesLength
+    var mockStartIndex = mockRoutes.mockStartIndex
 
-  // watch files, hot reload mock server
-  chokidar.watch(mockDir, {
-    ignored: /mock-server/,
-    ignoreInitial: true
-  }).on('all', (event, path) => {
-    if (event === 'change' || event === 'add') {
-      try {
-        // remove mock routes stack
-        app._router.stack.splice(mockStartIndex, mockRoutesLength)
+    // watch files, hot reload mock server
+    chokidar.watch(mockDir, {
+        ignored: /mock-server/,
+        ignoreInitial: true
+    }).on('all', (event, path) => {
+        if (event === 'change' || event === 'add') {
+            try {
+                // remove mock routes stack
+                app._router.stack.splice(mockStartIndex, mockRoutesLength)
 
-        // clear routes cache
-        unregisterRoutes()
+                // clear routes cache
+                unregisterRoutes()
 
-        const mockRoutes = registerRoutes(app)
-        mockRoutesLength = mockRoutes.mockRoutesLength
-        mockStartIndex = mockRoutes.mockStartIndex
+                const mockRoutes = registerRoutes(app)
+                mockRoutesLength = mockRoutes.mockRoutesLength
+                mockStartIndex = mockRoutes.mockStartIndex
 
-        console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
-      } catch (error) {
-        console.log(chalk.redBright(error))
-      }
-    }
-  })
+                console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
+            } catch (error) {
+                console.log(chalk.redBright(error))
+            }
+        }
+    })
 }

+ 20 - 20
element-demo/mock/table.js

@@ -1,29 +1,29 @@
 const Mock = require('mockjs')
 
 const data = Mock.mock({
-  'items|30': [{
-    id: '@id',
-    title: '@sentence(10, 20)',
-    'status|1': ['published', 'draft', 'deleted'],
-    author: 'name',
-    display_time: '@datetime',
-    pageviews: '@integer(300, 5000)'
-  }]
+    'items|30': [{
+        id: '@id',
+        title: '@sentence(10, 20)',
+        'status|1': ['published', 'draft', 'deleted'],
+        author: 'name',
+        display_time: '@datetime',
+        pageviews: '@integer(300, 5000)'
+    }]
 })
 
 module.exports = [
-  {
-    url: '/vue-admin-template/table/list',
-    type: 'get',
-    response: config => {
-      const items = data.items
-      return {
-        code: 20000,
-        data: {
-          total: items.length,
-          items: items
+    {
+        url: '/vue-admin-template/table/list',
+        type: 'get',
+        response: config => {
+            const items = data.items
+            return {
+                code: 20000,
+                data: {
+                    total: items.length,
+                    items: items
+                }
+            }
         }
-      }
     }
-  }
 ]

+ 59 - 59
element-demo/mock/table1.js

@@ -1,71 +1,71 @@
 const Mock = require('mockjs')
 
 module.exports = [
-  {
-    url: '/article/list',
-    type: 'get',
-    response: config => {
-      console.log(config.query)
-      console.log(config.body)
+    {
+        url: '/article/list',
+        type: 'get',
+        response: config => {
+            console.log(config.query)
+            console.log(config.body)
 
-      const data = Mock.mock({
-        code: 20000,
-        flag: true,
-        data: {
-          'total|100-200': 1,
-          'list|10': [{
-            'id|+1': 1,
-            name: '@name',
-            email: '@email',
-            date: '@date'
-          }]
+            const data = Mock.mock({
+                code: 20000,
+                flag: true,
+                data: {
+                    'total|100-200': 1,
+                    'list|10': [{
+                        'id|+1': 1,
+                        name: '@name',
+                        email: '@email',
+                        date: '@date'
+                    }]
+                }
+            })
+
+            return data
         }
-      })
+    },
 
-      return data
-    }
-  },
+    {
+        url: '/article/detail',
+        type: 'get',
+        response: config => {
+            const detail = Mock.mock({
+                code: 20000,
+                flag: true,
+                data: {
+                    'id|1-19': 1,
+                    name: '@name',
+                    email: '@email'
+                }
 
-  {
-    url: '/article/detail',
-    type: 'get',
-    response: config => {
-      const detail = Mock.mock({
-        code: 20000,
-        flag: true,
-        data: {
-          'id|1-19': 1,
-          name: '@name',
-          email: '@email'
+            })
+            return detail
         }
+    },
 
-      })
-      return detail
-    }
-  },
-
-  {
-    url: '/article/save',
-    type: 'post',
-    response: x => {
-      console.log(x.body)
-      return {
-        code: 20000,
-        flag: true,
-        data: 'success'
-      }
-    }
-  },
+    {
+        url: '/article/save',
+        type: 'post',
+        response: x => {
+            console.log(x.body)
+            return {
+                code: 20000,
+                flag: true,
+                data: 'success'
+            }
+        }
+    },
 
-  {
-    url: '/article/deleteOne',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        flag: true,
-        data: 'success'
-      }
+    {
+        url: '/article/deleteOne',
+        type: 'post',
+        response: _ => {
+            return {
+                code: 20000,
+                flag: true,
+                data: 'success'
+            }
+        }
     }
-  }
 ]

+ 67 - 68
element-demo/mock/user.js

@@ -1,84 +1,83 @@
-
 const tokens = {
-  admin: {
-    token: 'admin-token'
-  },
-  editor: {
-    token: 'editor-token'
-  }
+    admin: {
+        token: 'admin-token'
+    },
+    editor: {
+        token: 'editor-token'
+    }
 }
 
 const users = {
-  'admin-token': {
-    roles: ['admin'],
-    introduction: 'I am a super administrator',
-    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
-    name: 'Super Admin'
-  },
-  'editor-token': {
-    roles: ['editor'],
-    introduction: 'I am an editor',
-    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
-    name: 'Normal Editor'
-  }
+    'admin-token': {
+        roles: ['admin'],
+        introduction: 'I am a super administrator',
+        avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+        name: 'Super Admin'
+    },
+    'editor-token': {
+        roles: ['editor'],
+        introduction: 'I am an editor',
+        avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+        name: 'Normal Editor'
+    }
 }
 
 module.exports = [
-  // user login
-  {
-    url: '/vue-admin-template/user/login',
-    type: 'post',
-    response: config => {
-      const { username } = config.body
-      const token = tokens[username]
+    // user login
+    {
+        url: '/vue-admin-template/user/login',
+        type: 'post',
+        response: config => {
+            const {username} = config.body
+            const token = tokens[username]
+
+            // mock error
+            if (!token) {
+                return {
+                    code: 60204,
+                    message: 'Account and password are incorrect.'
+                }
+            }
 
-      // mock error
-      if (!token) {
-        return {
-          code: 60204,
-          message: 'Account and password are incorrect.'
+            return {
+                code: 20000,
+                data: token
+            }
         }
-      }
+    },
 
-      return {
-        code: 20000,
-        data: token
-      }
-    }
-  },
+    // get user info
+    {
+        url: '/vue-admin-template/user/info\.*',
+        type: 'get',
+        response: config => {
+            const {token} = config.query
+            const info = users[token]
 
-  // get user info
-  {
-    url: '/vue-admin-template/user/info\.*',
-    type: 'get',
-    response: config => {
-      const { token } = config.query
-      const info = users[token]
+            // mock error
+            if (!info) {
+                return {
+                    code: 50008,
+                    message: 'Login failed, unable to get user details.'
+                }
+            }
 
-      // mock error
-      if (!info) {
-        return {
-          code: 50008,
-          message: 'Login failed, unable to get user details.'
+            return {
+                code: 20000,
+                data: info
+            }
         }
-      }
-
-      return {
-        code: 20000,
-        data: info
-      }
-    }
-  },
+    },
 
-  // user logout
-  {
-    url: '/vue-admin-template/user/logout',
-    type: 'post',
-    response: _ => {
-      return {
-        code: 20000,
-        data: 'success'
-      }
+    // user logout
+    {
+        url: '/vue-admin-template/user/logout',
+        type: 'post',
+        response: _ => {
+            return {
+                code: 20000,
+                data: 'success'
+            }
+        }
     }
-  }
 ]

+ 15 - 15
element-demo/mock/utils.js

@@ -3,23 +3,23 @@
  * @returns {Object}
  */
 function param2Obj(url) {
-  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
-  if (!search) {
-    return {}
-  }
-  const obj = {}
-  const searchArr = search.split('&')
-  searchArr.forEach(v => {
-    const index = v.indexOf('=')
-    if (index !== -1) {
-      const name = v.substring(0, index)
-      const val = v.substring(index + 1, v.length)
-      obj[name] = val
+    const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+    if (!search) {
+        return {}
     }
-  })
-  return obj
+    const obj = {}
+    const searchArr = search.split('&')
+    searchArr.forEach(v => {
+        const index = v.indexOf('=')
+        if (index !== -1) {
+            const name = v.substring(0, index)
+            const val = v.substring(index + 1, v.length)
+            obj[name] = val
+        }
+    })
+    return obj
 }
 
 module.exports = {
-  param2Obj
+    param2Obj
 }

+ 2 - 5
element-demo/package.json

@@ -4,12 +4,9 @@
   "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
   "author": "Pan <panfree23@gmail.com>",
   "scripts": {
-    "dev": "vue-cli-service serve",
-    "build:prod": "vue-cli-service build",
-    "build:stage": "vue-cli-service build --mode staging",
-    "preview": "node build/index.js --preview",
+    "dev": "NODE_ENV=development && vue-cli-service serve",
+    "build": "vue-cli-service build",
     "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
-    "lint": "eslint --ext .js,.vue src",
     "test:unit": "jest --clearCache && vue-cli-service test:unit",
     "test:ci": "npm run lint && npm run test:unit"
   },

+ 4 - 4
element-demo/postcss.config.js

@@ -1,8 +1,8 @@
 // https://github.com/michael-ciniawsky/postcss-load-config
 
 module.exports = {
-  'plugins': {
-    // to edit target browsers: use "browserslist" field in package.json
-    'autoprefixer': {}
-  }
+    'plugins': {
+        // to edit target browsers: use "browserslist" field in package.json
+        'autoprefixer': {}
+    }
 }

+ 10 - 9
element-demo/public/index.html

@@ -1,17 +1,18 @@
 <!DOCTYPE html>
 <html>
-  <head>
+<head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= webpackConfig.name %></title>
-  </head>
-  <body>
-    <noscript>
-      <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
-    </noscript>
-    <div id="app"></div>
-    <!-- built files will be auto injected -->
-  </body>
+</head>
+<body>
+<noscript>
+    <strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it
+        to continue.</strong>
+</noscript>
+<div id="app"></div>
+<!-- built files will be auto injected -->
+</body>
 </html>

+ 1 - 1
element-demo/src/App.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="app">
-    <router-view />
+    <router-view/>
   </div>
 </template>
 

+ 5 - 5
element-demo/src/api/table.js

@@ -1,9 +1,9 @@
 import request from '@/utils/request'
 
 export function getList(params) {
-  return request({
-    url: '/vue-admin-template/table/list',
-    method: 'get',
-    params
-  })
+    return request({
+        url: '/vue-admin-template/table/list',
+        method: 'get',
+        params
+    })
 }

+ 20 - 20
element-demo/src/api/table1.js

@@ -1,34 +1,34 @@
 import request from '@/utils/request'
 
 export function fetchList(query) {
-  return request({
-    url: '/article/list',
-    method: 'get',
-    params: query
-  })
+    return request({
+        url: '/article/list',
+        method: 'get',
+        params: query
+    })
 }
 
 export function fetchOne(id) {
-  return request({
-    url: '/article/detail',
-    method: 'get',
-    params: { id }
-  })
+    return request({
+        url: '/article/detail',
+        method: 'get',
+        params: {id}
+    })
 }
 
 // create Or update
 export function saveOne(data) {
-  return request({
-    url: '/article/save',
-    method: 'post',
-    data
-  })
+    return request({
+        url: '/article/save',
+        method: 'post',
+        data
+    })
 }
 
 export function deleteOne(id) {
-  return request({
-    url: '/article/delete',
-    method: 'post',
-    params: { id }
-  })
+    return request({
+        url: '/article/delete',
+        method: 'post',
+        params: {id}
+    })
 }

+ 14 - 14
element-demo/src/api/user.js

@@ -1,24 +1,24 @@
 import request from '@/utils/request'
 
 export function login(data) {
-  return request({
-    url: '/vue-admin-template/user/login',
-    method: 'post',
-    data
-  })
+    return request({
+        url: '/vue-admin-template/user/login',
+        method: 'post',
+        data
+    })
 }
 
 export function getInfo(token) {
-  return request({
-    url: '/vue-admin-template/user/info',
-    method: 'get',
-    params: { token }
-  })
+    return request({
+        url: '/vue-admin-template/user/info',
+        method: 'get',
+        params: {token}
+    })
 }
 
 export function logout() {
-  return request({
-    url: '/vue-admin-template/user/logout',
-    method: 'post'
-  })
+    return request({
+        url: '/vue-admin-template/user/logout',
+        method: 'post'
+    })
 }

+ 6 - 4
element-demo/src/components/Breadcrumb/index.vue

@@ -2,7 +2,9 @@
   <el-breadcrumb class="app-breadcrumb" separator="/">
     <transition-group name="breadcrumb">
       <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
-        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
+        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{
+            item.meta.title
+          }}</span>
         <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
       </el-breadcrumb-item>
     </transition-group>
@@ -33,7 +35,7 @@ export default {
       const first = matched[0]
 
       if (!this.isDashboard(first)) {
-        matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
+        matched = [{path: '/dashboard', meta: {title: 'Dashboard'}}].concat(matched)
       }
 
       this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
@@ -47,12 +49,12 @@ export default {
     },
     pathCompile(path) {
       // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
-      const { params } = this.$route
+      const {params} = this.$route
       var toPath = pathToRegexp.compile(path)
       return toPath(params)
     },
     handleLink(item) {
-      const { redirect, path } = item
+      const {redirect, path} = item
       if (redirect) {
         this.$router.push(redirect)
         return

+ 8 - 7
element-demo/src/components/Hamburger/index.vue

@@ -1,14 +1,15 @@
 <template>
   <div style="padding: 0 15px;" @click="toggleClick">
     <svg
-      :class="{'is-active':isActive}"
-      class="hamburger"
-      viewBox="0 0 1024 1024"
-      xmlns="http://www.w3.org/2000/svg"
-      width="64"
-      height="64"
+        :class="{'is-active':isActive}"
+        class="hamburger"
+        viewBox="0 0 1024 1024"
+        xmlns="http://www.w3.org/2000/svg"
+        width="64"
+        height="64"
     >
-      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
+      <path
+          d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"/>
     </svg>
   </div>
 </template>

+ 4 - 4
element-demo/src/components/SvgIcon/index.vue

@@ -1,13 +1,13 @@
 <template>
-  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
+  <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners"/>
   <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
-    <use :xlink:href="iconName" />
+    <use :xlink:href="iconName"/>
   </svg>
 </template>
 
 <script>
 // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
-import { isExternal } from '@/utils/validate'
+import {isExternal} from '@/utils/validate'
 
 export default {
   name: 'SvgIcon',
@@ -56,7 +56,7 @@ export default {
 
 .svg-external-icon {
   background-color: currentColor;
-  mask-size: cover!important;
+  mask-size: cover !important;
   display: inline-block;
 }
 </style>

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
element-demo/src/icons/svg/dashboard.svg


+ 3 - 1
element-demo/src/icons/svg/example.svg

@@ -1 +1,3 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
+    <path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/>
+</svg>

+ 6 - 1
element-demo/src/icons/svg/eye-open.svg

@@ -1 +1,6 @@
-<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>
+<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128">
+    <defs>
+        <style/>
+    </defs>
+    <path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/>
+</svg>

+ 3 - 1
element-demo/src/icons/svg/eye.svg

@@ -1 +1,3 @@
-<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>
+<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg">
+    <path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/>
+</svg>

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
element-demo/src/icons/svg/form.svg


+ 5 - 1
element-demo/src/icons/svg/link.svg

@@ -1 +1,5 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
+    <path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/>
+    <path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/>
+    <path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/>
+</svg>

+ 3 - 1
element-demo/src/icons/svg/nested.svg

@@ -1 +1,3 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
+    <path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/>
+</svg>

+ 3 - 1
element-demo/src/icons/svg/password.svg

@@ -1 +1,3 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
+    <path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/>
+</svg>

+ 4 - 1
element-demo/src/icons/svg/table.svg

@@ -1 +1,4 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
+    <path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/>
+    <path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/>
+</svg>

+ 3 - 1
element-demo/src/icons/svg/tree.svg

@@ -1 +1,3 @@
-<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
+    <path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/>
+</svg>

+ 4 - 1
element-demo/src/icons/svg/user.svg

@@ -1 +1,4 @@
-<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>
+<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg">
+    <path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z"
+          stroke="#979797"/>
+</svg>

+ 4 - 4
element-demo/src/icons/svgo.yml

@@ -16,7 +16,7 @@ plugins:
   #     param1: 1
   #     param2: 2
 
-- removeAttrs:
-    attrs:
-      - 'fill'
-      - 'fill-rule'
+  - removeAttrs:
+      attrs:
+        - 'fill'
+        - 'fill-rule'

+ 3 - 2
element-demo/src/layout/components/AppMain.vue

@@ -1,7 +1,7 @@
 <template>
   <section class="app-main">
     <transition name="fade-transform" mode="out-in">
-      <router-view :key="key" />
+      <router-view :key="key"/>
     </transition>
   </section>
 </template>
@@ -25,7 +25,8 @@ export default {
   position: relative;
   overflow: hidden;
 }
-.fixed-header+.app-main {
+
+.fixed-header + .app-main {
   padding-top: 50px;
 }
 </style>

+ 5 - 5
element-demo/src/layout/components/Navbar.vue

@@ -1,14 +1,14 @@
 <template>
   <div class="navbar">
-    <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+    <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar"/>
 
-    <breadcrumb class="breadcrumb-container" />
+    <breadcrumb class="breadcrumb-container"/>
 
     <div class="right-menu">
       <el-dropdown class="avatar-container" trigger="click">
         <div class="avatar-wrapper">
           <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
-          <i class="el-icon-caret-bottom" />
+          <i class="el-icon-caret-bottom"/>
         </div>
         <el-dropdown-menu slot="dropdown" class="user-dropdown">
           <router-link to="/">
@@ -64,7 +64,7 @@ export default {
   overflow: hidden;
   position: relative;
   background: #fff;
-  box-shadow: 0 1px 4px rgba(0,21,41,.08);
+  box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
 
   .hamburger-container {
     line-height: 46px;
@@ -72,7 +72,7 @@ export default {
     float: left;
     cursor: pointer;
     transition: background .3s;
-    -webkit-tap-highlight-color:transparent;
+    -webkit-tap-highlight-color: transparent;
 
     &:hover {
       background: rgba(0, 0, 0, .025)

+ 22 - 22
element-demo/src/layout/components/Sidebar/FixiOSBug.js

@@ -1,26 +1,26 @@
 export default {
-  computed: {
-    device() {
-      return this.store.app.state.device
-    }
-  },
-  mounted() {
-    // In order to fix the click on menu on the ios device will trigger the mouseleave bug
-    // https://github.com/PanJiaChen/vue-element-admin/issues/1135
-    this.fixBugIniOS()
-  },
-  methods: {
-    fixBugIniOS() {
-      const $subMenu = this.$refs.subMenu
-      if ($subMenu) {
-        const handleMouseleave = $subMenu.handleMouseleave
-        $subMenu.handleMouseleave = (e) => {
-          if (this.device === 'mobile') {
-            return
-          }
-          handleMouseleave(e)
+    computed: {
+        device() {
+            return this.store.app.state.device
+        }
+    },
+    mounted() {
+        // In order to fix the click on menu on the ios device will trigger the mouseleave bug
+        // https://github.com/PanJiaChen/vue-element-admin/issues/1135
+        this.fixBugIniOS()
+    },
+    methods: {
+        fixBugIniOS() {
+            const $subMenu = this.$refs.subMenu
+            if ($subMenu) {
+                const handleMouseleave = $subMenu.handleMouseleave
+                $subMenu.handleMouseleave = (e) => {
+                    if (this.device === 'mobile') {
+                        return
+                    }
+                    handleMouseleave(e)
+                }
+            }
         }
-      }
     }
-  }
 }

+ 2 - 2
element-demo/src/layout/components/Sidebar/Item.vue

@@ -13,12 +13,12 @@ export default {
     }
   },
   render(h, context) {
-    const { icon, title } = context.props
+    const {icon, title} = context.props
     const vnodes = []
 
     if (icon) {
       if (icon.includes('el-icon')) {
-        vnodes.push(<i class={[icon, 'sub-el-icon']} />)
+        vnodes.push(<i class={[icon, 'sub-el-icon']}/>)
       } else {
         vnodes.push(<svg-icon icon-class={icon}/>)
       }

+ 2 - 2
element-demo/src/layout/components/Sidebar/Link.vue

@@ -1,11 +1,11 @@
 <template>
   <component :is="type" v-bind="linkProps(to)">
-    <slot />
+    <slot/>
   </component>
 </template>
 
 <script>
-import { isExternal } from '@/utils/validate'
+import {isExternal} from '@/utils/validate'
 
 export default {
   props: {

+ 13 - 12
element-demo/src/layout/components/Sidebar/SidebarItem.vue

@@ -1,24 +1,25 @@
 <template>
   <div v-if="!item.hidden">
-    <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
+    <template
+        v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
       <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
         <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
-          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
+          <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title"/>
         </el-menu-item>
       </app-link>
     </template>
 
     <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
       <template slot="title">
-        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
+        <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title"/>
       </template>
       <sidebar-item
-        v-for="child in item.children"
-        :key="child.path"
-        :is-nest="true"
-        :item="child"
-        :base-path="resolvePath(child.path)"
-        class="nest-menu"
+          v-for="child in item.children"
+          :key="child.path"
+          :is-nest="true"
+          :item="child"
+          :base-path="resolvePath(child.path)"
+          class="nest-menu"
       />
     </el-submenu>
   </div>
@@ -26,14 +27,14 @@
 
 <script>
 import path from 'path'
-import { isExternal } from '@/utils/validate'
+import {isExternal} from '@/utils/validate'
 import Item from './Item'
 import AppLink from './Link'
 import FixiOSBug from './FixiOSBug'
 
 export default {
   name: 'SidebarItem',
-  components: { Item, AppLink },
+  components: {Item, AppLink},
   mixins: [FixiOSBug],
   props: {
     // route object
@@ -75,7 +76,7 @@ export default {
 
       // Show parent if there are no child router to display
       if (showingChildren.length === 0) {
-        this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
+        this.onlyOneChild = {...parent, path: '', noShowingChildren: true}
         return true
       }
 

+ 12 - 12
element-demo/src/layout/components/Sidebar/index.vue

@@ -1,18 +1,18 @@
 <template>
   <div :class="{'has-logo':showLogo}">
-    <logo v-if="showLogo" :collapse="isCollapse" />
+    <logo v-if="showLogo" :collapse="isCollapse"/>
     <el-scrollbar wrap-class="scrollbar-wrapper">
       <el-menu
-        :default-active="activeMenu"
-        :collapse="isCollapse"
-        :background-color="variables.menuBg"
-        :text-color="variables.menuText"
-        :unique-opened="false"
-        :active-text-color="variables.menuActiveText"
-        :collapse-transition="false"
-        mode="vertical"
+          :default-active="activeMenu"
+          :collapse="isCollapse"
+          :background-color="variables.menuBg"
+          :text-color="variables.menuText"
+          :unique-opened="false"
+          :active-text-color="variables.menuActiveText"
+          :collapse-transition="false"
+          mode="vertical"
       >
-        <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
+        <sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path"/>
       </el-menu>
     </el-scrollbar>
   </div>
@@ -24,7 +24,7 @@ import SidebarItem from './SidebarItem'
 import variables from '@/styles/variables.scss'
 
 export default {
-  components: { SidebarItem, Logo },
+  components: {SidebarItem, Logo},
   data() {
     return {
       'sidebar': this.store.app.state.sidebar
@@ -36,7 +36,7 @@ export default {
     },
     activeMenu() {
       const route = this.$route
-      const { meta, path } = route
+      const {meta, path} = route
       // if set path, the sidebar will highlight the path you set
       if (meta.activeMenu) {
         return meta.activeMenu

+ 3 - 3
element-demo/src/layout/components/index.js

@@ -1,3 +1,3 @@
-export { default as Navbar } from './Navbar'
-export { default as Sidebar } from './Sidebar'
-export { default as AppMain } from './AppMain'
+export {default as Navbar} from './Navbar'
+export {default as Sidebar} from './Sidebar'
+export {default as AppMain} from './AppMain'

+ 40 - 38
element-demo/src/layout/index.vue

@@ -1,18 +1,18 @@
 <template>
   <div :class="classObj" class="app-wrapper">
-    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
-    <sidebar class="sidebar-container" />
+    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
+    <sidebar class="sidebar-container"/>
     <div class="main-container">
       <div :class="{'fixed-header':fixedHeader}">
-        <navbar />
+        <navbar/>
       </div>
-      <app-main />
+      <app-main/>
     </div>
   </div>
 </template>
 
 <script>
-import { Navbar, Sidebar, AppMain } from './components'
+import {Navbar, Sidebar, AppMain} from './components'
 import ResizeMixin from './mixin/ResizeHandler'
 
 export default {
@@ -42,50 +42,52 @@ export default {
   },
   methods: {
     handleClickOutside() {
-      this.store.app.closeSideBar({ withoutAnimation: false })
+      this.store.app.closeSideBar({withoutAnimation: false})
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-  @import "~@/styles/mixin.scss";
-  @import "~@/styles/variables.scss";
+@import "~@/styles/mixin.scss";
+@import "~@/styles/variables.scss";
 
-  .app-wrapper {
-    @include clearfix;
-    position: relative;
-    height: 100%;
-    width: 100%;
-    &.mobile.openSidebar{
-      position: fixed;
-      top: 0;
-    }
-  }
-  .drawer-bg {
-    background: #000;
-    opacity: 0.3;
-    width: 100%;
-    top: 0;
-    height: 100%;
-    position: absolute;
-    z-index: 999;
-  }
+.app-wrapper {
+  @include clearfix;
+  position: relative;
+  height: 100%;
+  width: 100%;
 
-  .fixed-header {
+  &.mobile.openSidebar {
     position: fixed;
     top: 0;
-    right: 0;
-    z-index: 9;
-    width: calc(100% - #{$sideBarWidth});
-    transition: width 0.28s;
   }
+}
 
-  .hideSidebar .fixed-header {
-    width: calc(100% - 54px)
-  }
+.drawer-bg {
+  background: #000;
+  opacity: 0.3;
+  width: 100%;
+  top: 0;
+  height: 100%;
+  position: absolute;
+  z-index: 999;
+}
 
-  .mobile .fixed-header {
-    width: 100%;
-  }
+.fixed-header {
+  position: fixed;
+  top: 0;
+  right: 0;
+  z-index: 9;
+  width: calc(100% - #{$sideBarWidth});
+  transition: width 0.28s;
+}
+
+.hideSidebar .fixed-header {
+  width: calc(100% - 54px)
+}
+
+.mobile .fixed-header {
+  width: 100%;
+}
 </style>

+ 34 - 34
element-demo/src/layout/mixin/ResizeHandler.js

@@ -1,45 +1,45 @@
 import store from '@/store'
 
-const { body } = document
+const {body} = document
 const WIDTH = 992 // refer to Bootstrap's responsive design
 
 export default {
-  watch: {
-    $route(route) {
-      if (this.device === 'mobile' && this.sidebar.opened) {
-        store.app.closeSideBar({ withoutAnimation: false })
-      }
-    }
-  },
-  beforeMount() {
-    window.addEventListener('resize', this.$_resizeHandler)
-  },
-  beforeDestroy() {
-    window.removeEventListener('resize', this.$_resizeHandler)
-  },
-  mounted() {
-    const isMobile = this.$_isMobile()
-    if (isMobile) {
-      store.app.toggleDevice('mobile')
-      store.app.closeSideBar({ withoutAnimation: true })
-    }
-  },
-  methods: {
-    // use $_ for mixins properties
-    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
-    $_isMobile() {
-      const rect = body.getBoundingClientRect()
-      return rect.width - 1 < WIDTH
+    watch: {
+        $route(route) {
+            if (this.device === 'mobile' && this.sidebar.opened) {
+                store.app.closeSideBar({withoutAnimation: false})
+            }
+        }
+    },
+    beforeMount() {
+        window.addEventListener('resize', this.$_resizeHandler)
+    },
+    beforeDestroy() {
+        window.removeEventListener('resize', this.$_resizeHandler)
     },
-    $_resizeHandler() {
-      if (!document.hidden) {
+    mounted() {
         const isMobile = this.$_isMobile()
-        store.app.toggleSideBar(isMobile ? 'mobile' : 'desktop')
-
         if (isMobile) {
-          store.app.closeSideBar({ withoutAnimation: true })
+            store.app.toggleDevice('mobile')
+            store.app.closeSideBar({withoutAnimation: true})
+        }
+    },
+    methods: {
+        // use $_ for mixins properties
+        // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+        $_isMobile() {
+            const rect = body.getBoundingClientRect()
+            return rect.width - 1 < WIDTH
+        },
+        $_resizeHandler() {
+            if (!document.hidden) {
+                const isMobile = this.$_isMobile()
+                store.app.toggleSideBar(isMobile ? 'mobile' : 'desktop')
+
+                if (isMobile) {
+                    store.app.closeSideBar({withoutAnimation: true})
+                }
+            }
         }
-      }
     }
-  }
 }

+ 7 - 7
element-demo/src/main.js

@@ -23,13 +23,13 @@ import '@/permission' // permission control
  * Currently MockJs will be used in the production environment,
  * please remove it before going online ! ! !
  */
-if (process.env.NODE_ENV === 'production') {
-  const { mockXHR } = require('../mock')
-  mockXHR()
+if (process.env.NODE_ENV === 'development') {
+    const {mockXHR} = require('../mock')
+    mockXHR()
 }
 
 // set ElementUI lang to EN
-Vue.use(ElementUI, { locale })
+Vue.use(ElementUI, {locale})
 // 如果想要中文版 element-ui,按如下方式声明
 // Vue.use(ElementUI)
 
@@ -37,7 +37,7 @@ Vue.config.productionTip = false
 Vue.prototype.store = store
 
 new Vue({
-  el: '#app',
-  router,
-  render: h => h(App)
+    el: '#app',
+    router,
+    render: h => h(App)
 })

+ 44 - 44
element-demo/src/permission.js

@@ -1,64 +1,64 @@
 import router from './router'
 import store from './store'
-import { Message } from 'element-ui'
+import {Message} from 'element-ui'
 import NProgress from 'nprogress' // progress bar
 import 'nprogress/nprogress.css' // progress bar style
-import { getToken } from '@/utils/auth' // get token from cookie
+import {getToken} from '@/utils/auth' // get token from cookie
 import getPageTitle from '@/utils/get-page-title'
 
-NProgress.configure({ showSpinner: false }) // NProgress Configuration
+NProgress.configure({showSpinner: false}) // NProgress Configuration
 
 const whiteList = ['/login'] // no redirect whitelist
 
-router.beforeEach(async(to, from, next) => {
-  // start progress bar
-  NProgress.start()
+router.beforeEach(async (to, from, next) => {
+    // start progress bar
+    NProgress.start()
 
-  // set page title
-  document.title = getPageTitle(to.meta.title)
+    // set page title
+    document.title = getPageTitle(to.meta.title)
 
-  // determine whether the user has logged in
-  const hasToken = getToken()
+    // determine whether the user has logged in
+    const hasToken = getToken()
 
-  if (hasToken) {
-    if (to.path === '/login') {
-      // if is logged in, redirect to the home page
-      next({ path: '/' })
-      NProgress.done()
-    } else {
-      const hasGetUserInfo = store.user.state.name
-      if (hasGetUserInfo) {
-        next()
-      } else {
-        try {
-          // get user info
-          await store.user.getInfo()
+    if (hasToken) {
+        if (to.path === '/login') {
+            // if is logged in, redirect to the home page
+            next({path: '/'})
+            NProgress.done()
+        } else {
+            const hasGetUserInfo = store.user.state.name
+            if (hasGetUserInfo) {
+                next()
+            } else {
+                try {
+                    // get user info
+                    await store.user.getInfo()
 
-          next()
-        } catch (error) {
-          // remove token and go to login page to re-login
-          await store.user.resetToken()
-          Message.error(error || 'Has Error')
-          next(`/login?redirect=${to.path}`)
-          NProgress.done()
+                    next()
+                } catch (error) {
+                    // remove token and go to login page to re-login
+                    await store.user.resetToken()
+                    Message.error(error || 'Has Error')
+                    next(`/login?redirect=${to.path}`)
+                    NProgress.done()
+                }
+            }
         }
-      }
-    }
-  } else {
-    /* has no token*/
-
-    if (whiteList.indexOf(to.path) !== -1) {
-      // in the free login whitelist, go directly
-      next()
     } else {
-      // other pages that do not have permission to access are redirected to the login page.
-      next(`/login?redirect=${to.path}`)
-      NProgress.done()
+        /* has no token*/
+
+        if (whiteList.indexOf(to.path) !== -1) {
+            // in the free login whitelist, go directly
+            next()
+        } else {
+            // other pages that do not have permission to access are redirected to the login page.
+            next(`/login?redirect=${to.path}`)
+            NProgress.done()
+        }
     }
-  }
 })
 
 router.afterEach(() => {
-  // finish progress bar
-  NProgress.done()
+    // finish progress bar
+    NProgress.done()
 })

+ 77 - 77
element-demo/src/router/index.js

@@ -31,97 +31,97 @@ import Layout from '@/layout'
  * all roles can be accessed
  */
 export const constantRoutes = [
-  {
-    path: '/login',
-    component: () => import('@/views/login/index'),
-    hidden: true
-  },
+    {
+        path: '/login',
+        component: () => import('@/views/login/index'),
+        hidden: true
+    },
 
-  {
-    path: '/404',
-    component: () => import('@/views/404'),
-    hidden: true
-  },
+    {
+        path: '/404',
+        component: () => import('@/views/404'),
+        hidden: true
+    },
 
-  {
-    path: '/',
-    component: Layout,
-    redirect: '/dashboard',
-    children: [{
-      path: 'dashboard',
-      name: 'Dashboard',
-      component: () => import('@/views/dashboard/index'),
-      meta: { title: 'Dashboard', icon: 'dashboard' }
-    }]
-  },
+    {
+        path: '/',
+        component: Layout,
+        redirect: '/dashboard',
+        children: [{
+            path: 'dashboard',
+            name: 'Dashboard',
+            component: () => import('@/views/dashboard/index'),
+            meta: {title: 'Dashboard', icon: 'dashboard'}
+        }]
+    },
 
-  {
-    path: '/example',
-    component: Layout,
-    redirect: '/example/table',
-    name: 'Example',
-    meta: { title: 'Example', icon: 'el-icon-s-help' },
-    children: [
-      {
-        path: 'table',
-        name: 'Table',
-        component: () => import('@/views/table/index'),
-        meta: { title: 'Table', icon: 'table' }
-      }
-    ]
-  },
-  {
-    path: '/table1',
-    component: Layout,
-    children: [
-      {
-        path: 'index',
-        name: 'Table1',
-        component: () => import('@/views/table1/index'),
-        meta: { title: 'Table1', icon: 'table' }
-      }
-    ]
-  },
-  {
-    path: '/form',
-    component: Layout,
-    children: [
-      {
-        path: 'index',
-        name: 'Form',
-        component: () => import('@/views/form/index'),
-        meta: { title: 'Form', icon: 'form' }
-      }
-    ]
-  },
+    {
+        path: '/example',
+        component: Layout,
+        redirect: '/example/table',
+        name: 'Example',
+        meta: {title: 'Example', icon: 'el-icon-s-help'},
+        children: [
+            {
+                path: 'table',
+                name: 'Table',
+                component: () => import('@/views/table/index'),
+                meta: {title: 'Table', icon: 'table'}
+            }
+        ]
+    },
+    {
+        path: '/table1',
+        component: Layout,
+        children: [
+            {
+                path: 'index',
+                name: 'Table1',
+                component: () => import('@/views/table1/index'),
+                meta: {title: 'Table1', icon: 'table'}
+            }
+        ]
+    },
+    {
+        path: '/form',
+        component: Layout,
+        children: [
+            {
+                path: 'index',
+                name: 'Form',
+                component: () => import('@/views/form/index'),
+                meta: {title: 'Form', icon: 'form'}
+            }
+        ]
+    },
 
-  {
-    path: 'external-link',
-    component: Layout,
-    children: [
-      {
-        path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
-        meta: { title: 'External Link', icon: 'link' }
-      }
-    ]
-  },
+    {
+        path: 'external-link',
+        component: Layout,
+        children: [
+            {
+                path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
+                meta: {title: 'External Link', icon: 'link'}
+            }
+        ]
+    },
 
-  // 404 page must be placed at the end !!!
-  { path: '*', redirect: '/404', hidden: true }
+    // 404 page must be placed at the end !!!
+    {path: '*', redirect: '/404', hidden: true}
 ]
 
 const createRouter = () => new Router({
-  // mode: 'history', // require service support
-  scrollBehavior: () => ({ y: 0 }),
-  routes: constantRoutes
+    // mode: 'history', // require service support
+    scrollBehavior: () => ({y: 0}),
+    routes: constantRoutes
 })
 
 const router = createRouter()
 
 // Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
 export function resetRouter() {
-  const newRouter = createRouter()
-  router.matcher = newRouter.matcher // reset router
+    const newRouter = createRouter()
+    router.matcher = newRouter.matcher // reset router
 }
 
 export default router

+ 11 - 11
element-demo/src/settings.js

@@ -1,16 +1,16 @@
 module.exports = {
 
-  title: '标题',
+    title: '标题',
 
-  /**
-   * @type {boolean} true | false
-   * @description Whether fix the header
-   */
-  fixedHeader: false,
+    /**
+     * @type {boolean} true | false
+     * @description Whether fix the header
+     */
+    fixedHeader: false,
 
-  /**
-   * @type {boolean} true | false
-   * @description Whether show the logo in sidebar
-   */
-  sidebarLogo: true
+    /**
+     * @type {boolean} true | false
+     * @description Whether show the logo in sidebar
+     */
+    sidebarLogo: true
 }

+ 3 - 3
element-demo/src/store/index.js

@@ -3,9 +3,9 @@ import settings from './modules/settings'
 import user from './modules/user'
 
 const store = {
-  app,
-  user,
-  settings
+    app,
+    user,
+    settings
 }
 
 export default store

+ 23 - 23
element-demo/src/store/modules/app.js

@@ -1,30 +1,30 @@
 import Cookies from 'js-cookie'
 
 export default {
-  state: {
-    sidebar: {
-      opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
-      withoutAnimation: false
+    state: {
+        sidebar: {
+            opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+            withoutAnimation: false
+        },
+        device: 'desktop'
     },
-    device: 'desktop'
-  },
 
-  toggleSideBar: function() {
-    this.state.sidebar.opened = !this.state.sidebar.opened
-    this.state.sidebar.withoutAnimation = false
-    if (this.state.sidebar.opened) {
-      Cookies.set('sidebarStatus', 1)
-    } else {
-      Cookies.set('sidebarStatus', 0)
-    }
-  },
-  closeSideBar: function({ withoutAnimation }) {
-    Cookies.set('sidebarStatus', 0)
-    this.state.sidebar.opened = false
-    this.state.sidebar.withoutAnimation = withoutAnimation
-  },
+    toggleSideBar: function () {
+        this.state.sidebar.opened = !this.state.sidebar.opened
+        this.state.sidebar.withoutAnimation = false
+        if (this.state.sidebar.opened) {
+            Cookies.set('sidebarStatus', 1)
+        } else {
+            Cookies.set('sidebarStatus', 0)
+        }
+    },
+    closeSideBar: function ({withoutAnimation}) {
+        Cookies.set('sidebarStatus', 0)
+        this.state.sidebar.opened = false
+        this.state.sidebar.withoutAnimation = withoutAnimation
+    },
 
-  toggleDevice: function(device) {
-    this.state.device = device
-  }
+    toggleDevice: function (device) {
+        this.state.device = device
+    }
 }

+ 11 - 11
element-demo/src/store/modules/settings.js

@@ -1,17 +1,17 @@
 import defaultSettings from '@/settings'
 
-const { showSettings, fixedHeader, sidebarLogo } = defaultSettings
+const {showSettings, fixedHeader, sidebarLogo} = defaultSettings
 
 export default {
-  state: {
-    showSettings: showSettings,
-    fixedHeader: fixedHeader,
-    sidebarLogo: sidebarLogo
-  },
-  changeSetting: function({ key, value }) {
-    // eslint-disable-next-line no-prototype-builtins
-    if (this.state.hasOwnProperty(key)) {
-      this.state[key] = value
+    state: {
+        showSettings: showSettings,
+        fixedHeader: fixedHeader,
+        sidebarLogo: sidebarLogo
+    },
+    changeSetting: function ({key, value}) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (this.state.hasOwnProperty(key)) {
+            this.state[key] = value
+        }
     }
-  }
 }

+ 58 - 58
element-demo/src/store/modules/user.js

@@ -1,67 +1,67 @@
-import { login, logout, getInfo } from '@/api/user'
-import { getToken, setToken, removeToken } from '@/utils/auth'
-import { resetRouter } from '@/router'
+import {login, logout, getInfo} from '@/api/user'
+import {getToken, setToken, removeToken} from '@/utils/auth'
+import {resetRouter} from '@/router'
 
 function getDefaultState() {
-  return {
-    token: getToken(),
-    name: '',
-    avatar: ''
-  }
+    return {
+        token: getToken(),
+        name: '',
+        avatar: ''
+    }
 }
 
 export default {
-  state: getDefaultState(),
-  login: function(userInfo) {
-    const { username, password } = userInfo
-    return new Promise((resolve, reject) => {
-      login({ username: username.trim(), password: password }).then(response => {
-        const { data } = response
-        this.state.token = data.token
-        setToken(data.token)
-        resolve()
-      }).catch(error => {
-        reject(error)
-      })
-    })
-  },
-  getInfo() {
-    return new Promise((resolve, reject) => {
-      getInfo(this.state.token).then(response => {
-        const { data } = response
+    state: getDefaultState(),
+    login: function (userInfo) {
+        const {username, password} = userInfo
+        return new Promise((resolve, reject) => {
+            login({username: username.trim(), password: password}).then(response => {
+                const {data} = response
+                this.state.token = data.token
+                setToken(data.token)
+                resolve()
+            }).catch(error => {
+                reject(error)
+            })
+        })
+    },
+    getInfo() {
+        return new Promise((resolve, reject) => {
+            getInfo(this.state.token).then(response => {
+                const {data} = response
 
-        if (!data) {
-          return reject('Verification failed, please Login again.')
-        }
+                if (!data) {
+                    return reject('Verification failed, please Login again.')
+                }
 
-        const { name, avatar } = data
-        this.state.name = name
-        this.state.avatar = avatar
-        resolve(data)
-      }).catch(error => {
-        reject(error)
-      })
-    })
-  },
-  logout() {
-    return new Promise((resolve, reject) => {
-      logout(this.state.token).then(() => {
-        removeToken() // must remove  token  first
-        resetRouter()
-        Object.assign(this.state, getDefaultState())
-        resolve()
-      }).catch(error => {
-        reject(error)
-      })
-    })
-  },
-  // remove token
-  resetToken() {
-    return new Promise(resolve => {
-      removeToken() // must remove  token  first
-      Object.assign(this.state, getDefaultState())
-      resolve()
-    })
-  }
+                const {name, avatar} = data
+                this.state.name = name
+                this.state.avatar = avatar
+                resolve(data)
+            }).catch(error => {
+                reject(error)
+            })
+        })
+    },
+    logout() {
+        return new Promise((resolve, reject) => {
+            logout(this.state.token).then(() => {
+                removeToken() // must remove  token  first
+                resetRouter()
+                Object.assign(this.state, getDefaultState())
+                resolve()
+            }).catch(error => {
+                reject(error)
+            })
+        })
+    },
+    // remove token
+    resetToken() {
+        return new Promise(resolve => {
+            removeToken() // must remove  token  first
+            Object.assign(this.state, getDefaultState())
+            resolve()
+        })
+    }
 }
 

+ 9 - 8
element-demo/src/styles/sidebar.scss

@@ -76,11 +76,11 @@
       }
     }
 
-    .is-active>.el-submenu__title {
+    .is-active > .el-submenu__title {
       color: $subMenuActiveText !important;
     }
 
-    & .nest-menu .el-submenu>.el-submenu__title,
+    & .nest-menu .el-submenu > .el-submenu__title,
     & .el-submenu .el-menu-item {
       min-width: $sideBarWidth !important;
       background-color: $subMenuBg !important;
@@ -120,7 +120,7 @@
     .el-submenu {
       overflow: hidden;
 
-      &>.el-submenu__title {
+      & > .el-submenu__title {
         padding: 0 !important;
 
         .svg-icon {
@@ -139,8 +139,8 @@
 
     .el-menu--collapse {
       .el-submenu {
-        &>.el-submenu__title {
-          &>span {
+        & > .el-submenu__title {
+          & > span {
             height: 0;
             width: 0;
             overflow: hidden;
@@ -187,17 +187,18 @@
 
 // when menu collapsed
 .el-menu--vertical {
-  &>.el-menu {
+  & > .el-menu {
     .svg-icon {
       margin-right: 16px;
     }
+
     .sub-el-icon {
       margin-right: 12px;
       margin-left: -2px;
     }
   }
 
-  .nest-menu .el-submenu>.el-submenu__title,
+  .nest-menu .el-submenu > .el-submenu__title,
   .el-menu-item {
     &:hover {
       // you can use $subMenuHover
@@ -206,7 +207,7 @@
   }
 
   // the scroll bar appears when the subMenu is too long
-  >.el-menu--popup {
+  > .el-menu--popup {
     max-height: 100vh;
     overflow-y: auto;
 

+ 7 - 7
element-demo/src/styles/variables.scss

@@ -1,13 +1,13 @@
 // sidebar
-$menuText:#bfcbd9;
-$menuActiveText:#409EFF;
-$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
+$menuText: #bfcbd9;
+$menuActiveText: #409EFF;
+$subMenuActiveText: #f4f4f5; //https://github.com/ElemeFE/element/issues/12951
 
-$menuBg:#304156;
-$menuHover:#263445;
+$menuBg: #304156;
+$menuHover: #263445;
 
-$subMenuBg:#1f2d3d;
-$subMenuHover:#001528;
+$subMenuBg: #1f2d3d;
+$subMenuHover: #001528;
 
 $sideBarWidth: 210px;
 

+ 3 - 3
element-demo/src/utils/auth.js

@@ -3,13 +3,13 @@ import Cookies from 'js-cookie'
 const TokenKey = 'vue_admin_template_token'
 
 export function getToken() {
-  return Cookies.get(TokenKey)
+    return Cookies.get(TokenKey)
 }
 
 export function setToken(token) {
-  return Cookies.set(TokenKey, token)
+    return Cookies.set(TokenKey, token)
 }
 
 export function removeToken() {
-  return Cookies.remove(TokenKey)
+    return Cookies.remove(TokenKey)
 }

+ 4 - 4
element-demo/src/utils/get-page-title.js

@@ -3,8 +3,8 @@ import defaultSettings from '@/settings'
 const title = defaultSettings.title || 'Vue Admin Template'
 
 export default function getPageTitle(pageTitle) {
-  if (pageTitle) {
-    return `${pageTitle} - ${title}`
-  }
-  return `${title}`
+    if (pageTitle) {
+        return `${pageTitle} - ${title}`
+    }
+    return `${title}`
 }

+ 86 - 84
element-demo/src/utils/index.js

@@ -9,46 +9,48 @@
  * @returns {string | null}
  */
 export function parseTime(time, cFormat) {
-  if (arguments.length === 0 || !time) {
-    return null
-  }
-  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
-  let date
-  if (typeof time === 'object') {
-    date = time
-  } else {
-    if ((typeof time === 'string')) {
-      if ((/^[0-9]+$/.test(time))) {
-        // support "1548221490638"
-        time = parseInt(time)
-      } else {
-        // support safari
-        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
-        time = time.replace(new RegExp(/-/gm), '/')
-      }
+    if (arguments.length === 0 || !time) {
+        return null
     }
+    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
+    let date
+    if (typeof time === 'object') {
+        date = time
+    } else {
+        if ((typeof time === 'string')) {
+            if ((/^[0-9]+$/.test(time))) {
+                // support "1548221490638"
+                time = parseInt(time)
+            } else {
+                // support safari
+                // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
+                time = time.replace(new RegExp(/-/gm), '/')
+            }
+        }
 
-    if ((typeof time === 'number') && (time.toString().length === 10)) {
-      time = time * 1000
+        if ((typeof time === 'number') && (time.toString().length === 10)) {
+            time = time * 1000
+        }
+        date = new Date(time)
     }
-    date = new Date(time)
-  }
-  const formatObj = {
-    y: date.getFullYear(),
-    m: date.getMonth() + 1,
-    d: date.getDate(),
-    h: date.getHours(),
-    i: date.getMinutes(),
-    s: date.getSeconds(),
-    a: date.getDay()
-  }
-  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
-    const value = formatObj[key]
-    // Note: getDay() returns 0 on Sunday
-    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
-    return value.toString().padStart(2, '0')
-  })
-  return time_str
+    const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+    }
+    const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
+        const value = formatObj[key]
+        // Note: getDay() returns 0 on Sunday
+        if (key === 'a') {
+            return ['日', '一', '二', '三', '四', '五', '六'][value]
+        }
+        return value.toString().padStart(2, '0')
+    })
+    return time_str
 }
 
 /**
@@ -57,41 +59,41 @@ export function parseTime(time, cFormat) {
  * @returns {string}
  */
 export function formatTime(time, option) {
-  if (('' + time).length === 10) {
-    time = parseInt(time) * 1000
-  } else {
-    time = +time
-  }
-  const d = new Date(time)
-  const now = Date.now()
+    if (('' + time).length === 10) {
+        time = parseInt(time) * 1000
+    } else {
+        time = +time
+    }
+    const d = new Date(time)
+    const now = Date.now()
 
-  const diff = (now - d) / 1000
+    const diff = (now - d) / 1000
 
-  if (diff < 30) {
-    return '刚刚'
-  } else if (diff < 3600) {
-    // less 1 hour
-    return Math.ceil(diff / 60) + '分钟前'
-  } else if (diff < 3600 * 24) {
-    return Math.ceil(diff / 3600) + '小时前'
-  } else if (diff < 3600 * 24 * 2) {
-    return '1天前'
-  }
-  if (option) {
-    return parseTime(time, option)
-  } else {
-    return (
-      d.getMonth() +
-      1 +
-      '月' +
-      d.getDate() +
-      '日' +
-      d.getHours() +
-      '时' +
-      d.getMinutes() +
-      '分'
-    )
-  }
+    if (diff < 30) {
+        return '刚刚'
+    } else if (diff < 3600) {
+        // less 1 hour
+        return Math.ceil(diff / 60) + '分钟前'
+    } else if (diff < 3600 * 24) {
+        return Math.ceil(diff / 3600) + '小时前'
+    } else if (diff < 3600 * 24 * 2) {
+        return '1天前'
+    }
+    if (option) {
+        return parseTime(time, option)
+    } else {
+        return (
+            d.getMonth() +
+            1 +
+            '月' +
+            d.getDate() +
+            '日' +
+            d.getHours() +
+            '时' +
+            d.getMinutes() +
+            '分'
+        )
+    }
 }
 
 /**
@@ -99,19 +101,19 @@ export function formatTime(time, option) {
  * @returns {Object}
  */
 export function param2Obj(url) {
-  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
-  if (!search) {
-    return {}
-  }
-  const obj = {}
-  const searchArr = search.split('&')
-  searchArr.forEach(v => {
-    const index = v.indexOf('=')
-    if (index !== -1) {
-      const name = v.substring(0, index)
-      const val = v.substring(index + 1, v.length)
-      obj[name] = val
+    const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+    if (!search) {
+        return {}
     }
-  })
-  return obj
+    const obj = {}
+    const searchArr = search.split('&')
+    searchArr.forEach(v => {
+        const index = v.indexOf('=')
+        if (index !== -1) {
+            const name = v.substring(0, index)
+            const val = v.substring(index + 1, v.length)
+            obj[name] = val
+        }
+    })
+    return obj
 }

+ 62 - 62
element-demo/src/utils/request.js

@@ -1,85 +1,85 @@
 import axios from 'axios'
-import { MessageBox, Message } from 'element-ui'
+import {MessageBox, Message} from 'element-ui'
 import store from '@/store'
-import { getToken } from '@/utils/auth'
+import {getToken} from '@/utils/auth'
 
 // create an axios instance
 const service = axios.create({
-  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
-  // withCredentials: true, // send cookies when cross-domain requests
-  timeout: 5000 // request timeout
+    baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
+    // withCredentials: true, // send cookies when cross-domain requests
+    timeout: 5000 // request timeout
 })
 
 // request interceptor
 service.interceptors.request.use(
-  config => {
-    // do something before request is sent
+    config => {
+        // do something before request is sent
 
-    if (store.user.state.token) {
-      // let each request carry token
-      // ['X-Token'] is a custom headers key
-      // please modify it according to the actual situation
-      config.headers['X-Token'] = getToken()
+        if (store.user.state.token) {
+            // let each request carry token
+            // ['X-Token'] is a custom headers key
+            // please modify it according to the actual situation
+            config.headers['X-Token'] = getToken()
+        }
+        return config
+    },
+    error => {
+        // do something with request error
+        console.log(error) // for debug
+        return Promise.reject(error)
     }
-    return config
-  },
-  error => {
-    // do something with request error
-    console.log(error) // for debug
-    return Promise.reject(error)
-  }
 )
 
 // response interceptor
 service.interceptors.response.use(
-  /**
-   * If you want to get http information such as headers or status
-   * Please return  response => response
-  */
+    /**
+     * If you want to get http information such as headers or status
+     * Please return  response => response
+     */
 
-  /**
-   * Determine the request status by custom code
-   * Here is just an example
-   * You can also judge the status by HTTP Status Code
-   */
-  response => {
-    const res = response.data
+    /**
+     * Determine the request status by custom code
+     * Here is just an example
+     * You can also judge the status by HTTP Status Code
+     */
+    response => {
+        const res = response.data
 
-    // if the custom code is not 20000, it is judged as an error.
-    if (res.code !== 20000) {
-      Message({
-        message: res.message || 'Error',
-        type: 'error',
-        duration: 5 * 1000
-      })
+        // if the custom code is not 20000, it is judged as an error.
+        if (res.code !== 20000) {
+            Message({
+                message: res.message || 'Error',
+                type: 'error',
+                duration: 5 * 1000
+            })
 
-      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
-      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
-        // to re-login
-        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
-          confirmButtonText: 'Re-Login',
-          cancelButtonText: 'Cancel',
-          type: 'warning'
-        }).then(() => {
-          store.user.resetToken().then(() => {
-            location.reload()
-          })
+            // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
+            if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
+                // to re-login
+                MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
+                    confirmButtonText: 'Re-Login',
+                    cancelButtonText: 'Cancel',
+                    type: 'warning'
+                }).then(() => {
+                    store.user.resetToken().then(() => {
+                        location.reload()
+                    })
+                })
+            }
+            return Promise.reject(new Error(res.message || 'Error'))
+        } else {
+            return res
+        }
+    },
+    error => {
+        console.log('err' + error) // for debug
+        Message({
+            message: error.message,
+            type: 'error',
+            duration: 5 * 1000
         })
-      }
-      return Promise.reject(new Error(res.message || 'Error'))
-    } else {
-      return res
+        return Promise.reject(error)
     }
-  },
-  error => {
-    console.log('err' + error) // for debug
-    Message({
-      message: error.message,
-      type: 'error',
-      duration: 5 * 1000
-    })
-    return Promise.reject(error)
-  }
 )
 
 export default service

+ 3 - 3
element-demo/src/utils/validate.js

@@ -7,7 +7,7 @@
  * @returns {Boolean}
  */
 export function isExternal(path) {
-  return /^(https?:|mailto:|tel:)/.test(path)
+    return /^(https?:|mailto:|tel:)/.test(path)
 }
 
 /**
@@ -15,6 +15,6 @@ export function isExternal(path) {
  * @returns {Boolean}
  */
 export function validUsername(str) {
-  const valid_map = ['admin', 'editor']
-  return valid_map.indexOf(str.trim()) >= 0
+    const valid_map = ['admin', 'editor']
+    return valid_map.indexOf(str.trim()) >= 0
 }

+ 19 - 3
element-demo/src/views/404.vue

@@ -13,7 +13,9 @@
           <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
         </div>
         <div class="bullshit__headline">{{ message }}</div>
-        <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
+        <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to
+          return to the homepage.
+        </div>
         <a href="" class="bullshit__return-home">Back to home</a>
       </div>
     </div>
@@ -33,27 +35,32 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.wscn-http404-container{
-  transform: translate(-50%,-50%);
+.wscn-http404-container {
+  transform: translate(-50%, -50%);
   position: absolute;
   top: 40%;
   left: 50%;
 }
+
 .wscn-http404 {
   position: relative;
   width: 1200px;
   padding: 0 50px;
   overflow: hidden;
+
   .pic-404 {
     position: relative;
     float: left;
     width: 600px;
     overflow: hidden;
+
     &__parent {
       width: 100%;
     }
+
     &__child {
       position: absolute;
+
       &.left {
         width: 80px;
         top: 17px;
@@ -65,6 +72,7 @@ export default {
         animation-fill-mode: forwards;
         animation-delay: 1s;
       }
+
       &.mid {
         width: 46px;
         top: 10px;
@@ -76,6 +84,7 @@ export default {
         animation-fill-mode: forwards;
         animation-delay: 1.2s;
       }
+
       &.right {
         width: 62px;
         top: 100px;
@@ -87,6 +96,7 @@ export default {
         animation-fill-mode: forwards;
         animation-delay: 1s;
       }
+
       @keyframes cloudLeft {
         0% {
           top: 17px;
@@ -155,12 +165,14 @@ export default {
       }
     }
   }
+
   .bullshit {
     position: relative;
     float: left;
     width: 300px;
     padding: 30px 0;
     overflow: hidden;
+
     &__oops {
       font-size: 32px;
       font-weight: bold;
@@ -172,6 +184,7 @@ export default {
       animation-duration: 0.5s;
       animation-fill-mode: forwards;
     }
+
     &__headline {
       font-size: 20px;
       line-height: 24px;
@@ -184,6 +197,7 @@ export default {
       animation-delay: 0.1s;
       animation-fill-mode: forwards;
     }
+
     &__info {
       font-size: 13px;
       line-height: 21px;
@@ -195,6 +209,7 @@ export default {
       animation-delay: 0.2s;
       animation-fill-mode: forwards;
     }
+
     &__return-home {
       display: block;
       float: left;
@@ -213,6 +228,7 @@ export default {
       animation-delay: 0.3s;
       animation-fill-mode: forwards;
     }
+
     @keyframes slideUp {
       0% {
         transform: translateY(60px);

+ 1 - 0
element-demo/src/views/dashboard/index.vue

@@ -24,6 +24,7 @@ export default {
   &-container {
     margin: 30px;
   }
+
   &-text {
     font-size: 30px;
     line-height: 46px;

+ 14 - 14
element-demo/src/views/form/index.vue

@@ -2,42 +2,42 @@
   <div class="app-container">
     <el-form ref="form" :model="form" label-width="120px">
       <el-form-item label="Activity name">
-        <el-input v-model="form.name" />
+        <el-input v-model="form.name"/>
       </el-form-item>
       <el-form-item label="Activity zone">
         <el-select v-model="form.region" placeholder="please select your zone">
-          <el-option label="Zone one" value="shanghai" />
-          <el-option label="Zone two" value="beijing" />
+          <el-option label="Zone one" value="shanghai"/>
+          <el-option label="Zone two" value="beijing"/>
         </el-select>
       </el-form-item>
       <el-form-item label="Activity time">
         <el-col :span="11">
-          <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
+          <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;"/>
         </el-col>
         <el-col :span="2" class="line">-</el-col>
         <el-col :span="11">
-          <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
+          <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;"/>
         </el-col>
       </el-form-item>
       <el-form-item label="Instant delivery">
-        <el-switch v-model="form.delivery" />
+        <el-switch v-model="form.delivery"/>
       </el-form-item>
       <el-form-item label="Activity type">
         <el-checkbox-group v-model="form.type">
-          <el-checkbox label="Online activities" name="type" />
-          <el-checkbox label="Promotion activities" name="type" />
-          <el-checkbox label="Offline activities" name="type" />
-          <el-checkbox label="Simple brand exposure" name="type" />
+          <el-checkbox label="Online activities" name="type"/>
+          <el-checkbox label="Promotion activities" name="type"/>
+          <el-checkbox label="Offline activities" name="type"/>
+          <el-checkbox label="Simple brand exposure" name="type"/>
         </el-checkbox-group>
       </el-form-item>
       <el-form-item label="Resources">
         <el-radio-group v-model="form.resource">
-          <el-radio label="Sponsor" />
-          <el-radio label="Venue" />
+          <el-radio label="Sponsor"/>
+          <el-radio label="Venue"/>
         </el-radio-group>
       </el-form-item>
       <el-form-item label="Activity form">
-        <el-input v-model="form.desc" type="textarea" />
+        <el-input v-model="form.desc" type="textarea"/>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" @click="onSubmit">Create</el-button>
@@ -78,7 +78,7 @@ export default {
 </script>
 
 <style scoped>
-.line{
+.line {
   text-align: center;
 }
 </style>

+ 8 - 8
element-demo/src/views/table/index.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="app-container">
     <el-table
-      v-loading="listLoading"
-      :data="list"
-      element-loading-text="Loading"
-      border
-      fit
-      highlight-current-row
+        v-loading="listLoading"
+        :data="list"
+        element-loading-text="Loading"
+        border
+        fit
+        highlight-current-row
     >
       <el-table-column align="center" label="ID" width="95">
         <template slot-scope="scope">
@@ -35,7 +35,7 @@
       </el-table-column>
       <el-table-column align="center" prop="created_at" label="Display_time" width="200">
         <template slot-scope="scope">
-          <i class="el-icon-time" />
+          <i class="el-icon-time"/>
           <span>{{ scope.row.display_time }}</span>
         </template>
       </el-table-column>
@@ -44,7 +44,7 @@
 </template>
 
 <script>
-import { getList } from '@/api/table'
+import {getList} from '@/api/table'
 
 export default {
   filters: {

+ 44 - 43
element-demo/src/views/table1/index.vue

@@ -2,10 +2,10 @@
   <div class="app-container">
     <el-form :inline="true" :model="param" class="demo-form-inline">
       <el-form-item label="名字">
-        <el-input v-model="param.name" placeholder="名字" />
+        <el-input v-model="param.name" placeholder="名字"/>
       </el-form-item>
       <el-form-item label="日期">
-        <el-input v-model="param.date" />
+        <el-input v-model="param.date"/>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" @click="queryList">查询</el-button>
@@ -18,42 +18,42 @@
       </el-row>
       <!--数据-->
       <el-table
-        :data="tableData"
-        border
-        style="width: 100%"
+          :data="tableData"
+          border
+          style="width: 100%"
       >
         <el-table-column
-          fixed
-          prop="date"
-          label="日期"
-          width="150"
+            fixed
+            prop="date"
+            label="日期"
+            width="150"
         />
         <el-table-column
-          prop="name"
-          label="姓名"
-          width="150"
+            prop="name"
+            label="姓名"
+            width="150"
         />
         <el-table-column
-          prop="email"
-          label="email地址"
-          width="300"
+            prop="email"
+            label="email地址"
+            width="300"
         />
         <el-table-column
-          fixed="right"
-          label="操作"
-          width="100"
+            fixed="right"
+            label="操作"
+            width="100"
         >
           <template slot-scope="scope">
             <el-button
-              type="text"
-              size="small"
-              @click="editOne(scope.row)"
+                type="text"
+                size="small"
+                @click="editOne(scope.row)"
             >编辑
             </el-button>
             <el-button
-              size="small"
-              type="text"
-              @click="deleteAlert(scope.row.id)"
+                size="small"
+                type="text"
+                @click="deleteAlert(scope.row.id)"
             >删除
             </el-button>
           </template>
@@ -64,10 +64,10 @@
       <el-dialog title="编辑" :visible.sync="dialogFormVisible">
         <el-form :model="editNews">
           <el-form-item label="姓名" :label-width="formLabelWidth">
-            <el-input v-model="editNews.name" autocomplete="off" />
+            <el-input v-model="editNews.name" autocomplete="off"/>
           </el-form-item>
           <el-form-item label="Email" :label-width="formLabelWidth">
-            <el-input v-model="editNews.email" placeholder="" />
+            <el-input v-model="editNews.email" placeholder=""/>
           </el-form-item>
         </el-form>
         <div slot="footer" class="dialog-footer">
@@ -78,10 +78,10 @@
 
       <!--删除提示-->
       <el-dialog
-        title="提示"
-        :visible.sync="dialogVisible"
-        width="30%"
-        :before-close="handleClose"
+          title="提示"
+          :visible.sync="dialogVisible"
+          width="30%"
+          :before-close="handleClose"
       >
         <span>真的要删吗?</span>
         <div slot="footer" class="dialog-footer">
@@ -93,13 +93,13 @@
       <!--分页-->
       <div class="block">
         <el-pagination
-          :current-page="param.page"
-          :page-sizes="[10, 20, 30, 40]"
-          :page-size="param.size"
-          layout="total, sizes, prev, pager, next, jumper"
-          :total="total"
-          @size-change="handleSizeChange"
-          @current-change="handleCurrentChange"
+            :current-page="param.page"
+            :page-sizes="[10, 20, 30, 40]"
+            :page-size="param.size"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
         />
       </div>
     </template>
@@ -107,7 +107,8 @@
 </template>
 
 <script>
-import { deleteOne, fetchList, fetchOne, saveOne } from '@/api/table1'
+import {deleteOne, fetchList, fetchOne, saveOne} from '@/api/table1'
+
 export default {
   name: 'Table1',
   data() {
@@ -181,11 +182,11 @@ export default {
     // 关闭提示框时,提示是否要关闭
     handleClose(done) {
       this.$confirm('确认关闭?')
-        .then(() => {
-          done()
-        })
-        .catch(() => {
-        })
+          .then(() => {
+            done()
+          })
+          .catch(() => {
+          })
     },
     // 点击添加按钮清空
     createOne() {

+ 3 - 3
element-demo/tests/unit/.eslintrc.js

@@ -1,5 +1,5 @@
 module.exports = {
-  env: {
-    jest: true
-  }
+    env: {
+        jest: true
+    }
 }

+ 80 - 80
element-demo/tests/unit/components/Breadcrumb.spec.js

@@ -1,4 +1,4 @@
-import { mount, createLocalVue } from '@vue/test-utils'
+import {mount, createLocalVue} from '@vue/test-utils'
 import VueRouter from 'vue-router'
 import ElementUI from 'element-ui'
 import Breadcrumb from '@/components/Breadcrumb/index.vue'
@@ -8,91 +8,91 @@ localVue.use(VueRouter)
 localVue.use(ElementUI)
 
 const routes = [
-  {
-    path: '/',
-    name: 'home',
-    children: [{
-      path: 'dashboard',
-      name: 'dashboard'
-    }]
-  },
-  {
-    path: '/menu',
-    name: 'menu',
-    children: [{
-      path: 'menu1',
-      name: 'menu1',
-      meta: { title: 'menu1' },
-      children: [{
-        path: 'menu1-1',
-        name: 'menu1-1',
-        meta: { title: 'menu1-1' }
-      },
-      {
-        path: 'menu1-2',
-        name: 'menu1-2',
-        redirect: 'noredirect',
-        meta: { title: 'menu1-2' },
+    {
+        path: '/',
+        name: 'home',
+        children: [{
+            path: 'dashboard',
+            name: 'dashboard'
+        }]
+    },
+    {
+        path: '/menu',
+        name: 'menu',
         children: [{
-          path: 'menu1-2-1',
-          name: 'menu1-2-1',
-          meta: { title: 'menu1-2-1' }
-        },
-        {
-          path: 'menu1-2-2',
-          name: 'menu1-2-2'
+            path: 'menu1',
+            name: 'menu1',
+            meta: {title: 'menu1'},
+            children: [{
+                path: 'menu1-1',
+                name: 'menu1-1',
+                meta: {title: 'menu1-1'}
+            },
+                {
+                    path: 'menu1-2',
+                    name: 'menu1-2',
+                    redirect: 'noredirect',
+                    meta: {title: 'menu1-2'},
+                    children: [{
+                        path: 'menu1-2-1',
+                        name: 'menu1-2-1',
+                        meta: {title: 'menu1-2-1'}
+                    },
+                        {
+                            path: 'menu1-2-2',
+                            name: 'menu1-2-2'
+                        }]
+                }]
         }]
-      }]
     }]
-  }]
 
 const router = new VueRouter({
-  routes
+    routes
 })
 
 describe('Breadcrumb.vue', () => {
-  const wrapper = mount(Breadcrumb, {
-    localVue,
-    router
-  })
-  it('dashboard', () => {
-    router.push('/dashboard')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(1)
-  })
-  it('normal route', () => {
-    router.push('/menu/menu1')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(2)
-  })
-  it('nested route', () => {
-    router.push('/menu/menu1/menu1-2/menu1-2-1')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(4)
-  })
-  it('no meta.title', () => {
-    router.push('/menu/menu1/menu1-2/menu1-2-2')
-    const len = wrapper.findAll('.el-breadcrumb__inner').length
-    expect(len).toBe(3)
-  })
-  // it('click link', () => {
-  //   router.push('/menu/menu1/menu1-2/menu1-2-2')
-  //   const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
-  //   const second = breadcrumbArray.at(1)
-  //   console.log(breadcrumbArray)
-  //   const href = second.find('a').attributes().href
-  //   expect(href).toBe('#/menu/menu1')
-  // })
-  // it('noRedirect', () => {
-  //   router.push('/menu/menu1/menu1-2/menu1-2-1')
-  //   const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
-  //   const redirectBreadcrumb = breadcrumbArray.at(2)
-  //   expect(redirectBreadcrumb.contains('a')).toBe(false)
-  // })
-  it('last breadcrumb', () => {
-    router.push('/menu/menu1/menu1-2/menu1-2-1')
-    const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
-    const redirectBreadcrumb = breadcrumbArray.at(3)
-    expect(redirectBreadcrumb.contains('a')).toBe(false)
-  })
+    const wrapper = mount(Breadcrumb, {
+        localVue,
+        router
+    })
+    it('dashboard', () => {
+        router.push('/dashboard')
+        const len = wrapper.findAll('.el-breadcrumb__inner').length
+        expect(len).toBe(1)
+    })
+    it('normal route', () => {
+        router.push('/menu/menu1')
+        const len = wrapper.findAll('.el-breadcrumb__inner').length
+        expect(len).toBe(2)
+    })
+    it('nested route', () => {
+        router.push('/menu/menu1/menu1-2/menu1-2-1')
+        const len = wrapper.findAll('.el-breadcrumb__inner').length
+        expect(len).toBe(4)
+    })
+    it('no meta.title', () => {
+        router.push('/menu/menu1/menu1-2/menu1-2-2')
+        const len = wrapper.findAll('.el-breadcrumb__inner').length
+        expect(len).toBe(3)
+    })
+    // it('click link', () => {
+    //   router.push('/menu/menu1/menu1-2/menu1-2-2')
+    //   const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
+    //   const second = breadcrumbArray.at(1)
+    //   console.log(breadcrumbArray)
+    //   const href = second.find('a').attributes().href
+    //   expect(href).toBe('#/menu/menu1')
+    // })
+    // it('noRedirect', () => {
+    //   router.push('/menu/menu1/menu1-2/menu1-2-1')
+    //   const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
+    //   const redirectBreadcrumb = breadcrumbArray.at(2)
+    //   expect(redirectBreadcrumb.contains('a')).toBe(false)
+    // })
+    it('last breadcrumb', () => {
+        router.push('/menu/menu1/menu1-2/menu1-2-1')
+        const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
+        const redirectBreadcrumb = breadcrumbArray.at(3)
+        expect(redirectBreadcrumb.contains('a')).toBe(false)
+    })
 })

+ 16 - 15
element-demo/tests/unit/components/Hamburger.spec.js

@@ -1,18 +1,19 @@
-import { shallowMount } from '@vue/test-utils'
+import {shallowMount} from '@vue/test-utils'
 import Hamburger from '@/components/Hamburger/index.vue'
+
 describe('Hamburger.vue', () => {
-  it('toggle click', () => {
-    const wrapper = shallowMount(Hamburger)
-    const mockFn = jest.fn()
-    wrapper.vm.$on('toggleClick', mockFn)
-    wrapper.find('.hamburger').trigger('click')
-    expect(mockFn).toBeCalled()
-  })
-  it('prop isActive', () => {
-    const wrapper = shallowMount(Hamburger)
-    wrapper.setProps({ isActive: true })
-    expect(wrapper.contains('.is-active')).toBe(true)
-    wrapper.setProps({ isActive: false })
-    expect(wrapper.contains('.is-active')).toBe(false)
-  })
+    it('toggle click', () => {
+        const wrapper = shallowMount(Hamburger)
+        const mockFn = jest.fn()
+        wrapper.vm.$on('toggleClick', mockFn)
+        wrapper.find('.hamburger').trigger('click')
+        expect(mockFn).toBeCalled()
+    })
+    it('prop isActive', () => {
+        const wrapper = shallowMount(Hamburger)
+        wrapper.setProps({isActive: true})
+        expect(wrapper.contains('.is-active')).toBe(true)
+        wrapper.setProps({isActive: false})
+        expect(wrapper.contains('.is-active')).toBe(false)
+    })
 })

+ 18 - 17
element-demo/tests/unit/components/SvgIcon.spec.js

@@ -1,22 +1,23 @@
-import { shallowMount } from '@vue/test-utils'
+import {shallowMount} from '@vue/test-utils'
 import SvgIcon from '@/components/SvgIcon/index.vue'
+
 describe('SvgIcon.vue', () => {
-  it('iconClass', () => {
-    const wrapper = shallowMount(SvgIcon, {
-      propsData: {
-        iconClass: 'test'
-      }
+    it('iconClass', () => {
+        const wrapper = shallowMount(SvgIcon, {
+            propsData: {
+                iconClass: 'test'
+            }
+        })
+        expect(wrapper.find('use').attributes().href).toBe('#icon-test')
     })
-    expect(wrapper.find('use').attributes().href).toBe('#icon-test')
-  })
-  it('className', () => {
-    const wrapper = shallowMount(SvgIcon, {
-      propsData: {
-        iconClass: 'test'
-      }
+    it('className', () => {
+        const wrapper = shallowMount(SvgIcon, {
+            propsData: {
+                iconClass: 'test'
+            }
+        })
+        expect(wrapper.classes().length).toBe(1)
+        wrapper.setProps({className: 'test'})
+        expect(wrapper.classes().includes('test')).toBe(true)
     })
-    expect(wrapper.classes().length).toBe(1)
-    wrapper.setProps({ className: 'test' })
-    expect(wrapper.classes().includes('test')).toBe(true)
-  })
 })

+ 26 - 26
element-demo/tests/unit/utils/formatTime.spec.js

@@ -1,30 +1,30 @@
-import { formatTime } from '@/utils/index.js'
+import {formatTime} from '@/utils/index.js'
 
 describe('Utils:formatTime', () => {
-  const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
-  const retrofit = 5 * 1000
+    const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
+    const retrofit = 5 * 1000
 
-  it('ten digits timestamp', () => {
-    expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分')
-  })
-  it('test now', () => {
-    expect(formatTime(+new Date() - 1)).toBe('刚刚')
-  })
-  it('less two minute', () => {
-    expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前')
-  })
-  it('less two hour', () => {
-    expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前')
-  })
-  it('less one day', () => {
-    expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前')
-  })
-  it('more than one day', () => {
-    expect(formatTime(d)).toBe('7月13日17时54分')
-  })
-  it('format', () => {
-    expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
-    expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
-    expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
-  })
+    it('ten digits timestamp', () => {
+        expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分')
+    })
+    it('test now', () => {
+        expect(formatTime(+new Date() - 1)).toBe('刚刚')
+    })
+    it('less two minute', () => {
+        expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前')
+    })
+    it('less two hour', () => {
+        expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前')
+    })
+    it('less one day', () => {
+        expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前')
+    })
+    it('more than one day', () => {
+        expect(formatTime(d)).toBe('7月13日17时54分')
+    })
+    it('format', () => {
+        expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
+        expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
+        expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
+    })
 })

+ 11 - 10
element-demo/tests/unit/utils/param2Obj.spec.js

@@ -1,14 +1,15 @@
-import { param2Obj } from '@/utils/index.js'
+import {param2Obj} from '@/utils/index.js'
+
 describe('Utils:param2Obj', () => {
-  const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95'
+    const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95'
 
-  it('param2Obj test', () => {
-    expect(param2Obj(url)).toEqual({
-      name: 'bill',
-      age: '29',
-      sex: '1',
-      field: window.btoa('test'),
-      key: '测试'
+    it('param2Obj test', () => {
+        expect(param2Obj(url)).toEqual({
+            name: 'bill',
+            age: '29',
+            sex: '1',
+            field: window.btoa('test'),
+            key: '测试'
+        })
     })
-  })
 })

+ 31 - 31
element-demo/tests/unit/utils/parseTime.spec.js

@@ -1,35 +1,35 @@
-import { parseTime } from '@/utils/index.js'
+import {parseTime} from '@/utils/index.js'
 
 describe('Utils:parseTime', () => {
-  const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
-  it('timestamp', () => {
-    expect(parseTime(d)).toBe('2018-07-13 17:54:01')
-  })
-  it('timestamp string', () => {
-    expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01')
-  })
-  it('ten digits timestamp', () => {
-    expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01')
-  })
-  it('new Date', () => {
-    expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01')
-  })
-  it('format', () => {
-    expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
-    expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
-    expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
-  })
-  it('get the day of the week', () => {
-    expect(parseTime(d, '{a}')).toBe('五') // 星期五
-  })
-  it('get the day of the week', () => {
-    expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日
-  })
-  it('empty argument', () => {
-    expect(parseTime()).toBeNull()
-  })
+    const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
+    it('timestamp', () => {
+        expect(parseTime(d)).toBe('2018-07-13 17:54:01')
+    })
+    it('timestamp string', () => {
+        expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01')
+    })
+    it('ten digits timestamp', () => {
+        expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01')
+    })
+    it('new Date', () => {
+        expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01')
+    })
+    it('format', () => {
+        expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
+        expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
+        expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
+    })
+    it('get the day of the week', () => {
+        expect(parseTime(d, '{a}')).toBe('五') // 星期五
+    })
+    it('get the day of the week', () => {
+        expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日
+    })
+    it('empty argument', () => {
+        expect(parseTime()).toBeNull()
+    })
 
-  it('null', () => {
-    expect(parseTime(null)).toBeNull()
-  })
+    it('null', () => {
+        expect(parseTime(null)).toBeNull()
+    })
 })

+ 14 - 14
element-demo/tests/unit/utils/validate.spec.js

@@ -1,17 +1,17 @@
-import { validUsername, isExternal } from '@/utils/validate.js'
+import {validUsername, isExternal} from '@/utils/validate.js'
 
 describe('Utils:validate', () => {
-  it('validUsername', () => {
-    expect(validUsername('admin')).toBe(true)
-    expect(validUsername('editor')).toBe(true)
-    expect(validUsername('xxxx')).toBe(false)
-  })
-  it('isExternal', () => {
-    expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true)
-    expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true)
-    expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false)
-    expect(isExternal('/dashboard')).toBe(false)
-    expect(isExternal('./dashboard')).toBe(false)
-    expect(isExternal('dashboard')).toBe(false)
-  })
+    it('validUsername', () => {
+        expect(validUsername('admin')).toBe(true)
+        expect(validUsername('editor')).toBe(true)
+        expect(validUsername('xxxx')).toBe(false)
+    })
+    it('isExternal', () => {
+        expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true)
+        expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true)
+        expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false)
+        expect(isExternal('/dashboard')).toBe(false)
+        expect(isExternal('./dashboard')).toBe(false)
+        expect(isExternal('dashboard')).toBe(false)
+    })
 })

+ 0 - 0
element-demo/tmp.js


+ 100 - 99
element-demo/vue.config.js

@@ -3,7 +3,7 @@ const path = require('path')
 const defaultSettings = require('./src/settings.js')
 
 function resolve(dir) {
-  return path.join(__dirname, dir)
+    return path.join(__dirname, dir)
 }
 
 const name = defaultSettings.title || 'vue Admin Template' // page title
@@ -17,107 +17,108 @@ const port = process.env.port || process.env.npm_config_port || 9528 // dev port
 
 // All configuration item explanations can be find in https://cli.vuejs.org/config/
 module.exports = {
-  /**
-   * You will need to set publicPath if you plan to deploy your site under a sub path,
-   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
-   * then publicPath should be set to "/bar/".
-   * In most cases please use '/' !!!
-   * Detail: https://cli.vuejs.org/config/#publicpath
-   */
-  publicPath: '/',
-  outputDir: 'dist',
-  assetsDir: 'static',
-  lintOnSave: process.env.NODE_ENV === 'development',
-  productionSourceMap: false,
-  devServer: {
-    port: port,
-    open: true,
-    overlay: {
-      warnings: false,
-      errors: true
+    /**
+     * You will need to set publicPath if you plan to deploy your site under a sub path,
+     * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
+     * then publicPath should be set to "/bar/".
+     * In most cases please use '/' !!!
+     * Detail: https://cli.vuejs.org/config/#publicpath
+     */
+    publicPath: '/',
+    outputDir: 'dist',
+    assetsDir: 'static',
+    lintOnSave: false,
+    // lintOnSave: process.env.NODE_ENV === 'development',
+    productionSourceMap: false,
+    devServer: {
+        port: port,
+        open: true,
+        overlay: {
+            warnings: false,
+            errors: true
+        },
+        before: require('./mock/mock-server.js')
     },
-    before: require('./mock/mock-server.js')
-  },
-  configureWebpack: {
-    // provide the app's title in webpack's name field, so that
-    // it can be accessed in index.html to inject the correct title.
-    name: name,
-    resolve: {
-      alias: {
-        '@': resolve('src')
-      }
-    }
-  },
-  chainWebpack(config) {
-    // it can improve the speed of the first screen, it is recommended to turn on preload
-    config.plugin('preload').tap(() => [
-      {
-        rel: 'preload',
-        // to ignore runtime.js
-        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
-        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
-        include: 'initial'
-      }
-    ])
-
-    // when there are many pages, it will cause too many meaningless requests
-    config.plugins.delete('prefetch')
+    configureWebpack: {
+        // provide the app's title in webpack's name field, so that
+        // it can be accessed in index.html to inject the correct title.
+        name: name,
+        resolve: {
+            alias: {
+                '@': resolve('src')
+            }
+        }
+    },
+    chainWebpack(config) {
+        // it can improve the speed of the first screen, it is recommended to turn on preload
+        config.plugin('preload').tap(() => [
+            {
+                rel: 'preload',
+                // to ignore runtime.js
+                // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
+                fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
+                include: 'initial'
+            }
+        ])
 
-    // set svg-sprite-loader
-    config.module
-      .rule('svg')
-      .exclude.add(resolve('src/icons'))
-      .end()
-    config.module
-      .rule('icons')
-      .test(/\.svg$/)
-      .include.add(resolve('src/icons'))
-      .end()
-      .use('svg-sprite-loader')
-      .loader('svg-sprite-loader')
-      .options({
-        symbolId: 'icon-[name]'
-      })
-      .end()
+        // when there are many pages, it will cause too many meaningless requests
+        config.plugins.delete('prefetch')
 
-    config
-      .when(process.env.NODE_ENV !== 'development',
-        config => {
-          config
-            .plugin('ScriptExtHtmlWebpackPlugin')
-            .after('html')
-            .use('script-ext-html-webpack-plugin', [{
-            // `runtime` must same as runtimeChunk name. default is `runtime`
-              inline: /runtime\..*\.js$/
-            }])
+        // set svg-sprite-loader
+        config.module
+            .rule('svg')
+            .exclude.add(resolve('src/icons'))
             .end()
-          config
-            .optimization.splitChunks({
-              chunks: 'all',
-              cacheGroups: {
-                libs: {
-                  name: 'chunk-libs',
-                  test: /[\\/]node_modules[\\/]/,
-                  priority: 10,
-                  chunks: 'initial' // only package third parties that are initially dependent
-                },
-                elementUI: {
-                  name: 'chunk-elementUI', // split elementUI into a single package
-                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
-                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
-                },
-                commons: {
-                  name: 'chunk-commons',
-                  test: resolve('src/components'), // can customize your rules
-                  minChunks: 3, //  minimum common number
-                  priority: 5,
-                  reuseExistingChunk: true
-                }
-              }
+        config.module
+            .rule('icons')
+            .test(/\.svg$/)
+            .include.add(resolve('src/icons'))
+            .end()
+            .use('svg-sprite-loader')
+            .loader('svg-sprite-loader')
+            .options({
+                symbolId: 'icon-[name]'
             })
-          // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
-          config.optimization.runtimeChunk('single')
-        }
-      )
-  }
+            .end()
+
+        config
+            .when(process.env.NODE_ENV !== 'development',
+                config => {
+                    config
+                        .plugin('ScriptExtHtmlWebpackPlugin')
+                        .after('html')
+                        .use('script-ext-html-webpack-plugin', [{
+                            // `runtime` must same as runtimeChunk name. default is `runtime`
+                            inline: /runtime\..*\.js$/
+                        }])
+                        .end()
+                    config
+                        .optimization.splitChunks({
+                        chunks: 'all',
+                        cacheGroups: {
+                            libs: {
+                                name: 'chunk-libs',
+                                test: /[\\/]node_modules[\\/]/,
+                                priority: 10,
+                                chunks: 'initial' // only package third parties that are initially dependent
+                            },
+                            elementUI: {
+                                name: 'chunk-elementUI', // split elementUI into a single package
+                                priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
+                                test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
+                            },
+                            commons: {
+                                name: 'chunk-commons',
+                                test: resolve('src/components'), // can customize your rules
+                                minChunks: 3, //  minimum common number
+                                priority: 5,
+                                reuseExistingChunk: true
+                            }
+                        }
+                    })
+                    // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
+                    config.optimization.runtimeChunk('single')
+                }
+            )
+    }
 }

+ 0 - 9
layui-demo/layui-demo.iml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="WEB_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 0 - 0
layui-demo/tmp.js


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff