From 3802f6f8d27aa67bdeec4b15eec684f7d833b3fd Mon Sep 17 00:00:00 2001 From: Pan Date: Wed, 10 Oct 2018 17:43:33 +0800 Subject: [PATCH 001/141] fix[ExternalLink]: fixed bug when url include chinese #1182 --- src/utils/index.js | 4 ++++ src/views/layout/components/Sidebar/Link.vue | 4 ++-- src/views/layout/components/Sidebar/SidebarItem.vue | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/utils/index.js b/src/utils/index.js index f607910c4ac..3af8b29b8ba 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -296,3 +296,7 @@ export function deepClone(source) { export function uniqueArr(arr) { return Array.from(new Set(arr)) } + +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} diff --git a/src/views/layout/components/Sidebar/Link.vue b/src/views/layout/components/Sidebar/Link.vue index 07793b9a29b..5d366f246c3 100644 --- a/src/views/layout/components/Sidebar/Link.vue +++ b/src/views/layout/components/Sidebar/Link.vue @@ -7,7 +7,7 @@ + + diff --git a/src/utils/index.js b/src/utils/index.js index 3af8b29b8ba..0445827b32e 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -164,17 +164,6 @@ export function objectMerge(target, source) { return target } -export function scrollTo(element, to, duration) { - if (duration <= 0) return - const difference = to - element.scrollTop - const perTick = (difference / duration) * 10 - setTimeout(() => { - element.scrollTop = element.scrollTop + perTick - if (element.scrollTop === to) return - scrollTo(element, to, duration - 10) - }, 10) -} - export function toggleClass(element, className) { if (!element || !className) { return diff --git a/src/utils/scrollTo.js b/src/utils/scrollTo.js new file mode 100644 index 00000000000..8affede6df2 --- /dev/null +++ b/src/utils/scrollTo.js @@ -0,0 +1,50 @@ +Math.easeInOutQuad = function(t, b, c, d) { + t /= d / 2 + if (t < 1) { + return c / 2 * t * t + b + } + t-- + return -c / 2 * (t * (t - 2) - 1) + b +} + +// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts +var requestAnimFrame = (function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } +})() + +// because it's so fucking difficult to detect the scrolling element, just move them all +function move(amount) { + document.documentElement.scrollTop = amount + document.body.parentNode.scrollTop = amount + document.body.scrollTop = amount +} + +function position() { + return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop +} + +export function scrollTo(to, duration, callback) { + const start = position() + const change = to - start + const increment = 20 + let currentTime = 0 + duration = (typeof (duration) === 'undefined') ? 500 : duration + var animateScroll = function() { + // increment the time + currentTime += increment + // find the value with the quadratic in-out easing function + var val = Math.easeInOutQuad(currentTime, start, change, duration) + // move the document.body + move(val) + // do the animation unless its over + if (currentTime < duration) { + requestAnimFrame(animateScroll) + } else { + if (callback && typeof (callback) === 'function') { + // the animation is done so lets callback + callback() + } + } + } + animateScroll() +} diff --git a/src/views/example/list.vue b/src/views/example/list.vue index 4ab61d3897b..85ae4e43822 100644 --- a/src/views/example/list.vue +++ b/src/views/example/list.vue @@ -50,26 +50,18 @@ -
- -
+ + + diff --git a/src/lang/en.js b/src/lang/en.js index 021bc66ca12..930f0ad1ff2 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -22,6 +22,7 @@ export default { componentMixin: 'Mixin', backToTop: 'BackToTop', dragDialog: 'Drag Dialog', + dragSelect: 'Drag Select', dragKanban: 'Drag Kanban', charts: 'Charts', keyboardChart: 'Keyboard Chart', diff --git a/src/lang/es.js b/src/lang/es.js index 191719045ea..f16044c4316 100755 --- a/src/lang/es.js +++ b/src/lang/es.js @@ -22,6 +22,7 @@ export default { componentMixin: 'Mixin', backToTop: 'Ir arriba', dragDialog: 'Drag Dialog', + dragSelect: 'Drag Select', dragKanban: 'Drag Kanban', charts: 'Gráficos', keyboardChart: 'Keyboard Chart', diff --git a/src/lang/zh.js b/src/lang/zh.js index 9da9e9e4bf1..46e96ccf5c5 100644 --- a/src/lang/zh.js +++ b/src/lang/zh.js @@ -22,6 +22,7 @@ export default { componentMixin: '小组件', backToTop: '返回顶部', dragDialog: '拖拽 Dialog', + dragSelect: '拖拽 Select', dragKanban: '可拖拽看板', charts: '图表', keyboardChart: '键盘图表', diff --git a/src/router/modules/components.js b/src/router/modules/components.js index 56dad2b124e..5fd9bd2955e 100644 --- a/src/router/modules/components.js +++ b/src/router/modules/components.js @@ -78,6 +78,12 @@ const componentsRouter = { name: 'DragDialogDemo', meta: { title: 'dragDialog' } }, + { + path: 'drag-select', + component: () => import('@/views/components-demo/dragSelect'), + name: 'DragSelectDemo', + meta: { title: 'dragSelect' } + }, { path: 'dnd-list', component: () => import('@/views/components-demo/dndList'), diff --git a/src/views/components-demo/dragSelect.vue b/src/views/components-demo/dragSelect.vue new file mode 100644 index 00000000000..559e8a57880 --- /dev/null +++ b/src/views/components-demo/dragSelect.vue @@ -0,0 +1,43 @@ + + + From 40a7626acb3dd5c64052c0d0a220f7fb3e3e104e Mon Sep 17 00:00:00 2001 From: zthxxx Date: Mon, 29 Oct 2018 13:55:36 +0800 Subject: [PATCH 014/141] feat: perfect migrate to @vue/cli-service, upgrade vue babel version (#1267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: perfect migrate to @vue/cli-service, upgrade vue babel version 1. update to @vue/cli-service@3.0.5, @babel/core@7.0.0 2. use vue-cli service replace config file in build/ and config/ 3. upgrade vue and babel configuration 4. solve the svg-sprite config problem #980 refs: #932 #1087 #980 #1056 * fix: fix breadcrumb dependency * fix: fix index template and static assets load with vue-cli 3 * fix: fix import driver.js in guide page * refactor(mock): mak mock api compatible with both web-view and webpack server 1. 把 Mockjs 功能移到 server 端中间件,同时也兼容前端直接劫持 XHR 2. dev 环境下默认作为 express 中间件通过 webpack server 提供 mock api 3. prod 构建时,默认在前端用 Mockjs 劫持 XHR benefits: - dev 开发调试时能直接看到 XHR 请求,方便调试网络,能和后端对接联调 - 避开在开发时因为 Mockjs 引起的网络 bug - prod 构建时劫持 XHR,保证本项目的 Github Pages preview 能正常显示 (逻辑和 error-log 一样) - 前后台使用的 mock 是同一份代码,不会增加维护负担 ref: [#562](https://github.com/PanJiaChen/vue-element-admin/issues/562#issuecomment-378116233) * update requires the lowest version of node * add favicon * fix(TreeTable): fix `Array.prototype.concat` on custom-tree-table page --- .babelrc | 17 -- .env | 1 + .env.development | 1 + .env.production | 1 + .gitignore | 2 + babel.config.js | 14 ++ build/build.js | 67 ------- build/check-versions.js | 64 ------ build/logo.png | Bin 6849 -> 0 bytes build/utils.js | 108 ---------- build/vue-loader.conf.js | 5 - build/webpack.base.conf.js | 107 ---------- build/webpack.dev.conf.js | 98 --------- build/webpack.prod.conf.js | 188 ------------------ config/dev.env.js | 5 - config/index.js | 88 -------- config/prod.env.js | 5 - config/sit.env.js | 5 - {src/mock => mock}/article.js | 28 +-- mock/index.js | 50 +++++ {src/mock => mock}/login.js | 15 +- mock/mocks.js | 12 ++ {src/mock => mock}/remoteSearch.js | 8 +- mock/transaction.js | 16 ++ package.json | 61 ++---- public/favicon.ico | Bin 0 -> 67646 bytes index.html => public/index.html | 3 +- .../static}/tinymce4.7.5/langs/zh_CN.js | 0 .../plugins/codesample/css/prism.css | 0 .../plugins/emoticons/img/smiley-cool.gif | Bin .../plugins/emoticons/img/smiley-cry.gif | Bin .../emoticons/img/smiley-embarassed.gif | Bin .../emoticons/img/smiley-foot-in-mouth.gif | Bin .../plugins/emoticons/img/smiley-frown.gif | Bin .../plugins/emoticons/img/smiley-innocent.gif | Bin .../plugins/emoticons/img/smiley-kiss.gif | Bin .../plugins/emoticons/img/smiley-laughing.gif | Bin .../emoticons/img/smiley-money-mouth.gif | Bin .../plugins/emoticons/img/smiley-sealed.gif | Bin .../plugins/emoticons/img/smiley-smile.gif | Bin .../emoticons/img/smiley-surprised.gif | Bin .../emoticons/img/smiley-tongue-out.gif | Bin .../emoticons/img/smiley-undecided.gif | Bin .../plugins/emoticons/img/smiley-wink.gif | Bin .../plugins/emoticons/img/smiley-yell.gif | Bin .../plugins/visualblocks/css/visualblocks.css | 0 .../skins/lightgray/content.inline.min.css | 0 .../skins/lightgray/content.min.css | 0 .../skins/lightgray/fonts/tinymce-mobile.woff | Bin .../skins/lightgray/fonts/tinymce-small.eot | Bin .../skins/lightgray/fonts/tinymce-small.svg | 0 .../skins/lightgray/fonts/tinymce-small.ttf | Bin .../skins/lightgray/fonts/tinymce-small.woff | Bin .../skins/lightgray/fonts/tinymce.eot | Bin .../skins/lightgray/fonts/tinymce.svg | 0 .../skins/lightgray/fonts/tinymce.ttf | Bin .../skins/lightgray/fonts/tinymce.woff | Bin .../skins/lightgray/img/anchor.gif | Bin .../skins/lightgray/img/loader.gif | Bin .../skins/lightgray/img/object.gif | Bin .../skins/lightgray/img/trans.gif | Bin .../tinymce4.7.5/skins/lightgray/skin.min.css | 0 .../skins/lightgray/skin.min.css.map | 0 .../static}/tinymce4.7.5/tinymce.min.js | 0 src/components/TreeTable/index.vue | 2 +- src/main.js | 6 +- src/mock/index.js | 39 ---- src/mock/transaction.js | 23 --- src/utils/request.js | 3 +- src/views/guide/index.vue | 2 +- vue.config.js | 60 ++++++ 71 files changed, 211 insertions(+), 893 deletions(-) delete mode 100644 .babelrc create mode 100644 .env create mode 100644 .env.development create mode 100644 .env.production create mode 100644 babel.config.js delete mode 100644 build/build.js delete mode 100644 build/check-versions.js delete mode 100644 build/logo.png delete mode 100644 build/utils.js delete mode 100644 build/vue-loader.conf.js delete mode 100644 build/webpack.base.conf.js delete mode 100644 build/webpack.dev.conf.js delete mode 100644 build/webpack.prod.conf.js delete mode 100644 config/dev.env.js delete mode 100644 config/index.js delete mode 100644 config/prod.env.js delete mode 100644 config/sit.env.js rename {src/mock => mock}/article.js (81%) create mode 100644 mock/index.js rename {src/mock => mock}/login.js (72%) create mode 100644 mock/mocks.js rename {src/mock => mock}/remoteSearch.js (64%) create mode 100644 mock/transaction.js create mode 100644 public/favicon.ico rename index.html => public/index.html (75%) rename {static => public/static}/tinymce4.7.5/langs/zh_CN.js (100%) rename {static => public/static}/tinymce4.7.5/plugins/codesample/css/prism.css (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif (100%) rename {static => public/static}/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/content.inline.min.css (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/content.min.css (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.svg (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce.svg (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/img/anchor.gif (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/img/loader.gif (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/img/object.gif (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/img/trans.gif (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/skin.min.css (100%) rename {static => public/static}/tinymce4.7.5/skins/lightgray/skin.min.css.map (100%) rename {static => public/static}/tinymce4.7.5/tinymce.min.js (100%) delete mode 100644 src/mock/index.js delete mode 100644 src/mock/transaction.js create mode 100644 vue.config.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 6c0b7f27e43..00000000000 --- a/.babelrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "presets": [ - ["env", { - "modules": false, - "targets": { - "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] - } - }], - "stage-2" - ], - "plugins": ["transform-vue-jsx", "transform-runtime"], - "env": { - "development":{ - "plugins": ["dynamic-import-node"] - } - } -} diff --git a/.env b/.env new file mode 100644 index 00000000000..31bc290af50 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/.env.development b/.env.development new file mode 100644 index 00000000000..1d2d6c9f82f --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +VUE_APP_BASE_API = '/api' diff --git a/.env.production b/.env.production new file mode 100644 index 00000000000..1d2d6c9f82f --- /dev/null +++ b/.env.production @@ -0,0 +1 @@ +VUE_APP_BASE_API = '/api' diff --git a/.gitignore b/.gitignore index 9322b8a68d2..887ce1ed073 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,7 @@ selenium-debug.log *.ntvs* *.njsproj *.sln +*.local package-lock.json +yarn.lock diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000000..6f812f6161d --- /dev/null +++ b/babel.config.js @@ -0,0 +1,14 @@ +module.exports = { + presets: [ + ['@vue/app', { modules: 'commonjs' }] + ], + plugins: [], + env: { + test: { + presets: [ + ['@vue/app', { modules: 'commonjs' }] + ], + plugins: ['istanbul'] + } + } +} diff --git a/build/build.js b/build/build.js deleted file mode 100644 index 34c71a55477..00000000000 --- a/build/build.js +++ /dev/null @@ -1,67 +0,0 @@ -'use strict' -require('./check-versions')() - -const ora = require('ora') -const rm = require('rimraf') -const path = require('path') -const chalk = require('chalk') -const webpack = require('webpack') -const config = require('../config') -const webpackConfig = require('./webpack.prod.conf') -var connect = require('connect') -var serveStatic = require('serve-static') - -const spinner = ora( - 'building for ' + process.env.env_config + ' environment...' -) -spinner.start() - -rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { - if (err) throw err - webpack(webpackConfig, (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' - ) - - if (stats.hasErrors()) { - console.log(chalk.red(' Build failed with errors.\n')) - process.exit(1) - } - - console.log(chalk.cyan(' Build complete.\n')) - console.log( - chalk.yellow( - ' Tip: built files are meant to be served over an HTTP server.\n' + - " Opening index.html over file:// won't work.\n" - ) - ) - - if (process.env.npm_config_preview) { - const port = 9526 - const host = 'http://localhost:' + port - const basePath = config.build.assetsPublicPath - const app = connect() - - app.use( - basePath, - serveStatic('./dist', { - index: ['index.html', '/'] - }) - ) - - app.listen(port, function() { - console.log( - chalk.green(`> Listening at http://localhost:${port}${basePath}`) - ) - }) - } - }) -}) diff --git a/build/check-versions.js b/build/check-versions.js deleted file mode 100644 index c5c29e90f46..00000000000 --- a/build/check-versions.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' -const chalk = require('chalk') -const semver = require('semver') -const packageConfig = require('../package.json') -const shell = require('shelljs') - -function exec(cmd) { - return require('child_process') - .execSync(cmd) - .toString() - .trim() -} - -const versionRequirements = [ - { - name: 'node', - currentVersion: semver.clean(process.version), - versionRequirement: packageConfig.engines.node - } -] - -if (shell.which('npm')) { - versionRequirements.push({ - name: 'npm', - currentVersion: exec('npm --version'), - versionRequirement: packageConfig.engines.npm - }) -} - -module.exports = function() { - const warnings = [] - - for (let i = 0; i < versionRequirements.length; i++) { - const 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 (let i = 0; i < warnings.length; i++) { - const warning = warnings[i] - console.log(' ' + warning) - } - - console.log() - process.exit(1) - } -} diff --git a/build/logo.png b/build/logo.png deleted file mode 100644 index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6849 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 { - const notifier = require('node-notifier') - - return (severity, errors) => { - if (severity !== 'error') return - - const error = errors[0] - const filename = error.file && error.file.split('!').pop() - - notifier.notify({ - title: packageConfig.name, - message: severity + ': ' + error.name, - subtitle: filename || '', - icon: path.join(__dirname, 'logo.png') - }) - } -} diff --git a/build/vue-loader.conf.js b/build/vue-loader.conf.js deleted file mode 100644 index 5496c9317fd..00000000000 --- a/build/vue-loader.conf.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict' - -module.exports = { - //You can set the vue-loader configuration by yourself. -} diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js deleted file mode 100644 index 3b946b4b242..00000000000 --- a/build/webpack.base.conf.js +++ /dev/null @@ -1,107 +0,0 @@ -'use strict' -const path = require('path') -const utils = require('./utils') -const config = require('../config') -const { VueLoaderPlugin } = require('vue-loader') -const vueLoaderConfig = require('./vue-loader.conf') - -function resolve(dir) { - return path.join(__dirname, '..', dir) -} - -const createLintingRule = () => ({ - test: /\.(js|vue)$/, - loader: 'eslint-loader', - enforce: 'pre', - include: [resolve('src'), resolve('test')], - options: { - formatter: require('eslint-friendly-formatter'), - emitWarning: !config.dev.showEslintErrorsInOverlay - } -}) - -module.exports = { - context: path.resolve(__dirname, '../'), - 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: { - '@': resolve('src') - } - }, - module: { - rules: [ - ...(config.dev.useEslint ? [createLintingRule()] : []), - { - test: /\.vue$/, - loader: 'vue-loader', - options: vueLoaderConfig - }, - { - test: /\.js$/, - loader: 'babel-loader?cacheDirectory', - include: [ - resolve('src'), - resolve('test'), - resolve('node_modules/webpack-dev-server/client') - ] - }, - { - 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: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, - loader: 'url-loader', - options: { - limit: 10000, - name: utils.assetsPath('media/[name].[hash:7].[ext]') - } - }, - { - test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, - loader: 'url-loader', - options: { - limit: 10000, - name: utils.assetsPath('fonts/[name].[hash:7].[ext]') - } - } - ] - }, - plugins: [new VueLoaderPlugin()], - node: { - // prevent webpack from injecting useless setImmediate polyfill because Vue - // source contains it (although only uses it if it's native). - setImmediate: false, - // prevent webpack from injecting mocks to Node native modules - // that does not make sense for the client - dgram: 'empty', - fs: 'empty', - net: 'empty', - tls: 'empty', - child_process: 'empty' - } -} diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js deleted file mode 100644 index 26a5584a868..00000000000 --- a/build/webpack.dev.conf.js +++ /dev/null @@ -1,98 +0,0 @@ -'use strict' -const path = require('path') -const utils = require('./utils') -const webpack = require('webpack') -const config = require('../config') -const merge = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.conf') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') -const portfinder = require('portfinder') - -function resolve(dir) { - return path.join(__dirname, '..', dir) -} - -const HOST = process.env.HOST -const PORT = process.env.PORT && Number(process.env.PORT) - -const devWebpackConfig = merge(baseWebpackConfig, { - mode: 'development', - module: { - rules: utils.styleLoaders({ - sourceMap: config.dev.cssSourceMap, - usePostCSS: true - }) - }, - // cheap-module-eval-source-map is faster for development - devtool: config.dev.devtool, - - // these devServer options should be customized in /config/index.js - devServer: { - clientLogLevel: 'warning', - historyApiFallback: true, - hot: true, - compress: true, - host: HOST || config.dev.host, - port: PORT || config.dev.port, - open: config.dev.autoOpenBrowser, - overlay: config.dev.errorOverlay - ? { warnings: false, errors: true } - : false, - publicPath: config.dev.assetsPublicPath, - proxy: config.dev.proxyTable, - quiet: true, // necessary for FriendlyErrorsPlugin - watchOptions: { - poll: config.dev.poll - } - }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env': require('../config/dev.env') - }), - new webpack.HotModuleReplacementPlugin(), - // https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: 'index.html', - template: 'index.html', - inject: true, - favicon: resolve('favicon.ico'), - title: 'vue-element-admin', - templateParameters: { - BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory, - }, - }), - ] -}) - -module.exports = new Promise((resolve, reject) => { - portfinder.basePort = process.env.PORT || config.dev.port - portfinder.getPort((err, port) => { - if (err) { - reject(err) - } else { - // publish the new Port, necessary for e2e tests - process.env.PORT = port - // add port to devServer config - devWebpackConfig.devServer.port = port - - // Add FriendlyErrorsPlugin - devWebpackConfig.plugins.push( - new FriendlyErrorsPlugin({ - compilationSuccessInfo: { - messages: [ - `Your application is running here: http://${ - devWebpackConfig.devServer.host - }:${port}` - ] - }, - onErrors: config.dev.notifyOnErrors - ? utils.createNotifierCallback() - : undefined - }) - ) - - resolve(devWebpackConfig) - } - }) -}) diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js deleted file mode 100644 index 946a134a55a..00000000000 --- a/build/webpack.prod.conf.js +++ /dev/null @@ -1,188 +0,0 @@ -'use strict' -const path = require('path') -const utils = require('./utils') -const webpack = require('webpack') -const config = require('../config') -const merge = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.conf') -const CopyWebpackPlugin = require('copy-webpack-plugin') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin') -const MiniCssExtractPlugin = require('mini-css-extract-plugin') -const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') -const UglifyJsPlugin = require('uglifyjs-webpack-plugin') - -function resolve(dir) { - return path.join(__dirname, '..', dir) -} - -const env = require('../config/' + process.env.env_config + '.env') - -// For NamedChunksPlugin -const seen = new Set() -const nameLength = 4 - -const webpackConfig = merge(baseWebpackConfig, { - mode: 'production', - module: { - rules: utils.styleLoaders({ - sourceMap: config.build.productionSourceMap, - extract: true, - usePostCSS: true - }) - }, - devtool: config.build.productionSourceMap ? config.build.devtool : false, - output: { - path: config.build.assetsRoot, - filename: utils.assetsPath('js/[name].[chunkhash:8].js'), - chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js') - }, - plugins: [ - // http://vuejs.github.io/vue-loader/en/workflow/production.html - new webpack.DefinePlugin({ - 'process.env': env - }), - // extract css into its own file - new MiniCssExtractPlugin({ - filename: utils.assetsPath('css/[name].[contenthash:8].css'), - chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css') - }), - // 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: config.build.index, - template: 'index.html', - inject: true, - favicon: resolve('favicon.ico'), - title: 'vue-element-admin', - templateParameters: { - BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory, - }, - minify: { - removeComments: true, - collapseWhitespace: true, - removeAttributeQuotes: true - // more options: - // https://github.com/kangax/html-minifier#options-quick-reference - } - // default sort mode uses toposort which cannot handle cyclic deps - // in certain cases, and in webpack 4, chunk order in HTML doesn't - // matter anyway - }), - new ScriptExtHtmlWebpackPlugin({ - //`runtime` must same as runtimeChunk name. default is `runtime` - inline: /runtime\..*\.js$/ - }), - // keep chunk.id stable when chunk has no name - new webpack.NamedChunksPlugin(chunk => { - if (chunk.name) { - return chunk.name - } - const modules = Array.from(chunk.modulesIterable) - if (modules.length > 1) { - const hash = require('hash-sum') - const joinedHash = hash(modules.map(m => m.id).join('_')) - let len = nameLength - while (seen.has(joinedHash.substr(0, len))) len++ - seen.add(joinedHash.substr(0, len)) - return `chunk-${joinedHash.substr(0, len)}` - } else { - return modules[0].id - } - }), - // keep module.id stable when vender modules does not change - new webpack.HashedModuleIdsPlugin(), - // copy custom static assets - new CopyWebpackPlugin([ - { - from: path.resolve(__dirname, '../static'), - to: config.build.assetsSubDirectory, - ignore: ['.*'] - } - ]) - ], - optimization: { - splitChunks: { - chunks: 'all', - cacheGroups: { - libs: { - name: 'chunk-libs', - test: /[\\/]node_modules[\\/]/, - priority: 10, - chunks: 'initial' // 只打包初始时依赖的第三方 - }, - elementUI: { - name: 'chunk-elementUI', // 单独将 elementUI 拆包 - priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app - test: /[\\/]node_modules[\\/]element-ui[\\/]/ - }, - commons: { - name: 'chunk-commons', - test: resolve('src/components'), // 可自定义拓展你的规则 - minChunks: 3, // 最小公用次数 - priority: 5, - reuseExistingChunk: true - } - } - }, - runtimeChunk: 'single', - minimizer: [ - new UglifyJsPlugin({ - uglifyOptions: { - mangle: { - safari10: true - } - }, - sourceMap: config.build.productionSourceMap, - cache: true, - parallel: true - }), - // Compress extracted CSS. We are using this plugin so that possible - // duplicated CSS from different components can be deduped. - new OptimizeCSSAssetsPlugin() - ] - } -}) - -if (config.build.productionGzip) { - const CompressionWebpackPlugin = require('compression-webpack-plugin') - - webpackConfig.plugins.push( - new CompressionWebpackPlugin({ - asset: '[path].gz[query]', - algorithm: 'gzip', - test: new RegExp( - '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' - ), - threshold: 10240, - minRatio: 0.8 - }) - ) -} - -if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) { - const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') - .BundleAnalyzerPlugin - - if (config.build.bundleAnalyzerReport) { - webpackConfig.plugins.push( - new BundleAnalyzerPlugin({ - analyzerPort: 8080, - generateStatsFile: false - }) - ) - } - - if (config.build.generateAnalyzerReport) { - webpackConfig.plugins.push( - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - reportFilename: 'bundle-report.html', - openAnalyzer: false - }) - ) - } -} - -module.exports = webpackConfig diff --git a/config/dev.env.js b/config/dev.env.js deleted file mode 100644 index 68ddea56214..00000000000 --- a/config/dev.env.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - NODE_ENV: '"development"', - ENV_CONFIG: '"dev"', - BASE_API: '"https://api-dev"' -} diff --git a/config/index.js b/config/index.js deleted file mode 100644 index 599e4a63471..00000000000 --- a/config/index.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict' -// Template version: 1.2.6 -// see http://vuejs-templates.github.io/webpack for documentation. - -const path = require('path') - -module.exports = { - dev: { - // Paths - assetsSubDirectory: 'static', - assetsPublicPath: '/', - proxyTable: {}, - - // Various Dev Server settings - - // can be overwritten by process.env.HOST - // if you want dev by ip, please set host: '0.0.0.0' - host: 'localhost', - port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined - autoOpenBrowser: true, - errorOverlay: true, - notifyOnErrors: false, - poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- - - // Use Eslint Loader? - // If true, your code will be linted during bundling and - // linting errors and warnings will be shown in the console. - useEslint: true, - // If true, eslint errors and warnings will also be shown in the error overlay - // in the browser. - showEslintErrorsInOverlay: false, - - /** - * Source Maps - */ - - // https://webpack.js.org/configuration/devtool/#development - devtool: 'cheap-source-map', - - // 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 - }, - - build: { - // Template for index.html - index: path.resolve(__dirname, '../dist/index.html'), - - // Paths - assetsRoot: path.resolve(__dirname, '../dist'), - assetsSubDirectory: 'static', - - /** - * You can set by youself according to actual condition - * You will need to set this if you plan to deploy your site under a sub path, - * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/, - * then assetsPublicPath should be set to "/bar/". - * In most cases please use '/' !!! - */ - assetsPublicPath: '/', - - /** - * Source Maps - */ - productionSourceMap: false, - // https://webpack.js.org/configuration/devtool/#production - devtool: 'source-map', - - // 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:prod --report` - // Set to `true` or `false` to always turn it on or off - bundleAnalyzerReport: process.env.npm_config_report || false, - - // `npm run build:prod --generate_report` - generateAnalyzerReport: process.env.npm_config_generate_report || false - } -} diff --git a/config/prod.env.js b/config/prod.env.js deleted file mode 100644 index bfcd6d27434..00000000000 --- a/config/prod.env.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - NODE_ENV: '"production"', - ENV_CONFIG: '"prod"', - BASE_API: '"https://api-prod"' -} diff --git a/config/sit.env.js b/config/sit.env.js deleted file mode 100644 index 93178e806cb..00000000000 --- a/config/sit.env.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - NODE_ENV: '"production"', - ENV_CONFIG: '"sit"', - BASE_API: '"https://api-sit"' -} diff --git a/src/mock/article.js b/mock/article.js similarity index 81% rename from src/mock/article.js rename to mock/article.js index 45923ddd3f6..72b5f837ad8 100644 --- a/src/mock/article.js +++ b/mock/article.js @@ -1,5 +1,4 @@ import Mock from 'mockjs' -import { param2Obj } from '@/utils' const List = [] const count = 100 @@ -29,8 +28,8 @@ for (let i = 0; i < count; i++) { } export default { - getList: config => { - const { importance, type, title, page = 1, limit = 20, sort } = param2Obj(config.url) + '/article/list': config => { + const { importance, type, title, page = 1, limit = 20, sort } = config.query let mockList = List.filter(item => { if (importance && item.importance !== +importance) return false @@ -50,21 +49,26 @@ export default { items: pageList } }, - getPv: () => ({ - pvData: [{ key: 'PC', pv: 1024 }, { key: 'mobile', pv: 1024 }, { key: 'ios', pv: 1024 }, { key: 'android', pv: 1024 }] - }), - getArticle: (config) => { - const { id } = param2Obj(config.url) + '/article/detail': config => { + const { id } = config.query for (const article of List) { if (article.id === +id) { return article } } }, - createArticle: () => ({ + '/article/pv': { + pvData: [ + { key: 'PC', pv: 1024 }, + { key: 'mobile', pv: 1024 }, + { key: 'ios', pv: 1024 }, + { key: 'android', pv: 1024 } + ] + }, + '/article/create': { data: 'success' - }), - updateArticle: () => ({ + }, + '/article/update': { data: 'success' - }) + } } diff --git a/mock/index.js b/mock/index.js new file mode 100644 index 00000000000..f40ac238923 --- /dev/null +++ b/mock/index.js @@ -0,0 +1,50 @@ +import Mock from 'mockjs' +import mocks from './mocks' +import { param2Obj } from '../src/utils' + +const MOCK_API_BASE = '/mock' + +export function mockXHR() { + // 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题 + // 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 + } + 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 [route, respond] of Object.entries(mocks)) { + Mock.mock(new RegExp(`${route}`), XHR2ExpressReqWrap(respond)) + } +} + +const responseFake = (route, respond) => ( + { + route: new RegExp(`${MOCK_API_BASE}${route}`), + response(req, res) { + res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) + } + } +) + +export default Object.keys(mocks).map(route => responseFake(route, mocks[route])) diff --git a/src/mock/login.js b/mock/login.js similarity index 72% rename from src/mock/login.js rename to mock/login.js index b9694f09959..e49f98ce25a 100644 --- a/src/mock/login.js +++ b/mock/login.js @@ -1,5 +1,3 @@ -import { param2Obj } from '@/utils' - const userMap = { admin: { roles: ['admin'], @@ -18,17 +16,18 @@ const userMap = { } export default { - loginByUsername: config => { - const { username } = JSON.parse(config.body) + '/login/login': config => { + const { username } = config.body return userMap[username] }, - getUserInfo: config => { - const { token } = param2Obj(config.url) + '/login/logout': 'success', + '/user/info': config => { + const { token } = config.query if (userMap[token]) { return userMap[token] } else { return false } - }, - logout: () => 'success' + } } + diff --git a/mock/mocks.js b/mock/mocks.js new file mode 100644 index 00000000000..9e551722077 --- /dev/null +++ b/mock/mocks.js @@ -0,0 +1,12 @@ +import login from './login' +import article from './article' +import search from './remoteSearch' +import transaction from './transaction' + +export default { + ...login, + ...article, + ...search, + ...transaction +} + diff --git a/src/mock/remoteSearch.js b/mock/remoteSearch.js similarity index 64% rename from src/mock/remoteSearch.js rename to mock/remoteSearch.js index b70f6f7d42e..bbdc0708b32 100644 --- a/src/mock/remoteSearch.js +++ b/mock/remoteSearch.js @@ -1,5 +1,4 @@ import Mock from 'mockjs' -import { param2Obj } from '@/utils' const NameList = [] const count = 100 @@ -12,12 +11,11 @@ for (let i = 0; i < count; i++) { NameList.push({ name: 'mockPan' }) export default { - searchUser: config => { - const { name } = param2Obj(config.url) + '/search/user': config => { + const { name } = config.query const mockNameList = NameList.filter(item => { const lowerCaseName = item.name.toLowerCase() - if (name && lowerCaseName.indexOf(name.toLowerCase()) < 0) return false - return true + return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0) }) return { items: mockNameList } } diff --git a/mock/transaction.js b/mock/transaction.js new file mode 100644 index 00000000000..61c84f0d220 --- /dev/null +++ b/mock/transaction.js @@ -0,0 +1,16 @@ +import Mock from 'mockjs' + +const count = 20 + +export default { + '/transaction/list': { + total: count, + [`items|${count}`]: [{ + order_no: '@guid()', + timestamp: +Mock.Random.date('T'), + username: '@name()', + price: '@float(1000, 15000, 0, 2)', + 'status|1': ['success', 'pending'] + }] + } +} diff --git a/package.json b/package.json index d795d1633a3..419293461a2 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "author": "Pan ", "license": "MIT", "scripts": { - "dev": "cross-env BABEL_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.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", + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:sit": "vue-cli-service build --mode text", "lint": "eslint --ext .js,.vue src", "test": "npm run lint", "precommit": "lint-staged", @@ -47,9 +47,9 @@ "js-cookie": "2.2.0", "jsonlint": "1.6.3", "jszip": "3.1.5", - "mockjs": "1.0.1-beta3", "normalize.css": "7.0.0", "nprogress": "0.2.0", + "path-to-regexp": "^2.4.0", "screenfull": "3.3.3", "showdown": "1.8.6", "simplemde": "1.11.2", @@ -64,63 +64,36 @@ "xlsx": "^0.11.16" }, "devDependencies": { + "@babel/core": "7.0.0", + "@babel/register": "7.0.0", + "@vue/babel-helper-vue-jsx-merge-props": "0.1.0", + "@vue/cli-plugin-babel": "^3.0.5", + "@vue/cli-plugin-eslint": "^3.0.5", + "@vue/cli-plugin-unit-mocha": "^3.0.5", + "@vue/cli-service": "^3.0.5", + "@vue/eslint-config-standard": "^3.0.5", + "@vue/test-utils": "^1.0.0-beta.25", "autoprefixer": "8.5.0", - "babel-core": "6.26.3", - "babel-eslint": "8.2.6", - "babel-helper-vue-jsx-merge-props": "2.0.3", - "babel-loader": "7.1.5", - "babel-plugin-dynamic-import-node": "2.0.0", - "babel-plugin-syntax-jsx": "6.18.0", - "babel-plugin-transform-runtime": "6.23.0", - "babel-plugin-transform-vue-jsx": "3.7.0", - "babel-preset-env": "1.7.0", - "babel-preset-stage-2": "6.24.1", - "chalk": "2.4.1", - "copy-webpack-plugin": "4.5.2", - "cross-env": "5.2.0", - "css-loader": "1.0.0", - "eslint": "4.19.1", - "eslint-friendly-formatter": "4.0.1", - "eslint-loader": "2.0.0", - "eslint-plugin-vue": "4.7.1", - "file-loader": "1.1.11", - "friendly-errors-webpack-plugin": "1.7.0", - "hash-sum": "1.0.2", - "html-webpack-plugin": "4.0.0-alpha", + "babel-plugin-istanbul": "^4.1.6", "husky": "0.14.3", "lint-staged": "7.2.2", - "mini-css-extract-plugin": "0.4.1", + "mockjs": "1.0.1-beta3", "node-notifier": "5.2.1", "node-sass": "^4.7.2", "optimize-css-assets-webpack-plugin": "5.0.0", - "ora": "3.0.0", - "path-to-regexp": "2.4.0", - "portfinder": "1.0.13", "postcss-import": "11.1.0", "postcss-loader": "2.1.6", "postcss-url": "7.3.2", - "rimraf": "2.6.2", "sass-loader": "7.0.3", "script-ext-html-webpack-plugin": "2.0.1", "script-loader": "0.7.2", - "semver": "5.5.0", - "serve-static": "1.13.2", "shelljs": "0.8.2", "svg-sprite-loader": "3.8.0", "svgo": "1.0.5", - "uglifyjs-webpack-plugin": "1.2.7", - "url-loader": "1.0.1", - "vue-loader": "15.3.0", - "vue-style-loader": "4.1.2", - "vue-template-compiler": "2.5.17", - "webpack": "4.16.5", - "webpack-bundle-analyzer": "2.13.1", - "webpack-cli": "3.1.0", - "webpack-dev-server": "3.1.5", - "webpack-merge": "4.1.4" + "vue-template-compiler": "2.5.17" }, "engines": { - "node": ">= 6.0.0", + "node": ">=8.9", "npm": ">= 3.0.0" }, "browserslist": [ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..34b63ac63a87ee3ea8e7a0f3f5b5406c437e2112 GIT binary patch literal 67646 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 X;@D+E7Ad=S_FbjlW&KY_+xPzm3MBT? literal 0 HcmV?d00001 diff --git a/index.html b/public/index.html similarity index 75% rename from index.html rename to public/index.html index 7a7ecacfecc..adb0ecc03a5 100644 --- a/index.html +++ b/public/index.html @@ -5,10 +5,11 @@ + vue-element-admin - +
diff --git a/static/tinymce4.7.5/langs/zh_CN.js b/public/static/tinymce4.7.5/langs/zh_CN.js similarity index 100% rename from static/tinymce4.7.5/langs/zh_CN.js rename to public/static/tinymce4.7.5/langs/zh_CN.js diff --git a/static/tinymce4.7.5/plugins/codesample/css/prism.css b/public/static/tinymce4.7.5/plugins/codesample/css/prism.css similarity index 100% rename from static/tinymce4.7.5/plugins/codesample/css/prism.css rename to public/static/tinymce4.7.5/plugins/codesample/css/prism.css diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cool.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-cry.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-embarassed.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-foot-in-mouth.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-frown.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-innocent.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-kiss.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-laughing.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-money-mouth.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-sealed.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-smile.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-surprised.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-tongue-out.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-undecided.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-wink.gif diff --git a/static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif b/public/static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif similarity index 100% rename from static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif rename to public/static/tinymce4.7.5/plugins/emoticons/img/smiley-yell.gif diff --git a/static/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css b/public/static/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css similarity index 100% rename from static/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css rename to public/static/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css diff --git a/static/tinymce4.7.5/skins/lightgray/content.inline.min.css b/public/static/tinymce4.7.5/skins/lightgray/content.inline.min.css similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/content.inline.min.css rename to public/static/tinymce4.7.5/skins/lightgray/content.inline.min.css diff --git a/static/tinymce4.7.5/skins/lightgray/content.min.css b/public/static/tinymce4.7.5/skins/lightgray/content.min.css similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/content.min.css rename to public/static/tinymce4.7.5/skins/lightgray/content.min.css diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-mobile.woff diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.eot diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.svg b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.svg similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.svg rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.svg diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.ttf diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce-small.woff diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.eot diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.svg b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.svg similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce.svg rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.svg diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.ttf diff --git a/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff b/public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff rename to public/static/tinymce4.7.5/skins/lightgray/fonts/tinymce.woff diff --git a/static/tinymce4.7.5/skins/lightgray/img/anchor.gif b/public/static/tinymce4.7.5/skins/lightgray/img/anchor.gif similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/img/anchor.gif rename to public/static/tinymce4.7.5/skins/lightgray/img/anchor.gif diff --git a/static/tinymce4.7.5/skins/lightgray/img/loader.gif b/public/static/tinymce4.7.5/skins/lightgray/img/loader.gif similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/img/loader.gif rename to public/static/tinymce4.7.5/skins/lightgray/img/loader.gif diff --git a/static/tinymce4.7.5/skins/lightgray/img/object.gif b/public/static/tinymce4.7.5/skins/lightgray/img/object.gif similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/img/object.gif rename to public/static/tinymce4.7.5/skins/lightgray/img/object.gif diff --git a/static/tinymce4.7.5/skins/lightgray/img/trans.gif b/public/static/tinymce4.7.5/skins/lightgray/img/trans.gif similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/img/trans.gif rename to public/static/tinymce4.7.5/skins/lightgray/img/trans.gif diff --git a/static/tinymce4.7.5/skins/lightgray/skin.min.css b/public/static/tinymce4.7.5/skins/lightgray/skin.min.css similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/skin.min.css rename to public/static/tinymce4.7.5/skins/lightgray/skin.min.css diff --git a/static/tinymce4.7.5/skins/lightgray/skin.min.css.map b/public/static/tinymce4.7.5/skins/lightgray/skin.min.css.map similarity index 100% rename from static/tinymce4.7.5/skins/lightgray/skin.min.css.map rename to public/static/tinymce4.7.5/skins/lightgray/skin.min.css.map diff --git a/static/tinymce4.7.5/tinymce.min.js b/public/static/tinymce4.7.5/tinymce.min.js similarity index 100% rename from static/tinymce4.7.5/tinymce.min.js rename to public/static/tinymce4.7.5/tinymce.min.js diff --git a/src/components/TreeTable/index.vue b/src/components/TreeTable/index.vue index a48765c882b..2ae1814c915 100644 --- a/src/components/TreeTable/index.vue +++ b/src/components/TreeTable/index.vue @@ -61,7 +61,7 @@ export default { tmp = this.data } const func = this.evalFunc || treeToArray - const args = this.evalArgs ? Array.concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll] + const args = this.evalArgs ? [].concat([tmp, this.expandAll], this.evalArgs) : [tmp, this.expandAll] return func.apply(null, args) } }, diff --git a/src/main.js b/src/main.js index 1ce709c9025..b9b300be18b 100644 --- a/src/main.js +++ b/src/main.js @@ -17,10 +17,14 @@ import i18n from './lang' // Internationalization import './icons' // icon import './errorLog' // error log import './permission' // permission control -import './mock' // simulation data import * as filters from './filters' // global filters +import { mockXHR } from '../mock' // simulation data + +// mock api in github pages site build +if (process.env.NODE_ENV === 'production') { mockXHR() } + Vue.use(Element, { size: Cookies.get('size') || 'medium', // set element-ui default size i18n: (key, value) => i18n.t(key, value) diff --git a/src/mock/index.js b/src/mock/index.js deleted file mode 100644 index 3e00e91838d..00000000000 --- a/src/mock/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import Mock from 'mockjs' -import loginAPI from './login' -import articleAPI from './article' -import remoteSearchAPI from './remoteSearch' -import transactionAPI from './transaction' - -// 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题 -// 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 - } - this.proxy_send(...arguments) -} - -// Mock.setup({ -// timeout: '350-600' -// }) - -// 登录相关 -Mock.mock(/\/login\/login/, 'post', loginAPI.loginByUsername) -Mock.mock(/\/login\/logout/, 'post', loginAPI.logout) -Mock.mock(/\/user\/info\.*/, 'get', loginAPI.getUserInfo) - -// 文章相关 -Mock.mock(/\/article\/list/, 'get', articleAPI.getList) -Mock.mock(/\/article\/detail/, 'get', articleAPI.getArticle) -Mock.mock(/\/article\/pv/, 'get', articleAPI.getPv) -Mock.mock(/\/article\/create/, 'post', articleAPI.createArticle) -Mock.mock(/\/article\/update/, 'post', articleAPI.updateArticle) - -// 搜索相关 -Mock.mock(/\/search\/user/, 'get', remoteSearchAPI.searchUser) - -// 账单相关 -Mock.mock(/\/transaction\/list/, 'get', transactionAPI.getList) - -export default Mock diff --git a/src/mock/transaction.js b/src/mock/transaction.js deleted file mode 100644 index a17517e4a0b..00000000000 --- a/src/mock/transaction.js +++ /dev/null @@ -1,23 +0,0 @@ -import Mock from 'mockjs' - -const List = [] -const count = 20 - -for (let i = 0; i < count; i++) { - List.push(Mock.mock({ - order_no: '@guid()', - timestamp: +Mock.Random.date('T'), - username: '@name()', - price: '@float(1000, 15000, 0, 2)', - 'status|1': ['success', 'pending'] - })) -} - -export default { - getList: () => { - return { - total: List.length, - items: List - } - } -} diff --git a/src/utils/request.js b/src/utils/request.js index 50f9ececb78..47237685661 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -5,7 +5,8 @@ import { getToken } from '@/utils/auth' // create an axios instance const service = axios.create({ - baseURL: process.env.BASE_API, // api 的 base_url + baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url + withCredentials: true, // 跨域请求时发送 cookies timeout: 5000 // request timeout }) diff --git a/src/views/guide/index.vue b/src/views/guide/index.vue index c30c52cf15c..49502aeff80 100644 --- a/src/views/guide/index.vue +++ b/src/views/guide/index.vue @@ -10,7 +10,7 @@ diff --git a/vue.config.js b/vue.config.js index d4f047fad1d..3cf98e6087d 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,18 +1,37 @@ 'use strict' -require('@babel/register') const path = require('path') -const bodyParser = require('body-parser') function resolve(dir) { return path.join(__dirname, dir) } +const port = 9527 // TODO: change to Settings + +// Explanation of each configuration item You can find it in https://cli.vuejs.org/config/ module.exports = { + /** + * You can set by yourself according to actual condition + * You will need to set this if you plan to deploy your site under a sub path, + * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/, + * then assetsPublicPath should be set to "/bar/". + * In most cases please use '/' !!! + * Detail https://cli.vuejs.org/config/#baseurl + */ + baseUrl: '/', + outputDir: 'dist', + assetsDir: 'static', + lintOnSave: process.env.NODE_ENV !== 'production', + productionSourceMap: false, devServer: { + port: port, open: true, + overlay: { + warnings: false, + errors: true + }, proxy: { '/api': { - target: 'http://localhost:8080/mock', + target: `http://localhost:${port}/mock`, changeOrigin: true, pathRewrite: { '^/api': '' @@ -20,6 +39,9 @@ module.exports = { } }, after(app) { + console.log('apple') + const bodyParser = require('body-parser') + require('@babel/register') // parse app.body // http://expressjs.com/en/4x/api.html#req.body app.use(bodyParser.json()) @@ -33,28 +55,74 @@ module.exports = { } }, configureWebpack: { + // We provide the app's title in Webpack's name field, so that + // it can be accessed in index.html to inject the correct title. + name: 'vue-element-admin', // TODO: change to Settings resolve: { alias: { - '$@': resolve('src/components') + '@': resolve('src') } - }, - module: { - rules: [ - { - test: /\.svg$/, - loader: 'svg-sprite-loader', - include: [resolve('src/icons')], - options: { - symbolId: 'icon-[name]' - } - } - ] } }, chainWebpack(config) { + config.plugins.delete('preload')// TODO: need test + config.plugins.delete('prefetch')// TODO: need test config.module .rule('svg') .exclude.add(resolve('src/icons')) .end() + config.module + .rule('icons') + .test(/\.svg$/) + .include.add(resolve('src/icons')) + .end() + .use('svg-sprite-loader') + .loader('svg-sprite-loader') + .options({ + symbolId: 'icon-[name]' + }) + .end() + + config + .when(process.env.NODE_ENV === 'development', + config => config.devtool('cheap-source-map') + ) + + config + .when(process.env.NODE_ENV !== 'development', + config => { + config + .plugin('ScriptExtHtmlWebpackPlugin') + .use('script-ext-html-webpack-plugin', [{ + // `runtime` must same as runtimeChunk name. default is `runtime` + inline: /runtime\..*\.js$/ + }]) + config + .optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' // 只打包初始时依赖的第三方 + }, + elementUI: { + name: 'chunk-elementUI', // 单独将 elementUI 拆包 + priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app + test: /[\\/]node_modules[\\/]element-ui[\\/]/ + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // 可自定义拓展你的规则 + minChunks: 3, // 最小公用次数 + priority: 5, + reuseExistingChunk: true + } + } + }) + config.optimization.runtimeChunk('single') + } + ) } } From 51f99770fe1c28b7bc904dbc68a60c1e29093980 Mon Sep 17 00:00:00 2001 From: Pan Date: Mon, 29 Oct 2018 15:29:54 +0800 Subject: [PATCH 016/141] add test --- .gitignore | 4 ++-- babel.config.js | 13 ++--------- jest.config.js | 24 ++++++++++++++++++++ package.json | 1 + src/components/Hamburger/index.vue | 9 ++++---- src/utils/index.js | 6 ++++- src/utils/validate.js | 2 +- src/views/layout/components/Navbar.vue | 2 +- src/views/login/index.vue | 4 ++-- tests/unit/.eslintrc.js | 5 +++++ tests/unit/components/Hamburger.spec.js | 18 +++++++++++++++ tests/unit/components/SvgIcon.spec.js | 22 +++++++++++++++++++ tests/unit/utils/formatTime.spec.js | 29 +++++++++++++++++++++++++ tests/unit/utils/parseTime.spec.js | 27 +++++++++++++++++++++++ tests/unit/utils/validate.spec.js | 28 ++++++++++++++++++++++++ 15 files changed, 172 insertions(+), 22 deletions(-) create mode 100644 jest.config.js create mode 100644 tests/unit/.eslintrc.js create mode 100644 tests/unit/components/Hamburger.spec.js create mode 100644 tests/unit/components/SvgIcon.spec.js create mode 100644 tests/unit/utils/formatTime.spec.js create mode 100644 tests/unit/utils/parseTime.spec.js create mode 100644 tests/unit/utils/validate.spec.js diff --git a/.gitignore b/.gitignore index 887ce1ed073..78a752d87e8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,8 @@ yarn-debug.log* yarn-error.log* **/*.log -test/unit/coverage -test/e2e/reports +tests/**/coverage/ +tests/e2e/reports selenium-debug.log # Editor directories and files diff --git a/babel.config.js b/babel.config.js index 6f812f6161d..ba179669a12 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,14 +1,5 @@ module.exports = { presets: [ - ['@vue/app', { modules: 'commonjs' }] - ], - plugins: [], - env: { - test: { - presets: [ - ['@vue/app', { modules: 'commonjs' }] - ], - plugins: ['istanbul'] - } - } + '@vue/app' + ] } diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000000..5a8aa6bb8bc --- /dev/null +++ b/jest.config.js @@ -0,0 +1,24 @@ +module.exports = { + verbose: true, + 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/package.json b/package.json index 2a11617aa81..90812d591fc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "build:sit": "vue-cli-service build --mode text", "lint": "eslint --ext .js,.vue src", "test": "npm run lint", + "test:unit": "vue-cli-service test:unit", "precommit": "lint-staged", "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" }, diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue index 26472e23dde..04c5881a1e8 100644 --- a/src/components/Hamburger/index.vue +++ b/src/components/Hamburger/index.vue @@ -33,10 +33,11 @@ export default { isActive: { type: Boolean, default: false - }, - toggleClick: { - type: Function, - default: null + } + }, + methods: { + toggleClick() { + this.$emit('toggleClick') } } } diff --git a/src/utils/index.js b/src/utils/index.js index 0445827b32e..766906a252e 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -36,7 +36,11 @@ export function parseTime(time, cFormat) { } export function formatTime(time, option) { - time = +time * 1000 + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } const d = new Date(time) const now = Date.now() diff --git a/src/utils/validate.js b/src/utils/validate.js index ada0e7e2fc1..b4800be3fbd 100644 --- a/src/utils/validate.js +++ b/src/utils/validate.js @@ -2,7 +2,7 @@ * Created by jiachenpan on 16/11/18. */ -export function isvalidUsername(str) { +export function validUsername(str) { const valid_map = ['admin', 'editor'] return valid_map.indexOf(str.trim()) >= 0 } diff --git a/src/views/layout/components/Navbar.vue b/src/views/layout/components/Navbar.vue index 7bae38e09e1..6899f399a79 100644 --- a/src/views/layout/components/Navbar.vue +++ b/src/views/layout/components/Navbar.vue @@ -1,6 +1,6 @@ diff --git a/src/views/components-demo/markdown.vue b/src/views/components-demo/markdown.vue index f60911d0730..5fb39569199 100644 --- a/src/views/components-demo/markdown.vue +++ b/src/views/components-demo/markdown.vue @@ -1,15 +1,40 @@ @@ -17,32 +42,46 @@ import MarkdownEditor from '@/components/MarkdownEditor' const content = ` -**this is test** +**This is test** * vue * element * webpack -## Simplemde ` - export default { name: 'MarkdownDemo', components: { MarkdownEditor }, data() { return { content: content, - html: '' + html: '', + languageTypeList: { + 'en': 'en_US', + 'zh': 'zh_CN', + 'es': 'es_ES' + } + } + }, + computed: { + language() { + return this.languageTypeList[this.$store.getters.language] } }, methods: { - markdown2Html() { - import('showdown').then(showdown => { - const converter = new showdown.Converter() - this.html = converter.makeHtml(this.content) - }) + getHtml() { + this.html = this.$refs.markdownEditor.getHtml() + console.log(this.html) } } } + From 2f731000c19b9b44b7b4a7bd9c56ca329a752d41 Mon Sep 17 00:00:00 2001 From: Pan Date: Wed, 28 Nov 2018 14:24:30 +0800 Subject: [PATCH 035/141] tweak --- src/views/components-demo/markdown.vue | 4 ++-- src/views/login/index.vue | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/views/components-demo/markdown.vue b/src/views/components-demo/markdown.vue index 5fb39569199..de2e817e433 100644 --- a/src/views/components-demo/markdown.vue +++ b/src/views/components-demo/markdown.vue @@ -3,8 +3,8 @@ Markdown is based on tui.editor ,Simply encapsulated in Vue. - - 相关文章 + + Documentation
diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 920c1696773..8f1b61d1181 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -107,7 +107,6 @@ export default { }, immediate: true } - }, created() { // window.addEventListener('hashchange', this.afterQRScan) From 84b19d7283d96a2ee339cf46352effed93be28bb Mon Sep 17 00:00:00 2001 From: Pan Date: Wed, 28 Nov 2018 18:11:18 +0800 Subject: [PATCH 036/141] add preview --- build/index.js | 31 +++++++++++++++++++++++++++++++ favicon.ico | Bin 67646 -> 0 bytes package.json | 31 ++++++++++++++++++------------- 3 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 build/index.js delete mode 100644 favicon.ico diff --git a/build/index.js b/build/index.js new file mode 100644 index 00000000000..a750ae0bbe8 --- /dev/null +++ b/build/index.js @@ -0,0 +1,31 @@ +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')) { + run(`vue-cli-service build ${args}`) + + const port = 9526 + const basePath = config.baseUrl + + var connect = require('connect') + var serveStatic = require('serve-static') + const app = connect() + + app.use( + basePath, + serveStatic('./dist', { + index: ['index.html', '/'] + }) + ) + + app.listen(port, function() { + console.log( + chalk.green(`> Listening at http://localhost:${port}${basePath}`) + ) + }) +} else { + run(`vue-cli-service build ${args}`) +} diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index 34b63ac63a87ee3ea8e7a0f3f5b5406c437e2112..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67646 zcmeHQ33wdEm2O$a2gEi66S8a^!){2(X2Y@}*zze`)?rJU(MUFiMYeol`2frK#KsuO zmSjtF$~K2NVhlNfB)}R7SkfFaCWOr{`-RN#4YIW(H- zo|aUj@2RJ{r>m>p|LWDNSFfrSr2u~|Eeif$u3R;tK>3)WC|7}SiYLW+e&x3_lNCW) zTK<C+ zR1SCpF}#VnD^NAY(^oSQ_)Y=-Q*rK69RC8x%Ygl*pi6-NM{#|U$L|<_q}x%@6|58T zLYZ(QKeyk8bhWAVkPjO?2iki|(6)h5$e}pLQj0&7qVaE>Z7c&zo=1K1Eq%6 zPiCH&1BdlEaj^n`p2H2XH-4&`R zaKVOzju8668Ca6LijVS~I{X!|<*Jo?14|3sA^XR{_hyjUxF?dKKcgH!1N|%L9(TY| z2K#cdCuAS%3oX;eA1Jr{WXAz_z@{ANU04A7>+jL-p9Zi007`^MKF@uCGW`m47X8B( z*pZ(BUEm4TVO(ifyuDHmh9U*zoy%WY2;57-+wX(^1j;AQ>7GrUKw0=Ps1sD|_1iAy z_{598q3GG6aAEY`)74uI>}zU4Z-CPA-ip`%8|8iwRO1cVF6jz!jA|RbfM!s07yWm^ znsU&OKvu*ylQR7rb@)2yMo*~vLfA1%M@ZU;iNwK!@f7@aw4c5Jew`fw*z4tl`rs7s zU)>q3yb!iRLCeb(&=m7g`Yy$q5yZX>4Kn_O3$Axhb>N*GY|4&dlK8^J2zXK1R2Q`8xQ`s+) zM)Jqyw-=zk$3cGtjdXkmTfbj}7ta9uTF^vKpqe~V=o24FANcs-=d*tvb^G^WgMFYz zbtfUr4-XdK!Tyfp#z!&VGy{FZcwcC#LVY<>K41Nh-SqYB0?{5GEKlRk_1 zsQd0NA4tc_#kJ07Z7SMqF3U*U;2qF@#Jv1f+lysmFz1AJQ#b6z0ArphsMnLj0eg3^ zUEOh@L|s`qLr?>bdRn<;hPq~Hk&ppzUrzCl$P)X!^eHMa- zg^#}j?RxuN3)PM5=c=n~W~wVHAP2x)Pb(^}Q*Yb5Ky^N!a~%+o0Umz~dKj@u^ST0c zV-S-vEJeWCEByT1Q5VKu>FZ~?@9gh)9a^Mr**0Ho{aU4ZM^~A;sd28_V4K+w|CNhp zsH)B}$$R-xOBuE)Q@hj=^iXI!h&)?GHNko8#fO=uCw^Vie4acA5pxyKg@Go)ttH&OFu~s>PSmsmRw_08n z;OC&-|FY%rN88_a$AT!%TW*`Lc0OlQ+n%UWH{Lu~Wt-Rc0ZcdTC^ote(CZfZ5#NE1 z+5x&`f8Qd@+XX(v*CS?X3ChiJuD&kT`i{0wtT%0#8}08`*=MSat7og5HqKMm-7qUE z7kU|3v#dz;6DHS<@llT>Hu~D5y>*4qTb9)UzFylHjAz%I%%6;9i+23MuPjm5ub8dj zkG8#{{5o|7j+BGdj-rJ4H&o3~ceO84Ic6}qj?@LOf$A}rK8bdL6+gb9?E;kXu*tm1 z91H0F-LU%_s$u5=bGGZPyNlKJD`yYX`#KwdW5lMN#j2~vbo?WAWPEBn@SldGa=*o5 z44|7XMY$fcGX8A)?Bh4AofFmlYwC)`7=X6mfPP<(KfbT~hgoVn?$2W#e~)KB0s6Zy zbuTM$`K=RY0=c{b<>LHzKKYaK*>1mGy}fhMK>ZFqpzrIGePwzM zakDRBook6Z=oo92IYspSSD{>%jql^w{m_%N@6q-LiFYD7*t~gOzVVO9${WzR%YpxR z#uw!K1MC^=!Sz*<@>%Lg-On*UeL0D69n?9<4ef+O-$ox`yf0`l{QD{J-w6CC4J5Z5c^O$`A1nIMi;l9e;B z=c)TS=1YY=$No3pG%KZya6W+Z1)Mjuhz=lM!!lrl9>~x5(9-y0%*Q$2RBfL=Uity= zyr*2)`N{MEf45=H95D_sVLl*}HuDQ$-vpZ2b*2h?UYNVTftB&6?%(4oO^g3ljPE<1 zsaCh&xiI-}(Lb!h9MSF$_<|r;7SnhCg|%t*DAU-^fVr^*R>q(H-p!ll4IKCB#`kR3 zP1}oA#(K1zT&%9bd~mY9g1@Ezn0BDWbO7b?Cx|5|+0(t=R9nEx_}_VNx#ri^;T?}H z`*n`(ou}>40XB8*^~uKx#J_RX9JTcum8wB;A=&DcvzUwd8#mUfn)R_V{`B`!XUAh6 zO+%+M&S(Gea?ze$-FEndF+Z3>UYOqxpm691pHtUL?i_ZvDI-@b3Wr8!=CmY#b=^!kplp_m%70oYlT_uE2va!4&RU zVdMwT`7Fpfai74j^E;Z|&-wj$?3v~`zUAS?1Lt&cFXKIL+XEXQncfK728+`xlDXom|(teZVcZ%+uzCtbzAHS%yylbJm~k>NRdGfO)8k!MhU?{^j)u?5O)0 zvzbiyNARRCKUw?dIFRcD=o^UqKGBhJV-_9@QXVibXWxwZp+cj20PJ@$5zpWry@}+{ z)N{1Q>BAGToGJQm>h8Us(xhc$K8y{gjhLzrApU#3mh}a&e(VFD1&ucfe@|~E*RyT} zCFQ3n*U+LYxf7J* zm*}I7GXNl1@HunOhc^>E+dRGi|2FvL*WHLX{uH{O@w|IHWr*WQEvxJU*tf5))#8N* z^#90*&*3;>|M3bd`-0wsjl12b_RoA_Uwj(a`}2uEqRc#hxbn@O;{v3Gp%d zJmb99Ek_(z{cLRxH$fl3HU5m>81z~W;J?RRD%Oank}LWNb~KkHw^`O0VvXWT~NPo|G2l?}kY zf%3JpwPf&pi+OzdE$s7+#^YbjKA;U`?w+r}hx>UX)cIkXjo5IV-+@Om)BO=yZhKtY zGa{W0z*rL6p%&8tKZE{XXf*!J-xGAu4`klnkLYXJ_C>r#0(&ol7w7xw%Ngq04c@n_ zEy4Oh-I#!Vz^z;7ix@(S;r}M~oV(N<{Oy+kf75J$n2#p8pPsm|?PnXW!?{ASUziSa zAz$Bi8;+%d8P&Kl~@O{l_pqA7=*shkMH~7hrz?&;29Fcsl^?|8{4o7PFnC z{YUIR#`k7ZCdLFL!hh}cv!H*pcp)*qL|-&iJ(ErOlHB_T=%O`7&j0D<>JZ=M8L}@$ zS>8=jo~$s?=Slw^+Zt_pw(*Frk3SNB&I#!6&G)%JK5{0i_bCuslr^+h*xuK?-* zGvq)0Gk$_SWUk;l_ssZoVC@Osq4#mr{f9=^-+RU({PV)@3*%3$N&Wo)xV8oTa#npZ z@TdNuFR)+U@v?xlur;ub$RawxiM<8SN1HSQex)O@lyd>&&<7j?{@m--uy#QFwe=m^ z{*4V)GsXH$uH|EFPXs5n+2${0AE!lIgTAA6HzwXMBqDn}Zdfzd3gf_Y;Q!3Gwtd7D z>?04sUPX)tCrsA9j9#A*P~SUUfAx~7c_03kGSvfnh)4zjL{mjzc-b<;&~!2 z2;+!|Y>B=A`i1krTd;r7kzQKKj8PBEzrd|+P{%Hfb%^4e2sV(bqxCkt~KR;qKpfr-`L3dr^)+O z*he$kU%nyIEKNOn{f=>nt!Y9T8Ha8NANJj&&CN3gM_?Z5i-8Bv(I3kg4X)M8RT+ps z_l)IyfUq;d&!pWi_K?GKx#ooWXY*$46@WFxxq5a6`TQR3Z>O)XX6%uk{Jew6eY%dm zz^g%TWKizG^9nvc&db%8VgJ6c%@;X}Hh-{0rG5}L7=D|pG7x{Uj~M2e6Foap2F?f3 z=fE*TR(5CRZHG43Q+N-dlT*R2cZip|tfoaBIl>+~GI80A-%z?7- z-Je*8l6xMoPiGtl{dxz#TB#AfA9~W@b(tIsLbveQZI9vkk!Qyp4;x*Mfjs?R@OkSI zf30D$-kA!KJ0#`=A2tGi=E*irovbHQ^evy8;Mt~^BPIj%w;sj2wx{?k^d5i5mvMd$ob4~jh8)I;cf^x|D9_bNr0eOoJ8{x9?3dVZ#F~3&;Jv(HKjK0wss5~Dy zJPtC{Cp^Nj*6SIz`!m3P0mx|hvd&*sRp_RgVw73h0onIeY(w7!?q6)~E6ExgGcxG- zZWVmOjtM9?{Q>6024v4?eS5RY_un9v2XlIkEA9?nubl9&Gy}e@pK%oL!1kRLK0&M# zvYQqk1X;5RZrPTDZRS!r@0;-D9DuI>!pU!~QGh>ac>!&ko_SdDgDfc+rH z#ct57&c4bCoI4|p(Wjk6y*~gM-L|ZjKi`>h4#Y9>wTPRXjLhndP(vJ_&jrM4y(`FfyV%+$ZNpAP?mKb7%(>Iz!O&z}`x8cgZlz<@wfNnS#CP zXbaFDJPR^{-&Vc$_HACj?J7^717qNk-M42d58OYZqvuAvN7%7o1j)cVsLTDpeL3PX zrn&mi&QVXVfqQXg%6BXM-sP`TI(wFn!8=SS1K$S?H+z8NcKU42BKCO~j@O}2zo;v; z3^oq>b_>MhSqbk%WpQKun6q~o-zR=8_}2@v`nZ5H%5^SpV;pk=WA`PPm%9vm%Zo5a@7~-Dj)hRUI#smxwuC7XRieQ6EJow z;CwvVzvAk({=9q=2=ac~9f1D>1Ya@Ud+*o;KL0a_`ZZVh4J9AiaV*C-Kuxe!{ubl4 z^MHQ={j>DV3%?EGo#ZDs9N=8R&euxOe~R%T{UkpI4F$WQ-b4TNX^;>4Xcfk4SG)XG zSl_CR*}DAJi?_=S=dF{A@D+pKt{$voM!XZ^AH3lITcDw0n(DsaAYb|+I6q0fQ;IhI z*PX%2v9#ehR(HcEFF)pU0P8)3j>TAUGWuBVHMa%Cwn@EAUn*lH*heH9H}E|D?EDRX z%RQ>-kD)#}1#)8C!MKDX$k?ZV^M%J=s;A!3bb1hTufufC-F&2sd!iQ@h%q!{NkTQ} zp%0$w4m#jFcdP?JFW8>|etp306%c)GJiY{ZLHxP>5qx)IOtux@?VziX{!1J$Mm`rD zdSUq(AKEzkaoNs|!!Q>)yZw02F>wM_oVXiyVr?Pt=e`pYaDF1rGu}8#z#p-P_VK`e z9DHwMy@Bd6zB3$`GY_#&4Y5hJ%HiPBTog~{VIl`y7%z&L5)oGtZogsK(C`)e5kzsO z@6|(nj(%MBFqYOb(5k~swGzeBT8Uz5tx8&TMIl6ny7Y8DK$jL7hO5sTL;~ zlvtnU1N7C!QI(h$xxtqM^J|3iKI-A_RE*W=R^fEL{kfJe%7F|G%7zi&qR zT#7U<>j8-u*!VQ%P2T`mJbijP(>jJ0$EBN@)-ixd9Rsum8LObkURU8_@$*;(o3(VL zg5lev6(TeFiAY>HyJ&&6tI-0B%JE#dfRUd^3RoQZeYk+pq*kEl?O~2I$F7qjy2~QN X;@D+E7Ad=S_FbjlW&KY_+xPzm3MBT? diff --git a/package.json b/package.json index 09487f42246..84bc63c4589 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "dev": "vue-cli-service serve", "build:prod": "vue-cli-service build", "build:sit": "vue-cli-service build --mode text", + "build:preview": "node build/index.js --preview", + "build:report": "node build/index.js --report", "lint": "eslint --ext .js,.vue src", "test": "npm run lint", "test:unit": "vue-cli-service test:unit", @@ -37,11 +39,11 @@ "dependencies": { "axios": "0.18.0", "clipboard": "1.7.1", - "codemirror": "5.39.2", - "driver.js": "0.5.2", - "dropzone": "5.2.0", + "codemirror": "5.42.0", + "driver.js": "0.8.1", + "dropzone": "5.5.1", "echarts": "4.1.0", - "element-ui": "2.4.6", + "element-ui": "2.4.10", "file-saver": "1.3.8", "js-cookie": "2.2.0", "jsonlint": "1.6.3", @@ -50,7 +52,6 @@ "nprogress": "0.2.0", "path-to-regexp": "2.4.0", "screenfull": "3.3.3", - "showdown": "1.8.6", "sortablejs": "1.7.0", "tui-editor": "1.2.7", "vue": "2.5.17", @@ -58,29 +59,33 @@ "vue-i18n": "7.3.2", "vue-router": "3.0.2", "vue-splitpane": "1.0.2", - "vuedraggable": "^2.16.0", + "vuedraggable": "2.17.0", "vuex": "3.0.1", "xlsx": "^0.11.16" }, "devDependencies": { "@babel/core": "7.0.0", "@babel/register": "7.0.0", - "@vue/cli-plugin-babel": "3.1.1", - "@vue/cli-plugin-eslint": "3.1.5", - "@vue/cli-plugin-unit-jest": "3.1.1", - "@vue/cli-service": "3.1.4", + "@vue/cli-plugin-babel": "3.2.0", + "@vue/cli-plugin-eslint": "3.2.1", + "@vue/cli-plugin-unit-jest": "3.2.0", + "@vue/cli-service": "3.2.0", "@vue/test-utils": "1.0.0-beta.25", "babel-core": "7.0.0-bridge.0", "babel-jest": "23.6.0", + "chalk": "^2.4.1", + "connect": "^3.6.6", "husky": "0.14.3", "lint-staged": "7.2.2", "mockjs": "1.0.1-beta3", "node-sass": "^4.9.0", + "runjs": "^4.3.2", "sass-loader": "7.0.3", - "script-ext-html-webpack-plugin": "2.0.1", + "script-ext-html-webpack-plugin": "2.1.3", "script-loader": "0.7.2", - "svg-sprite-loader": "3.8.0", - "svgo": "1.0.5", + "serve-static": "^1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.1.1", "vue-template-compiler": "2.5.17" }, "engines": { From 075d29aceaa8b91fd627b51cc856d013a1b10635 Mon Sep 17 00:00:00 2001 From: Pan Date: Thu, 29 Nov 2018 18:17:30 +0800 Subject: [PATCH 037/141] fix return back bug --- src/views/errorPage/404.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/errorPage/404.vue b/src/views/errorPage/404.vue index c3eafea07ba..6483fd5f7d6 100644 --- a/src/views/errorPage/404.vue +++ b/src/views/errorPage/404.vue @@ -14,7 +14,7 @@
{{ message }}
请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告
- 返回首页 + 返回首页 From b8b787733ce8d32a1d79500c6df462c86a4623bc Mon Sep 17 00:00:00 2001 From: Pan Date: Tue, 4 Dec 2018 14:00:30 +0800 Subject: [PATCH 038/141] update guide page --- src/views/guide/defineSteps.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/guide/defineSteps.js b/src/views/guide/defineSteps.js index fde7892620b..405a3f72eda 100644 --- a/src/views/guide/defineSteps.js +++ b/src/views/guide/defineSteps.js @@ -45,7 +45,8 @@ const steps = [ title: 'Tags view', description: 'The history of the page you visited', position: 'bottom' - } + }, + padding: 0 } ] From 49f1e5e6dc41f004b8702ce3c8422affa8ee6ee9 Mon Sep 17 00:00:00 2001 From: Pan Date: Tue, 4 Dec 2018 18:15:52 +0800 Subject: [PATCH 039/141] fix[Tinymce]: fixed fullScreen bug #1400 --- src/components/Tinymce/index.vue | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/Tinymce/index.vue b/src/components/Tinymce/index.vue index 7f4a0ae0ea1..9032a6a8ab2 100644 --- a/src/components/Tinymce/index.vue +++ b/src/components/Tinymce/index.vue @@ -157,8 +157,13 @@ export default { }) }, destroyTinymce() { - if (window.tinymce.get(this.tinymceId)) { - window.tinymce.get(this.tinymceId).destroy() + const tinymce = window.tinymce.get(this.tinymceId) + if (this.fullscreen) { + tinymce.execCommand('mceFullScreen') + } + + if (tinymce) { + tinymce.destroy() } }, setContent(value) { From 9ce0f81d5f2c535b4250129271ab30997226fe74 Mon Sep 17 00:00:00 2001 From: Pan Date: Mon, 24 Dec 2018 11:12:24 +0800 Subject: [PATCH 040/141] feat[Breadcrumb]: add hide Breadcrumb option #1442 --- src/components/Breadcrumb/index.vue | 5 +++-- src/router/index.js | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue index 554abe8d365..4b321e064f7 100644 --- a/src/components/Breadcrumb/index.vue +++ b/src/components/Breadcrumb/index.vue @@ -1,8 +1,9 @@ - + diff --git a/src/views/layout/components/Sidebar/index.vue b/src/views/layout/components/Sidebar/index.vue index 48407286805..11ef4c0257a 100644 --- a/src/views/layout/components/Sidebar/index.vue +++ b/src/views/layout/components/Sidebar/index.vue @@ -1,7 +1,6 @@ @@ -27,6 +28,7 @@ - - diff --git a/src/components/TreeTable/readme.md b/src/components/TreeTable/readme.md index 5b598e1109d..fe404ed04a2 100644 --- a/src/components/TreeTable/readme.md +++ b/src/components/TreeTable/readme.md @@ -1,89 +1,99 @@ ## 写在前面 -此组件仅提供一个创建TreeTable的解决思路 - -## prop说明 -#### *data* - **必填** - - 原始数据,要求是一个数组或者对象 - ```javascript - [{ - key1: value1, - key2: value2, - children: [{ - key1: value1 - }, - { - key1: value1 - }] - }, - { - key1: value1 - }] - ``` - 或者 - ```javascript - { - key1: value1, - key2: value2, - children: [{ - key1: value1 - }, - { - key1: value1 - }] - } - ``` - -#### columns - 列属性,要求是一个数组 - - 1. text: 显示在表头的文字 - 2. value: 对应data的key。treeTable将显示相应的value - 3. width: 每列的宽度,为一个数字(可选) - 如果你想要每个字段都有自定义的样式或者嵌套其他组件,columns可不提供,直接像在el-table一样写即可,如果没有自定义内容,提供columns将更加的便捷方便 +此组件仅提供一个创建 TreeTable 的解决思路,本组件充分利用 vue 插槽的特性,方便用户自定义 - 如果你有几个字段是需要自定义的,几个不需要,那么可以将不需要自定义的字段放入columns,将需要自定义的内容放入到slot中,详情见后文 - ```javascript - [{ - value:string, - text:string, - width:number - },{ - value:string, - text:string, - width:number - }] - ``` +evel.js 里面 `addAttrs` 方法会给数据添加几个属性,treeTotable 会对数组扁平化。这些操作都不会破坏源数据,只是会新增属性。 -#### expandAll - 是否默认全部展开,boolean值,默认为false +调用 addAttrs 后,因\_\_parent 属性,会造成数据循环引用,使用 JSON.stringify()报错,所以转成 JSON 之前需要清除\_\_parent 属性。 -#### evalFunc - 解析函数,function,非必须 +## prop 说明 - 如果不提供,将使用默认的[evalFunc](./eval.js) +- data(原始数据,要求是一个数组或者对象) +- columns(列属性,要求是一个数组) +- renderContent(数组扁平化方法(可选)) +- defaultExpandAll(默认是否全部展开,默认全部展开) +- defaultChildren(子元素名,默认为 children) +- spreadOffset(扩展符号的偏移量,默认为 50px) +- checkboxOffset(复选框的偏移量,默认为 50px) - 如果提供了evalFunc,那么会用提供的evalFunc去解析data,并返回treeTable渲染所需要的值。如何编写一个evalFunc,请参考[*eval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/TreeTable/eval.js)或[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js) +--- -#### evalArgs - 解析函数的参数,是一个数组 +### 代码示例 - **请注意,自定义的解析函数参数第一个为this.data,第二个参数为, this.expandAll,你不需要在evalArgs填写。一定记住,这两个参数是强制性的,并且位置不可颠倒** *this.data为需要解析的数据,this.expandAll为是否默认展开* +- data(**必填**) - 如你的解析函数需要的参数为`(this.data, this.expandAll,1,2,3,4)`,那么你只需要将`[1,2,3,4]`赋值给`evalArgs`就可以了 +原始数据, - 如果你的解析函数参数只有`(this.data, this.expandAll)`,那么就可以不用填写evalArgs了 - - 具体可参考[*customEval.js*](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customEval.js)的函数参数和[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue)的`evalArgs`属性值 - - ## slot - 这是一个自定义列的插槽。 - - 默认情况下,treeTable只有一行行展示数据的功能。但是一般情况下,我们会要给行加上一个操作按钮或者根据当行数据展示不同的样式,这时我们就需要自定义列了。请参考[customTreeTable](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/views/table/treeTable/customTreeTable.vue),[实例效果](https://panjiachen.github.io/vue-element-admin/#/table/tree-table) - - `slot`和`columns属性`可同时存在,columns里面的数据列会在slot自定义列的左边展示 - - ## 其他 - 如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的api自行修改index.vue +```js +const data = [ + { + key1: value1, + key2: value2, + children: [ + { + key1: value1 + }, + { + key1: value1 + } + ] + }, + { + key1: value1 + } +] +``` + +或者 + +```javascript + { + key1: value1, + key2: value2, + children: [{ + key1: value1 + }, + { + key1: value1 + }] + } +``` + +- columns + +1. label: 显示在表头的文字 +2. key: 对应 data 的 key。treeTable 将显示相应的 value +3. width: 每列的宽度,为一个数字(可选) + +树表组件将会根据 columns 的 key 属性生成具名插槽,如果你需要对列数据进行自定义,通过插槽即可实现 + +```javascript +const columns = [ + // 建议第一列做展开收缩操作 + { label: '', key: '__spread', width: '200' }, + // 如果添加复选框 + { label: '', key: '__checkbox', width: '200' }, + { + label: string, + key: string, + width: number + }, + { + label: string, + key: string, + width: number + } +] +``` + +#### renderContent + +解析函数,function,非必须 + +如果不提供,将使用默认的[evalFunc](./eval.js) + +如果提供了 evalFunc,那么会用提供的 evalFunc 去解析 data,并返回 treeTable 渲染所需要的值。 + +## 其他 + +如果有其他的需求,请参考[el-table](http://element-cn.eleme.io/#/en-US/component/table)的 api 自行修改 index.vue diff --git a/src/mock/table.js b/src/mock/table.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/views/table/treeTable/customEval.js b/src/views/table/treeTable/customEval.js deleted file mode 100644 index 73badb68109..00000000000 --- a/src/views/table/treeTable/customEval.js +++ /dev/null @@ -1,48 +0,0 @@ -/** -* @Author: jianglei -* @Date: 2017-10-12 12:06:49 -*/ -'use strict' -import Vue from 'vue' -export default function treeToArray(data, expandAll, parent, level, item) { - const marLTemp = [] - let tmp = [] - Array.from(data).forEach(function(record) { - if (record._expanded === undefined) { - Vue.set(record, '_expanded', expandAll) - } - let _level = 1 - if (level !== undefined && level !== null) { - _level = level + 1 - } - Vue.set(record, '_level', _level) - // 如果有父元素 - if (parent) { - Vue.set(record, 'parent', parent) - // 如果父元素有偏移量,需要计算在this的偏移量中 - // 偏移量还与前面同级元素有关,需要加上前面所有元素的长度和 - if (!marLTemp[_level]) { - marLTemp[_level] = 0 - } - Vue.set(record, '_marginLeft', marLTemp[_level] + parent._marginLeft) - Vue.set(record, '_width', record[item] / parent[item] * parent._width) - // 在本次计算过偏移量后加上自己长度,以供下一个元素使用 - marLTemp[_level] += record._width - } else { - // 如果为根 - // 初始化偏移量存储map - marLTemp[record.id] = [] - // map中是一个数组,存储的是每级的长度和 - // 初始情况下为0 - marLTemp[record.id][_level] = 0 - Vue.set(record, '_marginLeft', 0) - Vue.set(record, '_width', 1) - } - tmp.push(record) - if (record.children && record.children.length > 0) { - const children = treeToArray(record.children, expandAll, record, _level, item) - tmp = tmp.concat(children) - } - }) - return tmp -} diff --git a/src/views/table/treeTable/customTreeTable.vue b/src/views/table/treeTable/customTreeTable.vue index 2a21617195f..1ed346fb5f9 100644 --- a/src/views/table/treeTable/customTreeTable.vue +++ b/src/views/table/treeTable/customTreeTable.vue @@ -1,137 +1,162 @@