diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index b4050098993..00000000000
--- a/.babelrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "presets": [
- ["env", { "modules": false }],
- "stage-2"
- ],
- "plugins": ["transform-runtime"],
- "comments": false
-}
diff --git a/.editorconfig b/.editorconfig
index ea6e20f5b2e..3454886e3a5 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,4 +1,4 @@
-# http://editorconfig.org
+# https://editorconfig.org
root = true
[*]
diff --git a/.env.development b/.env.development
new file mode 100644
index 00000000000..de583d0940d
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,5 @@
+# just a flag
+ENV = 'development'
+
+# base api
+VUE_APP_BASE_API = '/dev-api'
diff --git a/.env.production b/.env.production
new file mode 100644
index 00000000000..80c810301f3
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,6 @@
+# just a flag
+ENV = 'production'
+
+# base api
+VUE_APP_BASE_API = '/prod-api'
+
diff --git a/.env.staging b/.env.staging
new file mode 100644
index 00000000000..a8793a09891
--- /dev/null
+++ b/.env.staging
@@ -0,0 +1,8 @@
+NODE_ENV = production
+
+# just a flag
+ENV = 'staging'
+
+# base api
+VUE_APP_BASE_API = '/stage-api'
+
diff --git a/.eslintignore b/.eslintignore
index e3a4037e479..e6529fc09c9 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,3 +1,4 @@
build/*.js
-config/*.js
src/assets
+public
+dist
diff --git a/.eslintrc.js b/.eslintrc.js
index 006e9824d78..c977505478d 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,144 +1,198 @@
module.exports = {
- root: true,
+ root: true,
+ parserOptions: {
parser: 'babel-eslint',
- parserOptions: {
- sourceType: 'module'
- },
- env: {
- browser: true,
- node: true,
- es6: true,
- },
- extends: 'eslint:recommended',
- // required to lint *.vue files
- plugins: [
- 'html'
- ],
- // check if imports actually resolve
- 'settings': {
- 'import/resolver': {
- 'webpack': {
- 'config': 'build/webpack.base.conf.js'
- }
- }
- },
- // add your custom rules here
- //it is base on https://github.com/vuejs/eslint-config-vue
- 'rules': {
- 'accessor-pairs': 2,
- 'arrow-spacing': [2, { 'before': true, 'after': true }],
- 'block-spacing': [2, 'always'],
- 'brace-style': [2, '1tbs', { 'allowSingleLine': true }],
- 'camelcase': [0, { 'properties': 'always' }],
- 'comma-dangle': [2, 'never'],
- 'comma-spacing': [2, { 'before': false, 'after': true }],
- 'comma-style': [2, 'last'],
- 'constructor-super': 2,
- 'curly': [2, 'multi-line'],
- 'dot-location': [2, 'property'],
- 'eol-last': 2,
- 'eqeqeq': [2, 'allow-null'],
- 'generator-star-spacing': [2, { 'before': true, 'after': true }],
- 'handle-callback-err': [2, '^(err|error)$' ],
- 'indent': [2, 2, { 'SwitchCase': 1 }],
- 'jsx-quotes': [2, 'prefer-single'],
- 'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
- 'keyword-spacing': [2, { 'before': true, 'after': true }],
- 'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
- 'new-parens': 2,
- 'no-array-constructor': 2,
- 'no-caller': 2,
- 'no-console': 'off',
- 'no-class-assign': 2,
- 'no-cond-assign': 2,
- 'no-const-assign': 2,
- 'no-control-regex': 2,
- 'no-delete-var': 2,
- 'no-dupe-args': 2,
- 'no-dupe-class-members': 2,
- 'no-dupe-keys': 2,
- 'no-duplicate-case': 2,
- 'no-empty-character-class': 2,
- 'no-empty-pattern': 2,
- 'no-eval': 2,
- 'no-ex-assign': 2,
- 'no-extend-native': 2,
- 'no-extra-bind': 2,
- 'no-extra-boolean-cast': 2,
- 'no-extra-parens': [2, 'functions'],
- 'no-fallthrough': 2,
- 'no-floating-decimal': 2,
- 'no-func-assign': 2,
- 'no-implied-eval': 2,
- 'no-inner-declarations': [2, 'functions'],
- 'no-invalid-regexp': 2,
- 'no-irregular-whitespace': 2,
- 'no-iterator': 2,
- 'no-label-var': 2,
- 'no-labels': [2, { 'allowLoop': false, 'allowSwitch': false }],
- 'no-lone-blocks': 2,
- 'no-mixed-spaces-and-tabs': 2,
- 'no-multi-spaces': 2,
- 'no-multi-str': 2,
- 'no-multiple-empty-lines': [2, { 'max': 1 }],
- 'no-native-reassign': 2,
- 'no-negated-in-lhs': 2,
- 'no-new-object': 2,
- 'no-new-require': 2,
- 'no-new-symbol': 2,
- 'no-new-wrappers': 2,
- 'no-obj-calls': 2,
- 'no-octal': 2,
- 'no-octal-escape': 2,
- 'no-path-concat': 2,
- 'no-proto': 2,
- 'no-redeclare': 2,
- 'no-regex-spaces': 2,
- 'no-return-assign': [2, 'except-parens'],
- 'no-self-assign': 2,
- 'no-self-compare': 2,
- 'no-sequences': 2,
- 'no-shadow-restricted-names': 2,
- 'no-spaced-func': 2,
- 'no-sparse-arrays': 2,
- 'no-this-before-super': 2,
- 'no-throw-literal': 2,
- 'no-trailing-spaces': 2,
- 'no-undef': 2,
- 'no-undef-init': 2,
- 'no-unexpected-multiline': 2,
- 'no-unmodified-loop-condition': 2,
- 'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
- 'no-unreachable': 2,
- 'no-unsafe-finally': 2,
- 'no-unused-vars': [2, { 'vars': 'all', 'args': 'none' }],
- 'no-useless-call': 2,
- 'no-useless-computed-key': 2,
- 'no-useless-constructor': 2,
- 'no-useless-escape': 0,
- 'no-whitespace-before-property': 2,
- 'no-with': 2,
- 'one-var': [2, { 'initialized': 'never' }],
- 'operator-linebreak': [2, 'after', { 'overrides': { '?': 'before', ':': 'before' } }],
- 'padded-blocks': [2, 'never'],
- 'quotes': [2, 'single', { 'avoidEscape': true, 'allowTemplateLiterals': true }],
- 'semi': [2, 'never'],
- 'semi-spacing': [2, { 'before': false, 'after': true }],
- 'space-before-blocks': [2, 'always'],
- 'space-before-function-paren': [2, 'never'],
- 'space-in-parens': [2, 'never'],
- 'space-infix-ops': 2,
- 'space-unary-ops': [2, { 'words': true, 'nonwords': false }],
- 'spaced-comment': [2, 'always', { 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] }],
- 'template-curly-spacing': [2, 'never'],
- 'use-isnan': 2,
- 'valid-typeof': 2,
- 'wrap-iife': [2, 'any'],
- 'yield-star-spacing': [2, 'both'],
- 'yoda': [2, 'never'],
- 'prefer-const': 2,
- 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
- 'object-curly-spacing': [2, 'always', { objectsInObjects: false }],
- 'array-bracket-spacing': [2, 'never']
- }
+ sourceType: 'module'
+ },
+ env: {
+ browser: true,
+ node: true,
+ es6: true,
+ },
+ extends: ['plugin:vue/recommended', 'eslint:recommended'],
+
+ // add your custom rules here
+ //it is base on https://github.com/vuejs/eslint-config-vue
+ rules: {
+ "vue/max-attributes-per-line": [2, {
+ "singleline": 10,
+ "multiline": {
+ "max": 1,
+ "allowFirstLine": false
+ }
+ }],
+ "vue/singleline-html-element-content-newline": "off",
+ "vue/multiline-html-element-content-newline":"off",
+ "vue/name-property-casing": ["error", "PascalCase"],
+ "vue/no-v-html": "off",
+ 'accessor-pairs': 2,
+ 'arrow-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'block-spacing': [2, 'always'],
+ 'brace-style': [2, '1tbs', {
+ 'allowSingleLine': true
+ }],
+ 'camelcase': [0, {
+ 'properties': 'always'
+ }],
+ 'comma-dangle': [2, 'never'],
+ 'comma-spacing': [2, {
+ 'before': false,
+ 'after': true
+ }],
+ 'comma-style': [2, 'last'],
+ 'constructor-super': 2,
+ 'curly': [2, 'multi-line'],
+ 'dot-location': [2, 'property'],
+ 'eol-last': 2,
+ 'eqeqeq': ["error", "always", {"null": "ignore"}],
+ 'generator-star-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'handle-callback-err': [2, '^(err|error)$'],
+ 'indent': [2, 2, {
+ 'SwitchCase': 1
+ }],
+ 'jsx-quotes': [2, 'prefer-single'],
+ 'key-spacing': [2, {
+ 'beforeColon': false,
+ 'afterColon': true
+ }],
+ 'keyword-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'new-cap': [2, {
+ 'newIsCap': true,
+ 'capIsNew': false
+ }],
+ 'new-parens': 2,
+ 'no-array-constructor': 2,
+ 'no-caller': 2,
+ 'no-console': 'off',
+ 'no-class-assign': 2,
+ 'no-cond-assign': 2,
+ 'no-const-assign': 2,
+ 'no-control-regex': 0,
+ 'no-delete-var': 2,
+ 'no-dupe-args': 2,
+ 'no-dupe-class-members': 2,
+ 'no-dupe-keys': 2,
+ 'no-duplicate-case': 2,
+ 'no-empty-character-class': 2,
+ 'no-empty-pattern': 2,
+ 'no-eval': 2,
+ 'no-ex-assign': 2,
+ 'no-extend-native': 2,
+ 'no-extra-bind': 2,
+ 'no-extra-boolean-cast': 2,
+ 'no-extra-parens': [2, 'functions'],
+ 'no-fallthrough': 2,
+ 'no-floating-decimal': 2,
+ 'no-func-assign': 2,
+ 'no-implied-eval': 2,
+ 'no-inner-declarations': [2, 'functions'],
+ 'no-invalid-regexp': 2,
+ 'no-irregular-whitespace': 2,
+ 'no-iterator': 2,
+ 'no-label-var': 2,
+ 'no-labels': [2, {
+ 'allowLoop': false,
+ 'allowSwitch': false
+ }],
+ 'no-lone-blocks': 2,
+ 'no-mixed-spaces-and-tabs': 2,
+ 'no-multi-spaces': 2,
+ 'no-multi-str': 2,
+ 'no-multiple-empty-lines': [2, {
+ 'max': 1
+ }],
+ 'no-native-reassign': 2,
+ 'no-negated-in-lhs': 2,
+ 'no-new-object': 2,
+ 'no-new-require': 2,
+ 'no-new-symbol': 2,
+ 'no-new-wrappers': 2,
+ 'no-obj-calls': 2,
+ 'no-octal': 2,
+ 'no-octal-escape': 2,
+ 'no-path-concat': 2,
+ 'no-proto': 2,
+ 'no-redeclare': 2,
+ 'no-regex-spaces': 2,
+ 'no-return-assign': [2, 'except-parens'],
+ 'no-self-assign': 2,
+ 'no-self-compare': 2,
+ 'no-sequences': 2,
+ 'no-shadow-restricted-names': 2,
+ 'no-spaced-func': 2,
+ 'no-sparse-arrays': 2,
+ 'no-this-before-super': 2,
+ 'no-throw-literal': 2,
+ 'no-trailing-spaces': 2,
+ 'no-undef': 2,
+ 'no-undef-init': 2,
+ 'no-unexpected-multiline': 2,
+ 'no-unmodified-loop-condition': 2,
+ 'no-unneeded-ternary': [2, {
+ 'defaultAssignment': false
+ }],
+ 'no-unreachable': 2,
+ 'no-unsafe-finally': 2,
+ 'no-unused-vars': [2, {
+ 'vars': 'all',
+ 'args': 'none'
+ }],
+ 'no-useless-call': 2,
+ 'no-useless-computed-key': 2,
+ 'no-useless-constructor': 2,
+ 'no-useless-escape': 0,
+ 'no-whitespace-before-property': 2,
+ 'no-with': 2,
+ 'one-var': [2, {
+ 'initialized': 'never'
+ }],
+ 'operator-linebreak': [2, 'after', {
+ 'overrides': {
+ '?': 'before',
+ ':': 'before'
+ }
+ }],
+ 'padded-blocks': [2, 'never'],
+ 'quotes': [2, 'single', {
+ 'avoidEscape': true,
+ 'allowTemplateLiterals': true
+ }],
+ 'semi': [2, 'never'],
+ 'semi-spacing': [2, {
+ 'before': false,
+ 'after': true
+ }],
+ 'space-before-blocks': [2, 'always'],
+ 'space-before-function-paren': [2, 'never'],
+ 'space-in-parens': [2, 'never'],
+ 'space-infix-ops': 2,
+ 'space-unary-ops': [2, {
+ 'words': true,
+ 'nonwords': false
+ }],
+ 'spaced-comment': [2, 'always', {
+ 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
+ }],
+ 'template-curly-spacing': [2, 'never'],
+ 'use-isnan': 2,
+ 'valid-typeof': 2,
+ 'wrap-iife': [2, 'any'],
+ 'yield-star-spacing': [2, 'both'],
+ 'yoda': [2, 'never'],
+ 'prefer-const': 2,
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+ 'object-curly-spacing': [2, 'always', {
+ objectsInObjects: false
+ }],
+ 'array-bracket-spacing': [2, 'never']
+ }
}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000000..d540802752b
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+patreon: panjiachen
+custom: https://panjiachen.github.io/vue-element-admin-site/donate
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100755
index 00000000000..1a114bc0044
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,33 @@
+---
+name: Bug report(报告问题)
+about: Create a report to help us improve
+---
+
+
+
+## Bug report(问题描述)
+
+#### Steps to reproduce(问题复现步骤)
+
+
+#### Screenshot or Gif(截图或动态图)
+
+
+#### Link to minimal reproduction(最小可在线还原demo)
+
+
+
+#### Other relevant information(格外信息)
+- Your OS:
+- Node.js version:
+- vue-element-admin version:
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100755
index 00000000000..c33d10d4621
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,7 @@
+---
+name: Feature Request(新功能建议)
+about: Suggest an idea for this project
+---
+
+## Feature request(新功能建议)
+
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100755
index 00000000000..76083546d30
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,35 @@
+---
+name: Question(提问)
+about: Asking questions about use
+---
+
+## Question(提问)
+
+
+
+#### Steps to reproduce(问题复现步骤)
+
+
+#### Screenshot or Gif(截图或动态图)
+
+
+#### Link to minimal reproduction(最小可在线还原demo)
+
+
+
+#### Other relevant information(格外信息)
+- Your OS:
+- Node.js version:
+- vue-element-admin version:
diff --git a/.gitignore b/.gitignore
index bb2a167e60e..78a752d87e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,23 @@
.DS_Store
node_modules/
dist/
-static/ckeditor
-gifs/
-npm-debug.log
-test/unit/coverage
-test/e2e/reports
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+**/*.log
+
+tests/**/coverage/
+tests/e2e/reports
selenium-debug.log
+
+# Editor directories and files
.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.local
+
package-lock.json
+yarn.lock
diff --git a/.postcssrc.js b/.postcssrc.js
deleted file mode 100644
index 09948d63e91..00000000000
--- a/.postcssrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// https://github.com/michael-ciniawsky/postcss-load-config
-
-module.exports = {
- "plugins": {
- // to edit target browsers: use "browserslist" field in package.json
- "autoprefixer": {}
- }
-}
diff --git a/.travis.yml b/.travis.yml
new file mode 100755
index 00000000000..f4be7a08559
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js: 10
+script: npm run test
+notifications:
+ email: false
diff --git a/LICENSE b/LICENSE
index b4bb0d9fbf9..61515750df8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2017 PanJiaChen
+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
diff --git a/README-en.md b/README-en.md
deleted file mode 100644
index 254591477bf..00000000000
--- a/README-en.md
+++ /dev/null
@@ -1,177 +0,0 @@
-[](https://github.com/vuejs/vue)
-[](https://github.com/ElemeFE/element)
-[](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
-[]()
-
-## Intro
-
-> In the past half year, I have been building a backend for management dashboard using Vue. Though the backend has contained greater than 70 pages and over 10 permissions, it still takes insignificant effort to maintain the project. So I decide to make it open source so as to share my development experience and progress on backend. The tech stack is mainly [Vue.js](https://github.com/vuejs/vue)+[Element](https://github.com/ElemeFE/element)+[axios](https://github.com/mzabriskie/axios). Since it's a personal project, all data requests are simulated with [Mock.js](https://github.com/nuysoft/Mock). **Note:** if anyone wants to modify or develop based on this project, please remove the mock files.
-
-**Live demo:** http://panjiachen.github.io/vue-element-admin
-
-**Note: element-ui@1.4.2 is used in the project, so vue 2.3.0+ is required.**
-
- - vueAdmin-template: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
- - electron-vue-admin: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- - Donate:[donate](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md#donate)
-
-## Features
-
-- Login/Logout
-- Permission authentication
-- Sidebar
-- Breadcrumb
-- Rich text editor
-- Markdown editor
-- JSON editor
-- Drag & drop list
-- SplitPane
-- Dropzone
-- Sticky
-- CountTo
-- ECharts
-- 401, 404 error page
-- Error log
-- Export Excel
-- Upload Excel
-- Export Zip
-- Table example
-- Interactive table example
-- Drag & drop table example
-- Form example
-- Multi-environments distribution
-- Dashboard
-- Two-factor authentication
-- Collapsing sidebar (support nested routes)
-- Mock data
-- cache tabs example
-- screenfull
-- markdown2html
-- views-tab
-- clipboard
-
-## Development
-
-```bash
-# Clone project
-git clone https://github.com/PanJiaChen/vue-element-admin.git
-
-# Install dependencies
-npm install
-
-# Or (not recommended for cnpm due to unknown bugs, use taobao mirror instead)
-npm install --registry=https://registry.npm.taobao.org
-
-# Run local dev server
-npm run dev
-```
-
-Visit in browser: http://localhost:9527
-
-## Distribution
-
-```bash
-# Build staged environment with webpack-bundle-analyzer
-npm run build:sit-preview
-
-# Build production environment
-npm run build:prod
-```
-
-## Directory structure
-
-```
-├── build // build
-├── config // config
-├── src // source code
-│ ├── api // all requests
-│ ├── assets // static resource like themes, fonts
-│ ├── components // global public components
-│ ├── directive // global directive
-│ ├── filters // global filters
-│ ├── mock // mock data
-│ ├── router // router
-│ ├── store // global status management
-│ ├── styles // global styles
-│ ├── utils // global public functions
-│ ├── view // view
-│ ├── App.vue // entry view
-│ └── main.js // entry for loading components, initialization
-├── static // third-party libraries not packed with Webpack
-│ └── Tinymce // rich text
-├── .babelrc // babel-loader config
-├── eslintrc.js // eslint config
-├── .gitignore // gitignore
-├── favicon.ico // favicon
-├── index.html // html template
-└── package.json // package.json
-```
-
-## Changelog
-Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
-
-## Donate
-If you find this project useful, you can buy me a cup of coffee
-
-
-## State Management
-
-Only status of user and app configuration is managed by Vuex. Other data are managed by their own business pages.
-
-## Demo
-
-#### Two-factor authentication, supporting WeChat and QQ
-
-
-
-#### Realtime switching themes
-
-
-
-#### tabs
-
-
-
-#### Collapsing sidebar
-
-
-
-#### Drag & drop table
-
-
-
-#### Interactive table
-
-
-
-#### Uploading cropped avatar
-
-
-
-#### Error log
-
-
-
-#### Rich text (integrated with Qiniu, watermark and customization)
-
-
-
-#### Packaging table component
-
-
-
-#### Charts
-
-
-
-#### Exporting to Excel
-
-
-
-#### More
-
-http://panjiachen.github.io/vue-element-admin
-
-## License
-
-MIT
diff --git a/README.es.md b/README.es.md
new file mode 100644
index 00000000000..dc20fa42124
--- /dev/null
+++ b/README.es.md
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Español | [English](./README.md) | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md)
+
+## Introducción
+
+[vue-element-admin](https://panjiachen.github.io/vue-element-admin) es una interfáz de administración preparada para producción. Está basada en [vue](https://github.com/vuejs/vue) y usa [element-ui](https://github.com/ElemeFE/element) como conjunto de herramientas de interfáz de usuario.
+
+Vue Element Admin es una solución práctica basada en la nueva plataforma de desarrollo de vue, construida con soporte a i18 para el manejo de múltiples lenguajes, plantillas estándares para aplicaciones de negocio y un conjunto de asombrosas características. Esta herramienta ayuda a construir largas y complejas Aplicacones de una sola página (SPA). Creo que lo que necesites hacer, este proyecto te ayudará.
+
+- [Vista Prévia de la Aplicación](https://panjiachen.github.io/vue-element-admin)
+
+- [Documentación](https://panjiachen.github.io/vue-element-admin-site/)
+
+- [Canal de Gitter](https://gitter.im/vue-element-admin/discuss)
+
+- [Para Donaciones](https://panjiachen.github.io/vue-element-admin-site/donate/)
+
+- [Enlace de Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
+
+- [Canal de Gitee](https://panjiachen.gitee.io/vue-element-admin/)
+
+- Plantilla base recomendada para usar: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
+- Aplicación de Escritorio: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+- Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour))
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+**Después de la versión `v4.1.0+`, la rama por defecto master no tendrá soporte para i18n. Por favor utilice la rama [i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), los cambios serán incluidos en la rama master**
+
+**la versión actual es `v4.0+` construida con `vue-cli`. Si encuentra algún problema, por favor coloque un [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). Si desea usar la versión anterior, puede cambiar de rama a [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), no relacionado con `vue-cli`**
+
+**Este proyecto no está soportado para versiones antigüas de navegadores (ej. IE).**
+
+## Preparación
+
+Necesita instalar [node](https://nodejs.org/) y [git](https://git-scm.com/) localmente. El proyecto es basado en [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), toda la solicitud de datos simulada se realiza a través de [Mock.js](https://github.com/nuysoft/Mock).
+Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto.
+
+[](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
+
+
+
+
+
+## Patrocinantes
+
+Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un enlace directo a su sitio web. [[Se un Patrocinante]](https://www.patreon.com/panjiachen)
+
+### Akveo
+
Get Java backend for Vue admin with 20% discount for 39$ use coupon code SWB0RAZPZR1M
+
+
+### Flatlogic
+
+
Admin Dashboard Templates made with Vue, React and Angular.
+
+## Características
+
+```
+- Iniciar / Cerrar Sesión
+
+- Permisos de Autenticación
+ - Página de Permisos
+ - Directivas de permisos
+ - Página de configuración de permisos
+ - Autenticación por dos pasos
+
+- Construcción Multi-entorno
+ - Desarrollo (dev)
+ - sit
+ - Escenario de pruebas (stage),
+ - Producción (prod)
+
+- Características Globales
+ - I18n
+ - Temas dinámicos
+ - Menu lateral dinámico (soporte a rutas multi-nivel)
+ - Barra de rutas dinámica
+ - Tags-view (Pestañas de página, Soporta operación de clic derecho)
+ - Svg Sprite
+ - Datos de simulación con Mock
+ - Pantalla completa
+ - Menu lateral responsivo
+
+- Editor
+ - Editor de Texto Enriquecido
+ - Editor Markdown
+ - Editor JSON
+
+- Excel
+ - Exportación a Excel
+ - Carga de Excel
+ - Visualización de Excel
+ - Exportación como ZIP
+
+- Tabla
+ - Tabla Dinámica
+ - Tabla con Arrastrar y Soltar
+ - Tabla de edición en línea
+
+- Páginas de Error
+ - 401
+ - 404
+
+- Componentes
+ - Carga de Avatar
+ - Botón para subir al inicio
+ - Arrastrar y Soltar (Diaglogo)
+ - Arrastrar y Soltar (Seleccionar)
+ - Arrastrar y Soltar (Kanban)
+ - Arrastrar y Soltar (Lista)
+ - Panel de división
+ - Componente para soltar archivos
+ - Adhesión de objetos
+ - Contador hasta
+
+- Ejemplo Avanzado
+- Registro de Errores
+- Tablero de indicadores
+- Página de Guías
+- ECharts (Gráficos)
+- Portapapeles
+- Convertidor de Markdown a HTML
+```
+
+## Iniciando
+
+```bash
+# clone el proyecto
+git clone https://github.com/PanJiaChen/vue-element-admin.git
+
+# vaya al directorio clonado
+cd vue-element-admin
+
+# instale las dependencias
+npm install
+
+# corra el proyecto como desarrollador
+npm run dev
+```
+
+Automáticamente se abrirá el siguiente enlace en su navegador http://localhost:9527
+
+## Construcción
+
+```bash
+# Construcción para entornos de prueba
+npm run build:stage
+
+# Construcción para entornos de producción
+npm run build:prod
+```
+
+## Avanzado
+
+```bash
+# Vista previa con efectos de entorno
+npm run preview
+
+# Vista previa con efectos + análisis de recursos estáticos
+npm run preview -- --report
+
+# Chequeo de formato de código
+npm run lint
+
+# Chequeo de formato de código y auto-corrección
+npm run lint -- --fix
+```
+
+Vaya a [Documentación](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) para mayor información
+
+## Registro de Cambios
+
+Los cambios detallados por cada liberación se encuentran en [notas de liberación](https://github.com/PanJiaChen/vue-element-admin/releases).
+
+## Demostración en línea
+
+[Vista Prévia de la Aplicación](https://panjiachen.github.io/vue-element-admin)
+
+## Donación
+
+Si este proyecto es de mucha ayuda para ti, puedes comprarle al autor un vaso de jugo :tropical_drink:
+
+
+
+[dona por Paypal](https://www.paypal.me/panfree23)
+
+[Comprame un Café](https://www.buymeacoffee.com/Pan)
+
+## Navegadores Soportados
+
+Navegadores modernos e Internet Explorer 10+.
+
+| [
](https://godban.github.io/browsers-support-badges/)IE / Edge | [
](https://godban.github.io/browsers-support-badges/)Firefox | [
](https://godban.github.io/browsers-support-badges/)Chrome | [
](https://godban.github.io/browsers-support-badges/)Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge | últimas 2 versiones | últimas 2 versiones | últimas 2 versiones |
+
+## Licencia
+
+[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
+
+Copyright (c) 2017-presente PanJiaChen
diff --git a/README.ja.md b/README.ja.md
new file mode 100644
index 00000000000..3bc3ce8bf0f
--- /dev/null
+++ b/README.ja.md
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+日本語 | [English](./README.md) | [简体中文](./README.zh-CN.md) | [Spanish](./README.es.md)
+
+## 概要
+
+[vue-element-admin](https://panjiachen.github.io/vue-element-admin) は管理画面のフロントエンドのインタフェースで、[vue](https://github.com/vuejs/vue) と [element-ui](https://github.com/ElemeFE/element)を使っています。i18nの多言語対応、可変ルート、権限、典型的なビジネスアプリテンプレートであり、豊富なコンポーネントを提供しています。素早くビジネス用の管理画面の現型を構築に役立ちます。
+
+- [デモページ](https://panjiachen.github.io/vue-element-admin)
+
+- [ドキュメント](https://panjiachen.github.io/vue-element-admin-site/)
+
+- [Gitter](https://gitter.im/vue-element-admin/discuss)
+
+- [Donate](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate)
+
+- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
+
+- おすすめシンプルテンプレート: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
+- デスクトップバージョン: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+- Typescriptバージョン: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (感謝: [@Armour](https://github.com/Armour))
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+**バージョン`v4.1.0+`以降について、デフォルトのmasterブランチではi18nをサポートしていません。masterブランチと共にアップデートされる[i18n Branch](https://github.com/PanJiaChen/vue-element-admin/tree/i18n)を使用してください。 **
+
+**現在のバージョン `v4.0+` は `vue-cli` で構築していて、バグ報告は[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)のissueでお願いします。旧バージョン[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)もあります。こちらは`vue-cli`に依存しないです。**
+
+**低いバージョンのブラウザはサーポートしないです(例えば ie),必要があれば polyfill を追加してください。 [詳細はこちら](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
+
+## 前準備
+
+ローカル環境に [node](http://nodejs.org/) と [git](https://git-scm.com/)のインストールが必要です。[ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 、[vue-cli](https://github.com/vuejs/vue-cli) 、[axios](https://github.com/axios/axios) と [element-ui](https://github.com/ElemeFE/element)で開発しています。Requestは[Mock.js](https://github.com/nuysoft/Mock)のモックデータを使っています。
+
+**バグ修正や新規機能追加のissue と pull requestは大歓迎です。**
+
+[](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
+
+
+
+
+
+## Sponsors
+
+Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
+
+### Akveo
+
Get Java backend for Vue admin with 20% discount for 39$ use coupon code SWB0RAZPZR1M
+
+
+### Flatlogic
+
+
Admin Dashboard Templates made with Vue, React and Angular.
+
+## 機能一覧
+
+```
+- ログイン / ログアウト
+
+- Auth認証
+ - ページ権限
+ - 権限パーミッション
+ - 権限設定
+ - 外部IDでログイン
+
+- 複数環境デプロイ
+ - dev
+ - sit
+ - stage
+ - prod
+
+- 共通機能
+ - 多言語切替
+ - テーマ切替
+ - サイトメニュー(ルートから生成)
+ - パンくずリストナビゲーション
+ - タブナビゲーション
+ - Svg Sprite アイコン
+ - ローカル/バックエンド モック データ
+ - Screenfull
+
+- WYSIWYG
+ - TinyMCE
+ - Markdown
+ - JSON
+
+- Excel
+ - エクスポート
+ - インポート
+ - リード
+ - Zip
+
+- テーブル
+ - ダイナミックテーブル
+ - ドラッグアンドドロップテーブル
+ - インラインエディットテーブル
+
+- エラーページ
+ - 401
+ - 404
+
+- コンポーネント
+ - アバターアップロード
+ - トップに戻る
+ - ドラッグダイアログ
+ - ドラッグ選択
+ - ドラッグKanban
+ - ドラッグリスト
+ - ペインの分割
+ - Dropzone
+ - スティッキー
+ - CountTo
+
+- 高度なサンプル
+- エラーログ
+- ダッシュボード
+- ガイドページ
+- ECharts
+- クリップボード
+- Markdown to html
+```
+
+## Getting started
+
+```bash
+# clone the project
+git clone https://github.com/PanJiaChen/vue-element-admin.git
+
+# enter the project directory
+cd vue-element-admin
+
+# install dependency
+npm install
+
+# develop
+npm run dev
+```
+
+http://localhost:9527 が自動的に開きます。
+
+## Build
+
+```bash
+# build for test environment
+npm run build:stage
+
+# build for production environment
+npm run build:prod
+```
+
+## Advanced
+
+```bash
+# preview the release environment effect
+npm run preview
+
+# preview the release environment effect + static resource analysis
+npm run preview -- --report
+
+# code format check
+npm run lint
+
+# code format check and auto fix
+npm run lint -- --fix
+```
+
+詳細は [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) を参照してください。
+
+## Changelog
+
+各リリースの詳細は [release notes](https://github.com/PanJiaChen/vue-element-admin/releases) にあります。
+
+## Online Demo
+
+[Preview](https://panjiachen.github.io/vue-element-admin)
+
+## Donate
+
+If you find this project useful, you can buy author a glass of juice :tropical_drink:
+
+
+
+[Paypal Me](https://www.paypal.me/panfree23)
+
+[Buy me a coffee](https://www.buymeacoffee.com/Pan)
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [
](https://godban.github.io/browsers-support-badges/)IE / Edge | [
](https://godban.github.io/browsers-support-badges/)Firefox | [
](https://godban.github.io/browsers-support-badges/)Chrome | [
](https://godban.github.io/browsers-support-badges/)Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
+
+Copyright (c) 2017-present PanJiaChen
diff --git a/README.md b/README.md
index 0e0b96d3998..bb677a4383a 100644
--- a/README.md
+++ b/README.md
@@ -1,211 +1,243 @@
-# vue-element-admin #
+
+
+
-[](https://github.com/vuejs/vue)
-[](https://github.com/ElemeFE/element)
-[](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
-[]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md)
-[线上地址](http://panjiachen.github.io/vue-element-admin)
+
-[English Document](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md)
+## Introduction
-[wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
+[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It is based on [vue](https://github.com/vuejs/vue) and uses the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
-[donate](https://github.com/PanJiaChen/vue-element-admin#donate)
+[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is based on the newest development stack of vue and it has a built-in i18n solution, typical templates for enterprise applications, and lots of awesome features. It helps you build large and complex Single-Page Applications. I believe whatever your needs are, this project will help you.
-**本项目的定位是后台集成方案,不适合当基础模板来开发。**
- - 模板建议使用: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
- - 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+- [Preview](https://panjiachen.github.io/vue-element-admin)
+- [Documentation](https://panjiachen.github.io/vue-element-admin-site/)
+- [Gitter](https://gitter.im/vue-element-admin/discuss)
-**注意:该项目目前使用element-ui@1.4.2版本,所以最低兼容 Vue 2.3.0**
+- [Donate](https://panjiachen.github.io/vue-element-admin-site/donate/)
-## 前言
-> 这半年来一直在用vue写管理后台,目前后台已经有百来个页面,十几种权限,但维护成本依然很低,所以准备开源分享一下后台开发的经验和成果。目前的技术栈主要的采用vue+element+axios由webpack2打包。由于是个人项目,所以数据请求都是用了mockjs模拟。注意:在此项目基础上改造开发时请移除mock文件。
+- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
+- [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 国内用户可访问该地址在线预览
-写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
+- Base template recommends using: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
+- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
- - [wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
- - [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
- - [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
- - [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
- - [手摸手,带你用vue撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
- - [手摸手,带你封装一个vue component](https://segmentfault.com/a/1190000009090836)
+**After the `v4.1.0+` version, the default master branch will not support i18n. Please use [i18n Branch](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), it will keep up with the master update**
- 相应需求,开了一个qq群 `591724180` 方便大家交流
+**The current version is `v4.0+` build on `vue-cli`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), it does not rely on `vue-cli`**
- 或者可以加入该 **[圈子](https://jianshiapp.com/circles/1209)** 讨论问题
+**This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.**
- **如有问题请先看上述文章和Wiki,若不能满足,欢迎 issue 和 pr**
+## Preparation
- **该项目并不是一个脚手架,更倾向于是一个集成解决方案**
+You need to install [node](https://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
+Understanding and learning this knowledge in advance will greatly help the use of this project.
- **该项目不支持低版本游览器(如ie),有需求请自行添加polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
+[](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
+
+
+
-## 功能
-- 登录/注销
-- 权限验证
-- 侧边栏
-- 面包屑
-- 富文本编辑器
-- Markdown编辑器
-- JSON编辑器
-- 列表拖拽
-- plitPane
-- Dropzone
-- Sticky
-- CountTo
-- echarts图表
-- 401,404错误页面
-- 错误日志
-- 导出excel
-- zip
-- 前端可视化excel
-- table example
-- 动态table example
-- 拖拽table example
-- 内联编辑table example
-- form example
-- 多环境发布
-- dashboard
-- 二次登录
-- 动态侧边栏(支持多级路由)
-- mock数据
-- cache tabs example
-- screenfull
-- markdown2html
-- views-tab
-- clipboard
+## Sponsors
+Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
-## 开发
-```bash
- # 克隆项目
- git clone https://github.com/PanJiaChen/vue-element-admin.git
+### Akveo
+
Get Java backend for Vue admin with 20% discount for 39$ use coupon code SWB0RAZPZR1M
+
- # 安装依赖
- npm install
- //or # 建议不要用cnpm 安装有各种诡异的bug 可以通过如下操作解决npm速度慢的问题
- npm install --registry=https://registry.npm.taobao.org
+### Flatlogic
- # 本地开发 开启服务
- npm run dev
-```
-浏览器访问 http://localhost:9527
+
Admin Dashboard Templates made with Vue, React and Angular.
-## 发布
-```bash
- # 发布测试环境 带webpack ananalyzer
- npm run build:sit-preview
+## Features
- # 构建生成环境
- npm run build:prod
```
-
-## 目录结构
-```shell
-├── build // 构建相关
-├── config // 配置相关
-├── src // 源代码
-│ ├── api // 所有请求
-│ ├── assets // 主题 字体等静态资源
-│ ├── components // 全局公用组件
-│ ├── directive // 全局指令
-│ ├── filtres // 全局filter
-│ ├── mock // mock数据
-│ ├── router // 路由
-│ ├── store // 全局store管理
-│ ├── styles // 全局样式
-│ ├── utils // 全局公用方法
-│ ├── view // view
-│ ├── App.vue // 入口页面
-│ └── main.js // 入口 加载组件 初始化等
-├── static // 第三方不打包资源
-│ └── Tinymce // 富文本
-├── .babelrc // babel-loader 配置
-├── eslintrc.js // eslint 配置项
-├── .gitignore // git 忽略项
-├── favicon.ico // favicon图标
-├── index.html // html模板
-└── package.json // package.json
-
+- Login / Logout
+
+- Permission Authentication
+ - Page permission
+ - Directive permission
+ - Permission configuration page
+ - Two-step login
+
+- Multi-environment build
+ - Develop (dev)
+ - sit
+ - Stage Test (stage)
+ - Production (prod)
+
+- Global Features
+ - I18n
+ - Multiple dynamic themes
+ - Dynamic sidebar (supports multi-level routing)
+ - Dynamic breadcrumb
+ - Tags-view (Tab page Support right-click operation)
+ - Svg Sprite
+ - Mock data
+ - Screenfull
+ - Responsive Sidebar
+
+- Editor
+ - Rich Text Editor
+ - Markdown Editor
+ - JSON Editor
+
+- Excel
+ - Export Excel
+ - Upload Excel
+ - Visualization Excel
+ - Export zip
+
+- Table
+ - Dynamic Table
+ - Drag And Drop Table
+ - Inline Edit Table
+
+- Error Page
+ - 401
+ - 404
+
+- Components
+ - Avatar Upload
+ - Back To Top
+ - Drag Dialog
+ - Drag Select
+ - Drag Kanban
+ - Drag List
+ - SplitPane
+ - Dropzone
+ - Sticky
+ - CountTo
+
+- Advanced Example
+- Error Log
+- Dashboard
+- Guide Page
+- ECharts
+- Clipboard
+- Markdown to html
```
-## Changelog
-Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
-
-## Donate
-If you find this project useful, you can buy me a cup of coffee
-
-
-## 状态管理
-后台只有user和app配置相关状态使用vuex存在全局,其它数据都由每个业务页面自己管理。
-
-
-## 效果图
-
-#### 两步验证登录 支持微信和qq
-
-
-
-#### 真正的动态换肤
-
-
-
-#### tabs
-
-
-
+## Getting started
+```bash
+# clone the project
+git clone https://github.com/PanJiaChen/vue-element-admin.git
-#### 可收起侧边栏
+# enter the project directory
+cd vue-element-admin
-
+# install dependency
+npm install
-#### table拖拽排序
+# develop
+npm run dev
+```
-
+This will automatically open http://localhost:9527
+## Build
-#### 动态table
+```bash
+# build for test environment
+npm run build:stage
-
+# build for production environment
+npm run build:prod
+```
+## Advanced
-#### 上传裁剪头像
+```bash
+# preview the release environment effect
+npm run preview
-
+# preview the release environment effect + static resource analysis
+npm run preview -- --report
+# code format check
+npm run lint
-#### 错误统计
+# code format check and auto fix
+npm run lint -- --fix
+```
-
+Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
+## Changelog
-#### 富文本(整合七牛 打水印等个性化功能)
+Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
-
+## Online Demo
-#### 封装table组件
+[Preview](https://panjiachen.github.io/vue-element-admin)
-
+## Donate
-#### 图表
+If you find this project useful, you can buy author a glass of juice :tropical_drink:
-
+
+[Paypal Me](https://www.paypal.me/panfree23)
-#### 导出excel
+[Buy me a coffee](https://www.buymeacoffee.com/Pan)
-
+## Browsers support
+Modern browsers and Internet Explorer 10+.
-## [查看更多demo](http://panjiachen.github.io/vue-element-admin)
+| [
](https://godban.github.io/browsers-support-badges/)IE / Edge | [
](https://godban.github.io/browsers-support-badges/)Firefox | [
](https://godban.github.io/browsers-support-badges/)Chrome | [
](https://godban.github.io/browsers-support-badges/)Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
## License
-MIT
+[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
+
+Copyright (c) 2017-present PanJiaChen
diff --git a/README.zh-CN.md b/README.zh-CN.md
new file mode 100644
index 00000000000..a14858a4d08
--- /dev/null
+++ b/README.zh-CN.md
@@ -0,0 +1,266 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+简体中文 | [English](./README.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md)
+
+
+
+## 简介
+
+[vue-element-admin](https://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
+
+- [在线预览](https://panjiachen.github.io/vue-element-admin)
+
+- [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
+
+- [Gitter 讨论组](https://gitter.im/vue-element-admin/discuss)
+
+- [Donate](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate)
+
+- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
+
+- [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 在线预览(国内用户可访问该地址)
+
+- [国内访问文档](https://panjiachen.gitee.io/vue-element-admin-site/zh/) 文档(方便没翻墙的用户查看)
+
+- 基础模板建议使用: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
+- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+- Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+**`v4.1.0+`版本之后默认 master 分支将不支持国际化,有需要的请使用[i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n)分支,它会和 master 保持同步更新**
+
+**该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
+
+**目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0),它不依赖 `vue-cli`**
+
+群主 **[圈子](https://jianshiapp.com/circles/1209)** 群主会经常分享一些技术相关的东西,或者加入 [qq 群](https://github.com/PanJiaChen/vue-element-admin/issues/602) 或者关注 [微博](https://weibo.com/u/3423485724?is_all=1)
+
+## 前序准备
+
+你需要在本地安装 [node](http://nodejs.org/) 和 [git](https://git-scm.com/)。本项目技术栈基于 [ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 、[vue-cli](https://github.com/vuejs/vue-cli) 、[axios](https://github.com/axios/axios) 和 [element-ui](https://github.com/ElemeFE/element),所有的请求数据都使用[Mock.js](https://github.com/nuysoft/Mock)进行模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。
+
+同时配套了系列教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目
+
+- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
+- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
+- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
+- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
+- [手摸手,带你用vue撸后台 系列五(v4.0新版本)](https://juejin.im/post/5c92ff94f265da6128275a85)
+- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
+- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)
+- [手摸手,带你用合理的姿势使用 webpack4(上)](https://juejin.im/post/5b56909a518825195f499806)
+- [手摸手,带你用合理的姿势使用 webpack4(下)](https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc)
+
+**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**
+
+[](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
+
+
+
+
+
+## Sponsors
+
+Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
+
+### Akveo
+
Java 后端整合,可以使用优惠码:SWB0RAZPZR1M,获得20%的价格优化
+
+### Flatlogic
+
+
Admin Dashboard Templates made with Vue, React and Angular.
+
+
+## 功能
+
+```
+- 登录 / 注销
+
+- 权限验证
+ - 页面权限
+ - 指令权限
+ - 权限配置
+ - 二步登录
+
+- 多环境发布
+ - dev
+ - sit
+ - stage
+ - prod
+
+- 全局功能
+ - 国际化多语言
+ - 多种动态换肤
+ - 动态侧边栏(支持多级路由嵌套)
+ - 动态面包屑
+ - 快捷导航(标签页)
+ - Svg Sprite 图标
+ - 本地/后端 mock 数据
+ - Screenfull全屏
+ - 自适应收缩侧边栏
+
+- 编辑器
+ - 富文本
+ - Markdown
+ - JSON 等多格式
+
+- Excel
+ - 导出excel
+ - 导入excel
+ - 前端可视化excel
+ - 导出zip
+
+- 表格
+ - 动态表格
+ - 拖拽表格
+ - 内联编辑
+
+- 错误页面
+ - 401
+ - 404
+
+- 組件
+ - 头像上传
+ - 返回顶部
+ - 拖拽Dialog
+ - 拖拽Select
+ - 拖拽看板
+ - 列表拖拽
+ - SplitPane
+ - Dropzone
+ - Sticky
+ - CountTo
+
+- 综合实例
+- 错误日志
+- Dashboard
+- 引导页
+- ECharts 图表
+- Clipboard(剪贴复制)
+- Markdown2html
+```
+
+## 开发
+
+```bash
+# 克隆项目
+git clone https://github.com/PanJiaChen/vue-element-admin.git
+
+# 进入项目目录
+cd vue-element-admin
+
+# 安装依赖
+npm install
+
+# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
+npm install --registry=https://registry.npm.taobao.org
+
+# 启动服务
+npm run dev
+```
+
+浏览器访问 http://localhost:9527
+
+## 发布
+
+```bash
+# 构建测试环境
+npm run build:stage
+
+# 构建生产环境
+npm run build:prod
+```
+
+## 其它
+
+```bash
+# 预览发布环境效果
+npm run preview
+
+# 预览发布环境效果 + 静态资源分析
+npm run preview -- --report
+
+# 代码格式检查
+npm run lint
+
+# 代码格式检查并自动修复
+npm run lint -- --fix
+```
+
+更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
+
+## Changelog
+
+Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
+
+## Online Demo
+
+[在线 Demo](https://panjiachen.github.io/vue-element-admin)
+
+## Donate
+
+如果你觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励 :tropical_drink:
+
+
+[更多捐赠方式](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate)
+
+[Paypal Me](https://www.paypal.me/panfree23)
+
+[Buy me a coffee](https://www.buymeacoffee.com/Pan)
+
+## 购买贴纸
+
+你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,本项目将获得 2 元的捐赠。
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [
](https://godban.github.io/browsers-support-badges/)IE / Edge | [
](https://godban.github.io/browsers-support-badges/)Firefox | [
](https://godban.github.io/browsers-support-badges/)Chrome | [
](https://godban.github.io/browsers-support-badges/)Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
+
+Copyright (c) 2017-present PanJiaChen
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 00000000000..fb82b2715f4
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +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']
+ }
+ }
+}
diff --git a/build/build.js b/build/build.js
deleted file mode 100644
index 2041892bec1..00000000000
--- a/build/build.js
+++ /dev/null
@@ -1,39 +0,0 @@
-require('./check-versions')();
-var server = require('pushstate-server');
-var opn = require('opn')
-var ora = require('ora')
-var rm = require('rimraf')
-var path = require('path')
-var chalk = require('chalk')
-var webpack = require('webpack');
-var config = require('../config');
-var webpackConfig = require('./webpack.prod.conf');
-
-var spinner = ora('building for ' + process.env.NODE_ENV + ' of ' + process.env.env_config+ ' mode...' )
-spinner.start()
-
-
-rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
- if (err) throw err
- webpack(webpackConfig, function (err, stats) {
- spinner.stop()
- if (err) throw err
- process.stdout.write(stats.toString({
- colors: true,
- modules: false,
- children: false,
- chunks: false,
- chunkModules: false
- }) + '\n\n')
-
- console.log(chalk.cyan(' Build complete.\n'))
- if(process.env.npm_config_preview){
- server.start({
- port: 9528,
- directory: './dist',
- file: '/index.html'
- });
- console.log('> Listening at ' + 'http://localhost:9528' + '\n')
- }
- })
-})
diff --git a/build/check-versions.js b/build/check-versions.js
deleted file mode 100644
index 3a1dda61e98..00000000000
--- a/build/check-versions.js
+++ /dev/null
@@ -1,45 +0,0 @@
-var chalk = require('chalk')
-var semver = require('semver')
-var packageConfig = require('../package.json')
-
-function exec(cmd) {
- return require('child_process').execSync(cmd).toString().trim()
-}
-
-var versionRequirements = [
- {
- name: 'node',
- currentVersion: semver.clean(process.version),
- versionRequirement: packageConfig.engines.node
- },
- {
- name: 'npm',
- currentVersion: exec('npm --version'),
- versionRequirement: packageConfig.engines.npm
- }
-]
-
-module.exports = function () {
- var warnings = []
- for (var i = 0; i < versionRequirements.length; i++) {
- var mod = versionRequirements[i]
- if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
- warnings.push(mod.name + ': ' +
- chalk.red(mod.currentVersion) + ' should be ' +
- chalk.green(mod.versionRequirement)
- )
- }
- }
-
- if (warnings.length) {
- console.log('')
- console.log(chalk.yellow('To use this template, you must update following to modules:'))
- console.log()
- for (var i = 0; i < warnings.length; i++) {
- var warning = warnings[i]
- console.log(' ' + warning)
- }
- console.log()
- process.exit(1)
- }
-}
diff --git a/build/dev-client.js b/build/dev-client.js
deleted file mode 100644
index 18aa1e21952..00000000000
--- a/build/dev-client.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/* eslint-disable */
-require('eventsource-polyfill')
-var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
-
-hotClient.subscribe(function (event) {
- if (event.action === 'reload') {
- window.location.reload()
- }
-})
diff --git a/build/dev-server.js b/build/dev-server.js
deleted file mode 100644
index 254a3bb1038..00000000000
--- a/build/dev-server.js
+++ /dev/null
@@ -1,91 +0,0 @@
-require('./check-versions')(); // 检查 Node 和 npm 版本
-
-var config = require('../config');
-if (!process.env.NODE_ENV) {
- process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
-}
-
-var opn = require('opn')
-var path = require('path');
-var express = require('express');
-var webpack = require('webpack');
-var proxyMiddleware = require('http-proxy-middleware');
-var webpackConfig = require('./webpack.dev.conf');
-
-// default port where dev server listens for incoming traffic
-var port = process.env.PORT || config.dev.port;
-// automatically open browser, if not set will be false
-var autoOpenBrowser = !!config.dev.autoOpenBrowser;
-// Define HTTP proxies to your custom API backend
-// https://github.com/chimurai/http-proxy-middleware
-var proxyTable = config.dev.proxyTable;
-
-var app = express();
-var compiler = webpack(webpackConfig);
-
-var devMiddleware = require('webpack-dev-middleware')(compiler, {
- publicPath: webpackConfig.output.publicPath,
- quiet: true
-});
-
-var hotMiddleware = require('webpack-hot-middleware')(compiler, {
- log: false,
- heartbeat: 2000
-});
-
-// force page reload when html-webpack-plugin template changes
-compiler.plugin('compilation', function (compilation) {
- compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
- hotMiddleware.publish({action: 'reload'});
- cb()
- })
-});
-
-// proxy api requests
-Object.keys(proxyTable).forEach(function (context) {
- var options = proxyTable[context]
- if (typeof options === 'string') {
- options = {target: options}
- }
- app.use(proxyMiddleware(options.filter || context, options))
-});
-
-// handle fallback for HTML5 history API
-app.use(require('connect-history-api-fallback')());
-
-// serve webpack bundle output
-app.use(devMiddleware);
-
-// enable hot-reload and state-preserving
-// compilation error display
-app.use(hotMiddleware);
-
-// serve pure static assets
-var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory);
-app.use(staticPath, express.static('./static'));
-
-var uri = 'http://localhost:' + port
-
-var _resolve
-var readyPromise = new Promise(resolve => {
- _resolve = resolve
-})
-
-console.log('> Starting dev server...')
-devMiddleware.waitUntilValid(() => {
- console.log('> Listening at ' + uri + '\n')
- // when env is testing, don't need open it
- if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
- opn(uri)
- }
- _resolve()
-})
-
-var server = app.listen(port)
-
-module.exports = {
- ready: readyPromise,
- close: () => {
- server.close()
- }
-}
diff --git a/build/index.js b/build/index.js
new file mode 100644
index 00000000000..0c57de2aad9
--- /dev/null
+++ b/build/index.js
@@ -0,0 +1,35 @@
+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')
+
+ run(`vue-cli-service build ${args}`)
+
+ const port = 9526
+ const publicPath = config.publicPath
+
+ var connect = require('connect')
+ var serveStatic = require('serve-static')
+ const app = connect()
+
+ 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`))
+ }
+
+ })
+} else {
+ run(`vue-cli-service build ${args}`)
+}
diff --git a/build/utils.js b/build/utils.js
deleted file mode 100644
index b1d54b4d6c5..00000000000
--- a/build/utils.js
+++ /dev/null
@@ -1,71 +0,0 @@
-var path = require('path')
-var config = require('../config')
-var ExtractTextPlugin = require('extract-text-webpack-plugin')
-
-exports.assetsPath = function (_path) {
- var assetsSubDirectory = process.env.NODE_ENV === 'production'
- ? config.build.assetsSubDirectory
- : config.dev.assetsSubDirectory
- return path.posix.join(assetsSubDirectory, _path)
-}
-
-exports.cssLoaders = function (options) {
- options = options || {}
-
- var cssLoader = {
- loader: 'css-loader',
- options: {
- minimize: process.env.NODE_ENV === 'production',
- sourceMap: options.sourceMap
- }
- }
-
- // generate loader string to be used with extract text plugin
- function generateLoaders (loader, loaderOptions) {
- var loaders = [cssLoader]
- if (loader) {
- loaders.push({
- loader: loader + '-loader',
- options: Object.assign({}, loaderOptions, {
- sourceMap: options.sourceMap
- })
- })
- }
-
- // Extract CSS when that option is specified
- // (which is the case during production build)
- if (options.extract) {
- return ExtractTextPlugin.extract({
- use: loaders,
- fallback: 'vue-style-loader'
- })
- } else {
- return ['vue-style-loader'].concat(loaders)
- }
- }
-
- // https://vue-loader.vuejs.org/en/configurations/extract-css.html
- return {
- css: generateLoaders(),
- postcss: generateLoaders(),
- less: generateLoaders('less'),
- sass: generateLoaders('sass', { indentedSyntax: true }),
- scss: generateLoaders('sass'),
- stylus: generateLoaders('stylus'),
- styl: generateLoaders('stylus')
- }
-}
-
-// Generate loaders for standalone style files (outside of .vue)
-exports.styleLoaders = function (options) {
- var output = []
- var loaders = exports.cssLoaders(options)
- for (var extension in loaders) {
- var loader = loaders[extension]
- output.push({
- test: new RegExp('\\.' + extension + '$'),
- use: loader
- })
- }
- return output
-}
diff --git a/build/vue-loader.conf.js b/build/vue-loader.conf.js
deleted file mode 100644
index d7df7e57270..00000000000
--- a/build/vue-loader.conf.js
+++ /dev/null
@@ -1,12 +0,0 @@
-var utils = require('./utils')
-var config = require('../config')
-var isProduction = process.env.NODE_ENV === 'production'
-
-module.exports = {
- loaders: utils.cssLoaders({
- sourceMap: isProduction
- ? config.build.productionSourceMap
- : config.dev.cssSourceMap,
- extract: isProduction
- })
-}
diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
deleted file mode 100644
index 0fd53f610ac..00000000000
--- a/build/webpack.base.conf.js
+++ /dev/null
@@ -1,92 +0,0 @@
-var path = require('path')
-var utils = require('./utils')
-var config = require('../config')
-var vueLoaderConfig = require('./vue-loader.conf')
-
-function resolve(dir) {
- return path.join(__dirname, '..', dir)
-}
-
-module.exports = {
- entry: {
- app: './src/main.js'
- },
- output: {
- path: config.build.assetsRoot,
- filename: '[name].js',
- publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
- },
- resolve: {
- extensions: ['.js', '.vue', '.json'],
- alias: {
- 'vue$': 'vue/dist/vue.esm.js',
- '@': resolve('src'),
- 'src': path.resolve(__dirname, '../src'),
- 'assets': path.resolve(__dirname, '../src/assets'),
- 'components': path.resolve(__dirname, '../src/components'),
- 'views': path.resolve(__dirname, '../src/views'),
- 'styles': path.resolve(__dirname, '../src/styles'),
- 'api': path.resolve(__dirname, '../src/api'),
- 'utils': path.resolve(__dirname, '../src/utils'),
- 'store': path.resolve(__dirname, '../src/store'),
- 'router': path.resolve(__dirname, '../src/router'),
- 'mock': path.resolve(__dirname, '../src/mock'),
- 'vendor': path.resolve(__dirname, '../src/vendor'),
- 'static': path.resolve(__dirname, '../static')
- }
- },
- module: {
- rules: [
- {
- test: /\.(js|vue)$/,
- loader: 'eslint-loader',
- enforce: "pre",
- include: [resolve('src'), resolve('test')],
- options: {
- formatter: require('eslint-friendly-formatter')
- }
- },
- {
- test: /\.vue$/,
- loader: 'vue-loader',
- options: vueLoaderConfig
- },
- {
- test: /\.js$/,
- loader: 'babel-loader?cacheDirectory',
- include: [resolve('src'), resolve('test')]
- },
- {
- test: /\.svg$/,
- loader: 'svg-sprite-loader',
- include: [resolve('src/icons')],
- options: {
- symbolId: 'icon-[name]'
- }
- },
- {
- test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
- loader: 'url-loader',
- exclude: [resolve('src/icons')],
- options: {
- limit: 10000,
- name: utils.assetsPath('img/[name].[hash:7].[ext]')
- }
- },
- {
- test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
- loader: 'url-loader',
- options: {
- limit: 10000,
- name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
- }
- }
- ]
- },
- //注入全局mixin
- // sassResources: path.join(__dirname, '../src/styles/mixin.scss'),
- // sassLoader: {
- // data: path.join(__dirname, '../src/styles/index.scss')
- // },
-}
-
diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js
deleted file mode 100644
index 5aec2fafc4f..00000000000
--- a/build/webpack.dev.conf.js
+++ /dev/null
@@ -1,46 +0,0 @@
-var utils = require('./utils')
-var path = require('path')
-var webpack = require('webpack')
-var config = require('../config')
-var merge = require('webpack-merge')
-var baseWebpackConfig = require('./webpack.base.conf')
-var HtmlWebpackPlugin = require('html-webpack-plugin')
-var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
-
-// add hot-reload related code to entry chunks
-Object.keys(baseWebpackConfig.entry).forEach(function (name) {
- baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
-})
-
-function resolveApp(relativePath) {
- return path.resolve(relativePath);
-}
-
-module.exports = merge(baseWebpackConfig, {
- module: {
- rules: utils.styleLoaders({
- sourceMap: config.dev.cssSourceMap
- })
- },
- // cheap-source-map is faster for development
- devtool: '#cheap-source-map',
- cache: true,
- plugins: [
- new webpack.DefinePlugin({
- 'process.env': config.dev.env
- }),
- // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
- new webpack.HotModuleReplacementPlugin(),
- new webpack.NoEmitOnErrorsPlugin(),
- // https://github.com/ampedandwired/html-webpack-plugin
- new HtmlWebpackPlugin({
- filename: 'index.html',
- template: 'index.html',
- favicon: resolveApp('favicon.ico'),
- inject: true,
- path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
- }),
- new FriendlyErrorsPlugin()
- ]
-})
-
diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js
deleted file mode 100644
index cf50e0c95cb..00000000000
--- a/build/webpack.prod.conf.js
+++ /dev/null
@@ -1,127 +0,0 @@
-var path = require('path')
-var utils = require('./utils')
-var webpack = require('webpack')
-var config = require('../config')
-var merge = require('webpack-merge')
-var baseWebpackConfig = require('./webpack.base.conf')
-var CopyWebpackPlugin = require('copy-webpack-plugin')
-var HtmlWebpackPlugin = require('html-webpack-plugin')
-var ExtractTextPlugin = require('extract-text-webpack-plugin')
-var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
-
-var env = config.build[process.env.env_config+'Env']
-
-function resolveApp(relativePath) {
- return path.resolve(relativePath);
-}
-
-var webpackConfig = merge(baseWebpackConfig, {
- module: {
- rules: utils.styleLoaders({
- sourceMap: config.build.productionSourceMap,
- extract: true
- })
- },
- devtool: config.build.productionSourceMap ? '#source-map' : false,
- output: {
- path: config.build.assetsRoot,
- filename: utils.assetsPath('js/[name].[chunkhash].js'),
- chunkFilename: utils.assetsPath('js/[id].[chunkhash].js'),
- publicPath: config.build.assetsPublicPath
- },
- plugins: [
- // http://vuejs.github.io/vue-loader/en/workflow/production.html
- new webpack.DefinePlugin({
- 'process.env': env
- }),
- new webpack.optimize.UglifyJsPlugin({
- compress: {
- warnings: false
- },
- sourceMap: true
- }),
- // extract css into its own file
- new ExtractTextPlugin({
- filename: utils.assetsPath('css/[name].[contenthash].css')
- }),
- // Compress extracted CSS. We are using this plugin so that possible
- // duplicated CSS from different components can be deduped.
- new OptimizeCSSPlugin(),
- // generate dist index.html with correct asset hash for caching.
- // you can customize output by editing /index.html
- // see https://github.com/ampedandwired/html-webpack-plugin
- new HtmlWebpackPlugin({
- filename: 'index.html',
- template: 'index.html',
- inject: true,
- favicon: resolveApp('favicon.ico'),
- minify: {
- removeComments: true,
- collapseWhitespace: true,
- removeRedundantAttributes: true,
- useShortDoctype: true,
- removeEmptyAttributes: true,
- removeStyleLinkTypeAttributes: true,
- keepClosingSlash: true,
- minifyJS: true,
- minifyCSS: true,
- minifyURLs: true
- },
- path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
- // necessary to consistently work with multiple chunks via CommonsChunkPlugin
- chunksSortMode: 'dependency'
- }),
- // cache Module Identifiers
- new webpack.HashedModuleIdsPlugin(),
- // split vendor js into its own file
- new webpack.optimize.CommonsChunkPlugin({
- name: 'vendor',
- minChunks: function (module, count) {
- // any required modules inside node_modules are extracted to vendor
- return (
- module.resource &&
- /\.js$/.test(module.resource) &&
- module.resource.indexOf(
- path.join(__dirname, '../node_modules')
- ) === 0
- )
- }
- }),
- // split echarts into its own file
- new webpack.optimize.CommonsChunkPlugin({
- async: 'echarts',
- minChunks(module) {
- var context = module.context;
- return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
- }
- }),
- // split xlsx into its own file
- new webpack.optimize.CommonsChunkPlugin({
- async: 'xlsx',
- minChunks(module) {
- var context = module.context;
- return context && (context.indexOf('xlsx') >= 0);
- }
- }),
- // extract webpack runtime and module manifest to its own file in order to
- // prevent vendor hash from being updated whenever app bundle is updated
- new webpack.optimize.CommonsChunkPlugin({
- name: 'manifest',
- chunks: ['vendor']
- }),
- // copy custom static assets
- new CopyWebpackPlugin([{
- from: path.resolve(__dirname, '../static'),
- to: config.build.assetsSubDirectory,
- ignore: ['.*']
- }])
- ]
-})
-
-if (config.build.bundleAnalyzerReport) {
- var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
- webpackConfig.plugins.push(new BundleAnalyzerPlugin())
-}
-
-module.exports = webpackConfig
-
diff --git a/config/dev.env.js b/config/dev.env.js
deleted file mode 100644
index f4aeda50c83..00000000000
--- a/config/dev.env.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- NODE_ENV: '"development"',
- ENV_CONFIG: '"dev"',
- BASE_API: '"https://api-dev"',
- APP_ORIGIN: '"https://wallstreetcn.com"'
-}
diff --git a/config/index.js b/config/index.js
deleted file mode 100644
index c38e0b8426f..00000000000
--- a/config/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// see http://vuejs-templates.github.io/webpack for documentation.
-var path = require('path')
-
-module.exports = {
- build: {
- sitEnv: require('./sit.env'),
- prodEnv: require('./prod.env'),
- index: path.resolve(__dirname, '../dist/index.html'),
- assetsRoot: path.resolve(__dirname, '../dist'),
- assetsSubDirectory: 'static',
- assetsPublicPath: './', //请根据自己路径配置更改
- productionSourceMap: false,
- // Gzip off by default as many popular static hosts such as
- // Surge or Netlify already gzip all static assets for you.
- // Before setting to `true`, make sure to:
- // npm install --save-dev compression-webpack-plugin
- productionGzip: false,
- productionGzipExtensions: ['js', 'css'],
- // Run the build command with an extra argument to
- // View the bundle analyzer report after build finishes:
- // `npm run build --report`
- // Set to `true` or `false` to always turn it on or off
- bundleAnalyzerReport: process.env.npm_config_report
- },
- dev: {
- env: require('./dev.env'),
- port: 9527,
- autoOpenBrowser: true,
- assetsSubDirectory: 'static',
- assetsPublicPath: '/',
- proxyTable: {},
- // CSS Sourcemaps off by default because relative paths are "buggy"
- // with this option, according to the CSS-Loader README
- // (https://github.com/webpack/css-loader#sourcemaps)
- // In our experience, they generally work as expected,
- // just be aware of this issue when enabling this option.
- cssSourceMap: false
- }
-}
diff --git a/config/prod.env.js b/config/prod.env.js
deleted file mode 100644
index 511b341aaeb..00000000000
--- a/config/prod.env.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- NODE_ENV: '"production"',
- ENV_CONFIG: '"prod"',
- BASE_API: '"https://api-prod"',
- APP_ORIGIN: '"https://wallstreetcn.com"'
-};
diff --git a/config/sit.env.js b/config/sit.env.js
deleted file mode 100644
index a9a041af3dd..00000000000
--- a/config/sit.env.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- NODE_ENV: '"production"',
- ENV_CONFIG: '"sit"',
- BASE_API: '"https://api-sit"',
- APP_ORIGIN: '"https://wallstreetcn.com"'
-};
diff --git a/favicon.ico b/favicon.ico
deleted file mode 100644
index 7cd39d7fc1b..00000000000
Binary files a/favicon.ico and /dev/null differ
diff --git a/gifs/2login.gif b/gifs/2login.gif
deleted file mode 100644
index 4b2b64da6a8..00000000000
Binary files a/gifs/2login.gif and /dev/null differ
diff --git a/gifs/dynamictable.gif b/gifs/dynamictable.gif
deleted file mode 100644
index ca666e53a7d..00000000000
Binary files a/gifs/dynamictable.gif and /dev/null differ
diff --git a/gifs/echarts.gif b/gifs/echarts.gif
deleted file mode 100644
index 11ad2a56e07..00000000000
Binary files a/gifs/echarts.gif and /dev/null differ
diff --git a/gifs/editor.gif b/gifs/editor.gif
deleted file mode 100644
index 1ebb9c6c152..00000000000
Binary files a/gifs/editor.gif and /dev/null differ
diff --git a/gifs/errorlog.gif b/gifs/errorlog.gif
deleted file mode 100644
index d37c7085036..00000000000
Binary files a/gifs/errorlog.gif and /dev/null differ
diff --git a/gifs/excel.png b/gifs/excel.png
deleted file mode 100644
index e536774c35f..00000000000
Binary files a/gifs/excel.png and /dev/null differ
diff --git a/gifs/leftmenu.gif b/gifs/leftmenu.gif
deleted file mode 100644
index f3ca2bd961b..00000000000
Binary files a/gifs/leftmenu.gif and /dev/null differ
diff --git a/gifs/login.png b/gifs/login.png
deleted file mode 100644
index a923b271fe6..00000000000
Binary files a/gifs/login.png and /dev/null differ
diff --git a/gifs/order.gif b/gifs/order.gif
deleted file mode 100644
index d038b06d2aa..00000000000
Binary files a/gifs/order.gif and /dev/null differ
diff --git a/gifs/table.gif b/gifs/table.gif
deleted file mode 100644
index 31dcd1443e8..00000000000
Binary files a/gifs/table.gif and /dev/null differ
diff --git a/gifs/tabs.gif b/gifs/tabs.gif
deleted file mode 100644
index 331d192fa44..00000000000
Binary files a/gifs/tabs.gif and /dev/null differ
diff --git a/gifs/theme.gif b/gifs/theme.gif
deleted file mode 100644
index 47f48d54c74..00000000000
Binary files a/gifs/theme.gif and /dev/null differ
diff --git a/gifs/upload1.gif b/gifs/upload1.gif
deleted file mode 100644
index 37a5db22368..00000000000
Binary files a/gifs/upload1.gif and /dev/null differ
diff --git a/gifs/uploadAvatar.gif b/gifs/uploadAvatar.gif
deleted file mode 100644
index c689b9a23b6..00000000000
Binary files a/gifs/uploadAvatar.gif and /dev/null differ
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 00000000000..143cdc868cb
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +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: {
+ '^@/(.*)$': '/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: '/tests/unit/coverage',
+ // 'collectCoverage': true,
+ 'coverageReporters': [
+ 'lcov',
+ 'text-summary'
+ ],
+ testURL: 'http://localhost/'
+}
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 00000000000..958df0467f1
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
\ No newline at end of file
diff --git a/mock/article.js b/mock/article.js
new file mode 100644
index 00000000000..23d8ba51056
--- /dev/null
+++ b/mock/article.js
@@ -0,0 +1,116 @@
+const Mock = require('mockjs')
+
+const List = []
+const count = 100
+
+const baseContent = 'I am testing data, I am testing data.

'
+const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'
+
+for (let i = 0; i < count; i++) {
+ List.push(Mock.mock({
+ id: '@increment',
+ timestamp: +Mock.Random.date('T'),
+ author: '@first',
+ reviewer: '@first',
+ title: '@title(5, 10)',
+ content_short: 'mock data',
+ content: baseContent,
+ forecast: '@float(0, 100, 2, 2)',
+ importance: '@integer(1, 3)',
+ 'type|1': ['CN', 'US', 'JP', 'EU'],
+ 'status|1': ['published', 'draft'],
+ display_time: '@datetime',
+ comment_disabled: true,
+ pageviews: '@integer(300, 5000)',
+ image_uri,
+ platforms: ['a-platform']
+ }))
+}
+
+module.exports = [
+ {
+ url: '/vue-element-admin/article/list',
+ type: 'get',
+ response: config => {
+ const { importance, type, title, page = 1, limit = 20, sort } = config.query
+
+ let mockList = List.filter(item => {
+ if (importance && item.importance !== +importance) return false
+ if (type && item.type !== type) return false
+ if (title && item.title.indexOf(title) < 0) return false
+ return true
+ })
+
+ if (sort === '-id') {
+ mockList = mockList.reverse()
+ }
+
+ const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
+
+ return {
+ code: 20000,
+ data: {
+ total: mockList.length,
+ items: pageList
+ }
+ }
+ }
+ },
+
+ {
+ url: '/vue-element-admin/article/detail',
+ type: 'get',
+ response: config => {
+ const { id } = config.query
+ for (const article of List) {
+ if (article.id === +id) {
+ return {
+ code: 20000,
+ data: article
+ }
+ }
+ }
+ }
+ },
+
+ {
+ url: '/vue-element-admin/article/pv',
+ type: 'get',
+ response: _ => {
+ return {
+ code: 20000,
+ data: {
+ pvData: [
+ { key: 'PC', pv: 1024 },
+ { key: 'mobile', pv: 1024 },
+ { key: 'ios', pv: 1024 },
+ { key: 'android', pv: 1024 }
+ ]
+ }
+ }
+ }
+ },
+
+ {
+ url: '/vue-element-admin/article/create',
+ type: 'post',
+ response: _ => {
+ return {
+ code: 20000,
+ data: 'success'
+ }
+ }
+ },
+
+ {
+ url: '/vue-element-admin/article/update',
+ type: 'post',
+ response: _ => {
+ return {
+ code: 20000,
+ data: 'success'
+ }
+ }
+ }
+]
+
diff --git a/mock/index.js b/mock/index.js
new file mode 100644
index 00000000000..2eed65db83b
--- /dev/null
+++ b/mock/index.js
@@ -0,0 +1,60 @@
+const Mock = require('mockjs')
+const { param2Obj } = require('./utils')
+
+const user = require('./user')
+const role = require('./role')
+const article = require('./article')
+const search = require('./remote-search')
+
+const mocks = [
+ ...user,
+ ...role,
+ ...article,
+ ...search
+]
+
+// 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
+ }
+ }
+ 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)
+ }
+ }
+
+ for (const i of mocks) {
+ Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
+ }
+}
+
+module.exports = {
+ mocks,
+ mockXHR
+}
diff --git a/mock/mock-server.js b/mock/mock-server.js
new file mode 100644
index 00000000000..8941ec0f803
--- /dev/null
+++ b/mock/mock-server.js
@@ -0,0 +1,81 @@
+const chokidar = require('chokidar')
+const bodyParser = require('body-parser')
+const chalk = require('chalk')
+const path = require('path')
+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
+ }
+}
+
+function unregisterRoutes() {
+ 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))
+ }
+ }
+}
+
+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
+ }))
+
+ 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)
+
+ // clear routes cache
+ unregisterRoutes()
+
+ 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))
+ }
+ }
+ })
+}
diff --git a/mock/remote-search.js b/mock/remote-search.js
new file mode 100644
index 00000000000..8fc4926743d
--- /dev/null
+++ b/mock/remote-search.js
@@ -0,0 +1,51 @@
+const Mock = require('mockjs')
+
+const NameList = []
+const count = 100
+
+for (let i = 0; i < count; i++) {
+ NameList.push(Mock.mock({
+ name: '@first'
+ }))
+}
+NameList.push({ name: 'mock-Pan' })
+
+module.exports = [
+ // username search
+ {
+ url: '/vue-element-admin/search/user',
+ type: 'get',
+ response: config => {
+ const { name } = config.query
+ const mockNameList = NameList.filter(item => {
+ const lowerCaseName = item.name.toLowerCase()
+ return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0)
+ })
+ return {
+ code: 20000,
+ data: { items: mockNameList }
+ }
+ }
+ },
+
+ // transaction list
+ {
+ url: '/vue-element-admin/transaction/list',
+ type: 'get',
+ response: _ => {
+ return {
+ code: 20000,
+ data: {
+ total: 20,
+ 'items|20': [{
+ order_no: '@guid()',
+ timestamp: +Mock.Random.date('T'),
+ username: '@name()',
+ price: '@float(1000, 15000, 0, 2)',
+ 'status|1': ['success', 'pending']
+ }]
+ }
+ }
+ }
+ }
+]
diff --git a/mock/role/index.js b/mock/role/index.js
new file mode 100644
index 00000000000..4643f006d9c
--- /dev/null
+++ b/mock/role/index.js
@@ -0,0 +1,98 @@
+const Mock = require('mockjs')
+const { deepClone } = require('../utils')
+const { asyncRoutes, constantRoutes } = require('./routes.js')
+
+const routes = deepClone([...constantRoutes, ...asyncRoutes])
+
+const roles = [
+ {
+ key: 'admin',
+ name: 'admin',
+ description: 'Super Administrator. Have access to view all pages.',
+ routes: routes
+ },
+ {
+ key: 'editor',
+ name: 'editor',
+ description: 'Normal Editor. Can see all pages except permission page',
+ routes: routes.filter(i => i.path !== '/permission')// just a mock
+ },
+ {
+ key: 'visitor',
+ name: 'visitor',
+ description: 'Just a visitor. Can only see the home page and the document page',
+ routes: [{
+ path: '',
+ redirect: 'dashboard',
+ children: [
+ {
+ path: 'dashboard',
+ name: 'Dashboard',
+ meta: { title: 'dashboard', icon: 'dashboard' }
+ }
+ ]
+ }]
+ }
+]
+
+module.exports = [
+ // mock get all routes form server
+ {
+ url: '/vue-element-admin/routes',
+ type: 'get',
+ response: _ => {
+ return {
+ code: 20000,
+ data: routes
+ }
+ }
+ },
+
+ // mock get all roles form server
+ {
+ url: '/vue-element-admin/roles',
+ type: 'get',
+ response: _ => {
+ return {
+ code: 20000,
+ data: roles
+ }
+ }
+ },
+
+ // add role
+ {
+ url: '/vue-element-admin/role',
+ type: 'post',
+ response: {
+ code: 20000,
+ data: {
+ key: Mock.mock('@integer(300, 5000)')
+ }
+ }
+ },
+
+ // update role
+ {
+ url: '/vue-element-admin/role/[A-Za-z0-9]',
+ type: 'put',
+ response: {
+ code: 20000,
+ data: {
+ status: 'success'
+ }
+ }
+ },
+
+ // delete role
+ {
+ url: '/vue-element-admin/role/[A-Za-z0-9]',
+ type: 'delete',
+ response: {
+ code: 20000,
+ data: {
+ status: 'success'
+ }
+ }
+ }
+]
diff --git a/mock/role/routes.js b/mock/role/routes.js
new file mode 100644
index 00000000000..d33f1624418
--- /dev/null
+++ b/mock/role/routes.js
@@ -0,0 +1,530 @@
+// Just a mock data
+
+const constantRoutes = [
+ {
+ path: '/redirect',
+ component: 'layout/Layout',
+ hidden: true,
+ children: [
+ {
+ path: '/redirect/:path*',
+ component: 'views/redirect/index'
+ }
+ ]
+ },
+ {
+ path: '/login',
+ component: 'views/login/index',
+ hidden: true
+ },
+ {
+ path: '/auth-redirect',
+ component: 'views/login/auth-redirect',
+ hidden: true
+ },
+ {
+ path: '/404',
+ component: 'views/error-page/404',
+ hidden: true
+ },
+ {
+ path: '/401',
+ component: 'views/error-page/401',
+ hidden: true
+ },
+ {
+ path: '',
+ component: 'layout/Layout',
+ redirect: 'dashboard',
+ children: [
+ {
+ path: 'dashboard',
+ component: 'views/dashboard/index',
+ name: 'Dashboard',
+ meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
+ }
+ ]
+ },
+ {
+ path: '/documentation',
+ component: 'layout/Layout',
+ children: [
+ {
+ path: 'index',
+ component: 'views/documentation/index',
+ name: 'Documentation',
+ meta: { title: 'Documentation', icon: 'documentation', affix: true }
+ }
+ ]
+ },
+ {
+ path: '/guide',
+ component: 'layout/Layout',
+ redirect: '/guide/index',
+ children: [
+ {
+ path: 'index',
+ component: 'views/guide/index',
+ name: 'Guide',
+ meta: { title: 'Guide', icon: 'guide', noCache: true }
+ }
+ ]
+ }
+]
+
+const asyncRoutes = [
+ {
+ path: '/permission',
+ component: 'layout/Layout',
+ redirect: '/permission/index',
+ alwaysShow: true,
+ meta: {
+ title: 'Permission',
+ icon: 'lock',
+ roles: ['admin', 'editor']
+ },
+ children: [
+ {
+ path: 'page',
+ component: 'views/permission/page',
+ name: 'PagePermission',
+ meta: {
+ title: 'Page Permission',
+ roles: ['admin']
+ }
+ },
+ {
+ path: 'directive',
+ component: 'views/permission/directive',
+ name: 'DirectivePermission',
+ meta: {
+ title: 'Directive Permission'
+ }
+ },
+ {
+ path: 'role',
+ component: 'views/permission/role',
+ name: 'RolePermission',
+ meta: {
+ title: 'Role Permission',
+ roles: ['admin']
+ }
+ }
+ ]
+ },
+
+ {
+ path: '/icon',
+ component: 'layout/Layout',
+ children: [
+ {
+ path: 'index',
+ component: 'views/icons/index',
+ name: 'Icons',
+ meta: { title: 'Icons', icon: 'icon', noCache: true }
+ }
+ ]
+ },
+
+ {
+ path: '/components',
+ component: 'layout/Layout',
+ redirect: 'noRedirect',
+ name: 'ComponentDemo',
+ meta: {
+ title: 'Components',
+ icon: 'component'
+ },
+ children: [
+ {
+ path: 'tinymce',
+ component: 'views/components-demo/tinymce',
+ name: 'TinymceDemo',
+ meta: { title: 'Tinymce' }
+ },
+ {
+ path: 'markdown',
+ component: 'views/components-demo/markdown',
+ name: 'MarkdownDemo',
+ meta: { title: 'Markdown' }
+ },
+ {
+ path: 'json-editor',
+ component: 'views/components-demo/json-editor',
+ name: 'JsonEditorDemo',
+ meta: { title: 'Json Editor' }
+ },
+ {
+ path: 'split-pane',
+ component: 'views/components-demo/split-pane',
+ name: 'SplitpaneDemo',
+ meta: { title: 'SplitPane' }
+ },
+ {
+ path: 'avatar-upload',
+ component: 'views/components-demo/avatar-upload',
+ name: 'AvatarUploadDemo',
+ meta: { title: 'Avatar Upload' }
+ },
+ {
+ path: 'dropzone',
+ component: 'views/components-demo/dropzone',
+ name: 'DropzoneDemo',
+ meta: { title: 'Dropzone' }
+ },
+ {
+ path: 'sticky',
+ component: 'views/components-demo/sticky',
+ name: 'StickyDemo',
+ meta: { title: 'Sticky' }
+ },
+ {
+ path: 'count-to',
+ component: 'views/components-demo/count-to',
+ name: 'CountToDemo',
+ meta: { title: 'Count To' }
+ },
+ {
+ path: 'mixin',
+ component: 'views/components-demo/mixin',
+ name: 'ComponentMixinDemo',
+ meta: { title: 'componentMixin' }
+ },
+ {
+ path: 'back-to-top',
+ component: 'views/components-demo/back-to-top',
+ name: 'BackToTopDemo',
+ meta: { title: 'Back To Top' }
+ },
+ {
+ path: 'drag-dialog',
+ component: 'views/components-demo/drag-dialog',
+ name: 'DragDialogDemo',
+ meta: { title: 'Drag Dialog' }
+ },
+ {
+ path: 'drag-select',
+ component: 'views/components-demo/drag-select',
+ name: 'DragSelectDemo',
+ meta: { title: 'Drag Select' }
+ },
+ {
+ path: 'dnd-list',
+ component: 'views/components-demo/dnd-list',
+ name: 'DndListDemo',
+ meta: { title: 'Dnd List' }
+ },
+ {
+ path: 'drag-kanban',
+ component: 'views/components-demo/drag-kanban',
+ name: 'DragKanbanDemo',
+ meta: { title: 'Drag Kanban' }
+ }
+ ]
+ },
+ {
+ path: '/charts',
+ component: 'layout/Layout',
+ redirect: 'noRedirect',
+ name: 'Charts',
+ meta: {
+ title: 'Charts',
+ icon: 'chart'
+ },
+ children: [
+ {
+ path: 'keyboard',
+ component: 'views/charts/keyboard',
+ name: 'KeyboardChart',
+ meta: { title: 'Keyboard Chart', noCache: true }
+ },
+ {
+ path: 'line',
+ component: 'views/charts/line',
+ name: 'LineChart',
+ meta: { title: 'Line Chart', noCache: true }
+ },
+ {
+ path: 'mixchart',
+ component: 'views/charts/mixChart',
+ name: 'MixChart',
+ meta: { title: 'Mix Chart', noCache: true }
+ }
+ ]
+ },
+ {
+ path: '/nested',
+ component: 'layout/Layout',
+ redirect: '/nested/menu1/menu1-1',
+ name: 'Nested',
+ meta: {
+ title: 'Nested',
+ icon: 'nested'
+ },
+ children: [
+ {
+ path: 'menu1',
+ component: 'views/nested/menu1/index',
+ name: 'Menu1',
+ meta: { title: 'Menu1' },
+ redirect: '/nested/menu1/menu1-1',
+ children: [
+ {
+ path: 'menu1-1',
+ component: 'views/nested/menu1/menu1-1',
+ name: 'Menu1-1',
+ meta: { title: 'Menu1-1' }
+ },
+ {
+ path: 'menu1-2',
+ component: 'views/nested/menu1/menu1-2',
+ name: 'Menu1-2',
+ redirect: '/nested/menu1/menu1-2/menu1-2-1',
+ meta: { title: 'Menu1-2' },
+ children: [
+ {
+ path: 'menu1-2-1',
+ component: 'views/nested/menu1/menu1-2/menu1-2-1',
+ name: 'Menu1-2-1',
+ meta: { title: 'Menu1-2-1' }
+ },
+ {
+ path: 'menu1-2-2',
+ component: 'views/nested/menu1/menu1-2/menu1-2-2',
+ name: 'Menu1-2-2',
+ meta: { title: 'Menu1-2-2' }
+ }
+ ]
+ },
+ {
+ path: 'menu1-3',
+ component: 'views/nested/menu1/menu1-3',
+ name: 'Menu1-3',
+ meta: { title: 'Menu1-3' }
+ }
+ ]
+ },
+ {
+ path: 'menu2',
+ name: 'Menu2',
+ component: 'views/nested/menu2/index',
+ meta: { title: 'Menu2' }
+ }
+ ]
+ },
+
+ {
+ path: '/example',
+ component: 'layout/Layout',
+ redirect: '/example/list',
+ name: 'Example',
+ meta: {
+ title: 'Example',
+ icon: 'example'
+ },
+ children: [
+ {
+ path: 'create',
+ component: 'views/example/create',
+ name: 'CreateArticle',
+ meta: { title: 'Create Article', icon: 'edit' }
+ },
+ {
+ path: 'edit/:id(\\d+)',
+ component: 'views/example/edit',
+ name: 'EditArticle',
+ meta: { title: 'Edit Article', noCache: true },
+ hidden: true
+ },
+ {
+ path: 'list',
+ component: 'views/example/list',
+ name: 'ArticleList',
+ meta: { title: 'Article List', icon: 'list' }
+ }
+ ]
+ },
+
+ {
+ path: '/tab',
+ component: 'layout/Layout',
+ children: [
+ {
+ path: 'index',
+ component: 'views/tab/index',
+ name: 'Tab',
+ meta: { title: 'Tab', icon: 'tab' }
+ }
+ ]
+ },
+
+ {
+ path: '/error',
+ component: 'layout/Layout',
+ redirect: 'noRedirect',
+ name: 'ErrorPages',
+ meta: {
+ title: 'Error Pages',
+ icon: '404'
+ },
+ children: [
+ {
+ path: '401',
+ component: 'views/error-page/401',
+ name: 'Page401',
+ meta: { title: 'Page 401', noCache: true }
+ },
+ {
+ path: '404',
+ component: 'views/error-page/404',
+ name: 'Page404',
+ meta: { title: 'Page 404', noCache: true }
+ }
+ ]
+ },
+
+ {
+ path: '/error-log',
+ component: 'layout/Layout',
+ redirect: 'noRedirect',
+ children: [
+ {
+ path: 'log',
+ component: 'views/error-log/index',
+ name: 'ErrorLog',
+ meta: { title: 'Error Log', icon: 'bug' }
+ }
+ ]
+ },
+
+ {
+ path: '/excel',
+ component: 'layout/Layout',
+ redirect: '/excel/export-excel',
+ name: 'Excel',
+ meta: {
+ title: 'Excel',
+ icon: 'excel'
+ },
+ children: [
+ {
+ path: 'export-excel',
+ component: 'views/excel/export-excel',
+ name: 'ExportExcel',
+ meta: { title: 'Export Excel' }
+ },
+ {
+ path: 'export-selected-excel',
+ component: 'views/excel/select-excel',
+ name: 'SelectExcel',
+ meta: { title: 'Select Excel' }
+ },
+ {
+ path: 'export-merge-header',
+ component: 'views/excel/merge-header',
+ name: 'MergeHeader',
+ meta: { title: 'Merge Header' }
+ },
+ {
+ path: 'upload-excel',
+ component: 'views/excel/upload-excel',
+ name: 'UploadExcel',
+ meta: { title: 'Upload Excel' }
+ }
+ ]
+ },
+
+ {
+ path: '/zip',
+ component: 'layout/Layout',
+ redirect: '/zip/download',
+ alwaysShow: true,
+ meta: { title: 'Zip', icon: 'zip' },
+ children: [
+ {
+ path: 'download',
+ component: 'views/zip/index',
+ name: 'ExportZip',
+ meta: { title: 'Export Zip' }
+ }
+ ]
+ },
+
+ {
+ path: '/pdf',
+ component: 'layout/Layout',
+ redirect: '/pdf/index',
+ children: [
+ {
+ path: 'index',
+ component: 'views/pdf/index',
+ name: 'PDF',
+ meta: { title: 'PDF', icon: 'pdf' }
+ }
+ ]
+ },
+ {
+ path: '/pdf/download',
+ component: 'views/pdf/download',
+ hidden: true
+ },
+
+ {
+ path: '/theme',
+ component: 'layout/Layout',
+ redirect: 'noRedirect',
+ children: [
+ {
+ path: 'index',
+ component: 'views/theme/index',
+ name: 'Theme',
+ meta: { title: 'Theme', icon: 'theme' }
+ }
+ ]
+ },
+
+ {
+ path: '/clipboard',
+ component: 'layout/Layout',
+ redirect: 'noRedirect',
+ children: [
+ {
+ path: 'index',
+ component: 'views/clipboard/index',
+ name: 'ClipboardDemo',
+ meta: { title: 'Clipboard Demo', icon: 'clipboard' }
+ }
+ ]
+ },
+
+ {
+ path: '/i18n',
+ component: 'layout/Layout',
+ children: [
+ {
+ path: 'index',
+ component: 'views/i18n-demo/index',
+ name: 'I18n',
+ meta: { title: 'I18n', icon: 'international' }
+ }
+ ]
+ },
+
+ {
+ path: 'external-link',
+ component: 'layout/Layout',
+ children: [
+ {
+ path: 'https://github.com/PanJiaChen/vue-element-admin',
+ meta: { title: 'External Link', icon: 'link' }
+ }
+ ]
+ },
+
+ { path: '*', redirect: '/404', hidden: true }
+]
+
+module.exports = {
+ constantRoutes,
+ asyncRoutes
+}
diff --git a/mock/user.js b/mock/user.js
new file mode 100644
index 00000000000..d82e079d58c
--- /dev/null
+++ b/mock/user.js
@@ -0,0 +1,84 @@
+
+const tokens = {
+ 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'
+ }
+}
+
+module.exports = [
+ // user login
+ {
+ url: '/vue-element-admin/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.'
+ }
+ }
+
+ return {
+ code: 20000,
+ data: token
+ }
+ }
+ },
+
+ // get user info
+ {
+ url: '/vue-element-admin/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.'
+ }
+ }
+
+ return {
+ code: 20000,
+ data: info
+ }
+ }
+ },
+
+ // user logout
+ {
+ url: '/vue-element-admin/user/logout',
+ type: 'post',
+ response: _ => {
+ return {
+ code: 20000,
+ data: 'success'
+ }
+ }
+ }
+]
diff --git a/mock/utils.js b/mock/utils.js
new file mode 100644
index 00000000000..f909a29362a
--- /dev/null
+++ b/mock/utils.js
@@ -0,0 +1,48 @@
+/**
+ * @param {string} url
+ * @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
+ }
+ })
+ return obj
+}
+
+/**
+ * This is just a simple version of deep copy
+ * Has a lot of edge cases bug
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+ * @param {Object} source
+ * @returns {Object}
+ */
+function deepClone(source) {
+ if (!source && typeof source !== 'object') {
+ throw new Error('error arguments', 'deepClone')
+ }
+ const targetObj = source.constructor === Array ? [] : {}
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
+ }
+ })
+ return targetObj
+}
+
+module.exports = {
+ param2Obj,
+ deepClone
+}
diff --git a/package.json b/package.json
index 168afe3537b..02f68e23764 100644
--- a/package.json
+++ b/package.json
@@ -1,100 +1,111 @@
{
- "name": "juicy",
- "version": "2.2.0",
- "description": "A Vue.js admin",
+ "name": "vue-element-admin",
+ "version": "4.4.0",
+ "description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
"author": "Pan ",
- "license": "MIT",
- "private": true,
"scripts": {
- "dev": "node build/dev-server.js",
- "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
- "build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
- "build:sit-preview": "cross-env NODE_ENV=production env_config=sit npm_config_preview=true npm_config_report=true node build/build.js",
- "lint": "eslint --ext .js,.vue src"
+ "dev": "vue-cli-service serve",
+ "lint": "eslint --ext .js,.vue src",
+ "build:prod": "vue-cli-service build",
+ "build:stage": "vue-cli-service build --mode staging",
+ "preview": "node build/index.js --preview",
+ "new": "plop",
+ "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
+ "test:unit": "jest --clearCache && vue-cli-service test:unit",
+ "test:ci": "npm run lint && npm run test:unit"
},
"dependencies": {
- "axios": "0.16.2",
- "clipboard": "1.7.1",
- "codemirror": "5.26.0",
- "dropzone": "5.1.0",
- "echarts": "3.7.2",
- "element-ui": "1.4.2",
- "file-saver": "1.3.3",
- "js-cookie": "2.1.4",
- "jsonlint": "1.6.2",
- "mockjs": "1.0.1-beta3",
+ "axios": "0.18.1",
+ "clipboard": "2.0.4",
+ "codemirror": "5.45.0",
+ "core-js": "3.6.5",
+ "driver.js": "0.9.5",
+ "dropzone": "5.5.1",
+ "echarts": "4.2.1",
+ "element-ui": "2.13.2",
+ "file-saver": "2.0.1",
+ "fuse.js": "3.4.4",
+ "js-cookie": "2.2.0",
+ "jsonlint": "1.6.3",
+ "jszip": "3.2.1",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
- "screenfull": "3.2.2",
- "showdown": "1.7.1",
- "simplemde": "1.11.2",
- "sortablejs": "1.5.1",
- "vue": "2.4.2",
- "vue-count-to": "1.0.5",
- "vue-multiselect": "2.0.2",
- "vue-router": "2.7.0",
- "vue-splitpane": "^1.0.0",
- "vuedraggable": "2.14.1",
- "vuex": "2.3.1",
- "xlsx": "^0.10.8",
- "jszip": "^3.1.4"
+ "path-to-regexp": "2.4.0",
+ "screenfull": "4.2.0",
+ "script-loader": "0.7.2",
+ "sortablejs": "1.8.4",
+ "tui-editor": "1.3.3",
+ "vue": "2.6.10",
+ "vue-count-to": "1.0.13",
+ "vue-router": "3.0.2",
+ "vue-splitpane": "1.0.4",
+ "vuedraggable": "2.20.0",
+ "vuex": "3.1.0",
+ "xlsx": "0.14.1"
},
"devDependencies": {
- "autoprefixer": "7.1.1",
- "babel-core": "6.25.0",
- "babel-eslint": "7.2.3",
- "babel-loader": "7.0.0",
- "babel-plugin-transform-runtime": "6.23.0",
- "babel-preset-env": "1.5.2",
- "babel-preset-stage-2": "6.24.1",
- "babel-register": "6.24.1",
- "chalk": "1.1.3",
- "connect-history-api-fallback": "1.3.0",
- "copy-webpack-plugin": "4.0.1",
- "cross-env": "5.0.1",
- "css-loader": "0.28.4",
- "eslint": "3.19.0",
- "eslint-friendly-formatter": "3.0.0",
- "eslint-import-resolver-webpack": "0.8.1",
- "eslint-loader": "1.7.1",
- "eslint-plugin-html": "3.0.0",
- "eslint-plugin-import": "2.3.0",
- "eventsource-polyfill": "0.9.6",
- "express": "4.15.3",
- "extract-text-webpack-plugin": "2.1.2",
- "file-loader": "0.11.2",
- "friendly-errors-webpack-plugin": "1.6.1",
- "function-bind": "1.1.0",
- "html-webpack-plugin": "2.28.0",
- "http-proxy-middleware": "0.17.4",
- "node-sass": "^4.5.0",
- "opn": "4.0.2",
- "optimize-css-assets-webpack-plugin": "1.3.0",
- "ora": "1.1.0",
- "pushstate-server": "2.1.0",
- "rimraf": "2.6.0",
- "sass-loader": "6.0.5",
- "script-loader": "0.7.0",
- "semver": "5.3.0",
- "style-loader": "0.17.0",
- "svg-sprite-loader": "3.2.4",
- "url-loader": "0.5.8",
- "vue-loader": "13.0.4",
- "vue-style-loader": "3.0.1",
- "vue-template-compiler": "2.4.2",
- "webpack": "2.6.1",
- "webpack-bundle-analyzer": "2.8.2",
- "webpack-dev-middleware": "1.10.2",
- "webpack-hot-middleware": "2.18.0",
- "webpack-merge": "4.1.0"
+ "@vue/cli-plugin-babel": "4.4.4",
+ "@vue/cli-plugin-eslint": "4.4.4",
+ "@vue/cli-plugin-unit-jest": "4.4.4",
+ "@vue/cli-service": "4.4.4",
+ "@vue/test-utils": "1.0.0-beta.29",
+ "autoprefixer": "9.5.1",
+ "babel-eslint": "10.1.0",
+ "babel-jest": "23.6.0",
+ "babel-plugin-dynamic-import-node": "2.3.3",
+ "chalk": "2.4.2",
+ "chokidar": "2.1.5",
+ "connect": "3.6.6",
+ "eslint": "6.7.2",
+ "eslint-plugin-vue": "6.2.2",
+ "html-webpack-plugin": "3.2.0",
+ "husky": "1.3.1",
+ "lint-staged": "8.1.5",
+ "mockjs": "1.0.1-beta3",
+ "plop": "2.3.0",
+ "runjs": "4.3.2",
+ "sass": "1.26.2",
+ "sass-loader": "8.0.2",
+ "script-ext-html-webpack-plugin": "2.1.3",
+ "serve-static": "1.13.2",
+ "svg-sprite-loader": "4.1.3",
+ "svgo": "1.2.0",
+ "vue-template-compiler": "2.6.10"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions"
+ ],
+ "bugs": {
+ "url": "https://github.com/PanJiaChen/vue-element-admin/issues"
},
"engines": {
- "node": ">= 4.0.0",
+ "node": ">=8.9",
"npm": ">= 3.0.0"
},
- "browserslist": [
- "> 1%",
- "last 2 versions",
- "not ie <= 8"
- ]
+ "keywords": [
+ "vue",
+ "admin",
+ "dashboard",
+ "element-ui",
+ "boilerplate",
+ "admin-template",
+ "management-system"
+ ],
+ "license": "MIT",
+ "lint-staged": {
+ "src/**/*.{js,vue}": [
+ "eslint --fix",
+ "git add"
+ ]
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "lint-staged"
+ }
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
+ }
}
diff --git a/plop-templates/component/index.hbs b/plop-templates/component/index.hbs
new file mode 100644
index 00000000000..76610552d74
--- /dev/null
+++ b/plop-templates/component/index.hbs
@@ -0,0 +1,26 @@
+{{#if template}}
+
+
+
+{{/if}}
+
+{{#if script}}
+
+{{/if}}
+
+{{#if style}}
+
+{{/if}}
diff --git a/plop-templates/component/prompt.js b/plop-templates/component/prompt.js
new file mode 100644
index 00000000000..3723e8e1357
--- /dev/null
+++ b/plop-templates/component/prompt.js
@@ -0,0 +1,55 @@
+const { notEmpty } = require('../utils.js')
+
+module.exports = {
+ description: 'generate vue component',
+ prompts: [{
+ type: 'input',
+ name: 'name',
+ message: 'component name please',
+ validate: notEmpty('name')
+ },
+ {
+ type: 'checkbox',
+ name: 'blocks',
+ message: 'Blocks:',
+ choices: [{
+ name: '',
+ value: 'template',
+ checked: true
+ },
+ {
+ name: '
+{{/if}}
+
+{{#if style}}
+
+{{/if}}
diff --git a/plop-templates/view/prompt.js b/plop-templates/view/prompt.js
new file mode 100644
index 00000000000..1d490ee8242
--- /dev/null
+++ b/plop-templates/view/prompt.js
@@ -0,0 +1,55 @@
+const { notEmpty } = require('../utils.js')
+
+module.exports = {
+ description: 'generate a view',
+ prompts: [{
+ type: 'input',
+ name: 'name',
+ message: 'view name please',
+ validate: notEmpty('name')
+ },
+ {
+ type: 'checkbox',
+ name: 'blocks',
+ message: 'Blocks:',
+ choices: [{
+ name: '',
+ value: 'template',
+ checked: true
+ },
+ {
+ name: '
-
-
-
+
+
+