From 3523138a8d1490424e77bbee5e2d5ed6c609dc54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=A3=95=E8=B4=A2?= Date: Mon, 25 Oct 2021 21:08:39 +0800 Subject: [PATCH] webpack5 --- .postcssrc.js | 9 +- build/utils.js | 43 +- build/vue-loader.conf.js | 3 +- build/webpack.base.conf.js | 298 +++++++---- build/webpack.dev.conf.js | 41 +- build/webpack.prod.conf.js | 172 ++---- package.json | 106 ++-- src/components/Image/ImageCategoryTree.vue | 518 ++++++++++++++----- src/components/Image/More/Index.vue | 4 +- src/components/Image/More/IndexOneUpdate.vue | 79 +-- src/components/Image/More/sizeimg.vue | 2 +- src/components/Image/ShearSelectUpload.vue | 38 +- src/components/Image/Single/Index.vue | 22 +- src/components/Image/UploadImage.vue | 197 +++---- 14 files changed, 921 insertions(+), 611 deletions(-) diff --git a/.postcssrc.js b/.postcssrc.js index eee3e92d..bc0ad1e3 100644 --- a/.postcssrc.js +++ b/.postcssrc.js @@ -1,10 +1,17 @@ // https://github.com/michael-ciniawsky/postcss-load-config module.exports = { + "autoprefixer": { + "grid": true + }, "plugins": { "postcss-import": {}, "postcss-url": {}, // to edit target browsers: use "browserslist" field in package.json - "autoprefixer": {} + "autoprefixer": {}, + "cssnano":{ + autoprefixer:false, + "postcss-zindex":false, + } } } diff --git a/build/utils.js b/build/utils.js index 2bf91ede..6043e92b 100644 --- a/build/utils.js +++ b/build/utils.js @@ -1,7 +1,7 @@ 'use strict' const path = require('path') const config = require('../config') -const ExtractTextPlugin = require('extract-text-webpack-plugin') +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const packageConfig = require('../package.json') exports.assetsPath = function (_path) { @@ -15,6 +15,13 @@ exports.assetsPath = function (_path) { exports.cssLoaders = function (options) { options = options || {} + const threadLoader = { + loader: 'thread-loader', + options: { + sourceMap: options.sourceMap + } + } + const cssLoader = { loader: 'css-loader', options: { @@ -31,7 +38,7 @@ exports.cssLoaders = function (options) { // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { - const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] + let loaders = options.usePostCSS ? [ cssLoader, postcssLoader] : [ cssLoader] if (loader) { loaders.push({ @@ -44,14 +51,26 @@ exports.cssLoaders = function (options) { // 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', - publicPath:'../' - }) + let loaderss=[]; + if (options.extract) { + loaderss=[ + threadLoader, + { + loader: MiniCssExtractPlugin.loader, + options: { + publicPath:'../' + }, + }, + ] + loaderss=loaderss.concat(loaders) + return loaderss } else { - return ['vue-style-loader'].concat(loaders) + loaderss=[ + threadLoader, + 'vue-style-loader' + ] + loaderss=loaderss.concat(loaders) + return loaderss } } @@ -76,7 +95,8 @@ exports.styleLoaders = function (options) { const loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), - use: loader + use: loader, + exclude:/node_modules/ }) } @@ -90,8 +110,7 @@ exports.createNotifierCallback = () => { if (severity !== 'error') return const error = errors[0] - const filename = error.file && error.file.split('!').pop() - + const filename = error.file && error.file.split('!').pop() notifier.notify({ title: packageConfig.name, message: severity + ': ' + error.name, diff --git a/build/vue-loader.conf.js b/build/vue-loader.conf.js index 8b063c03..33ed58bc 100644 --- a/build/vue-loader.conf.js +++ b/build/vue-loader.conf.js @@ -18,6 +18,5 @@ module.exports = { source: 'src', img: 'src', image: 'xlink:href' - }, - hotReload: false + } } diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js index a1905679..fc983d2c 100644 --- a/build/webpack.base.conf.js +++ b/build/webpack.base.conf.js @@ -2,101 +2,223 @@ const path = require('path') const utils = require('./utils') const config = require('../config') +const webpack = require('webpack') + +const pkg = require('../package.json'); + const vueLoaderConfig = require('./vue-loader.conf') +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin') + +const threadLoader = require('thread-loader'); + + +threadLoader.warmup({ + // pool options, like passed to loader options + // must match loader options to boot the correct pool + }, [ + // modules to load + // can be any module, i. e. + 'vue-loader', + 'css-loader', + 'babel-loader', + 'babel-preset-es2015', + 'sass-loader', + ]); + +var threadLoaderConfig={ + loader: "thread-loader", + // 有同样配置的 loader 会共享一个 worker 池(worker pool) + options: { + // 产生的 worker 的数量,默认是 cpu 的核心数 + //workers: 8, + + // 一个 worker 进程中并行执行工作的数量 + // 默认为 20 + //workerParallelJobs: 20, + + // 额外的 node.js 参数 + //workerNodeArgs: ['--max-old-space-size', '1024'], + + // 闲置时定时删除 worker 进程 + // 默认为 500ms + // 可以设置为无穷大, 这样在监视模式(--watch)下可以保持 worker 持续存在 + //poolTimeout: 2000, -function resolve (dir) { - return path.join(__dirname, '..', dir) + // 池(pool)分配给 worker 的工作数量 + // 默认为 200 + // 降低这个数值会降低总体的效率,但是会提升工作分布更均一 + //poolParallelJobs: 200, + + // 池(pool)的名称 + // 可以修改名称来创建其余选项都一样的池(pool) + name: "my-pool" + } +} +const publicCssLoaders=process.env.NODE_ENV === 'production'?[{loader:MiniCssExtractPlugin.loader,options:{publicPath:'../'}},'css-loader']:[ 'style-loader','css-loader'] + +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 - } + 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: { - 'vue$': 'vue/dist/vue.esm.js', - '@': resolve('src'), - } - }, - module: { - rules: [ - ...(config.dev.useEslint ? [createLintingRule()] : []), - { - test: /\.vue$/, - loader: 'vue-loader', - options: vueLoaderConfig - }, - { - test: /\.js$/, - loader: 'babel-loader?cacheDirectory', - exclude: /node_modules(?!\/quill-image-drop-module|quill-image-resize-module)/, - //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]' + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + clean:true, + path: config.build.assetsRoot, + filename: 'js/[name].[contenthash].js', + pathinfo: false, + 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'), } - }, - { - 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]') - } - } - ] - }, - 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' - } + }, + // 加载器 + module: { + // https://doc.webpack-china.org/guides/migrating/#module-loaders-module-rules + rules: [ + //...(config.dev.useEslint ? [createLintingRule()] : []), + { + test: /\.vue$/, + include: resolve('src'), + use:[ + threadLoaderConfig, + { + loader: 'vue-loader', + /** + options:vueLoaderConfig, + */ + options: { + postcss: [require('postcss-cssnext')()], + loaders: { + js: [ + { loader: 'cache-loader' }, + { loader: 'babel-loader', options: { presets: ['env'] } } + ] + }, + extractCSS: true, + hotReload:true, + + }, + } + ] + + + }, + { + test: /\.css$/, + use: publicCssLoaders, + }, + { + test: /\.(sa|sc)ss$/, + use: publicCssLoaders.concat([ + // 将 Sass 编译成 CSS + 'sass-loader', + ]), + }, + { + test: /\.less$/, + use: publicCssLoaders.concat([ + // 将 Sass 编译成 CSS + 'less-loader', + ]), + }, + { + test: /\.(stylus|styl)$/, + use: publicCssLoaders.concat([ + // 将 Sass 编译成 CSS + 'stylus-loader', + ]), + }, + { // 配置Babel将ES6+ 转换为ES5 + test: /\.js$/, + use:[ + threadLoaderConfig, + { + loader: 'babel-loader', + options: { + presets: ['env'], + plugins: ['transform-runtime'] + }, + }, + ], + include: resolve('src'), + }, + { + test: /\.svg$/, + loader: 'svg-sprite-loader', + include: [resolve('src/icons')], + options: { + symbolId: 'icon-[name]' + } + }, + { + test: /\.(png|jpe?g|gif|tif?f|bmp|webp|svg)(\?.*)?$/, + exclude: [resolve('src/icons')], + type: 'asset', + generator: { + filename: 'img/[hash][ext][query]' + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + type: 'asset/resource', + generator: { + filename: 'media/[hash][ext][query]' + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + type: 'asset/resource', + generator: { + filename: 'fonts/[hash][ext][query]' + } + } + ] + + }, + plugins: [ + new VueLoaderPlugin(), + ], + optimization: { + splitChunks: { + chunks: 'all', + minSize: 200000, + enforceSizeThreshold: 400000, + cacheGroups: { + defaultVendors: { + test: /[\\/]node_modules[\\/]/, + priority: -10, + reuseExistingChunk: true, + enforceSizeThreshold: 400000, + }, + default: { + minChunks: 2, + priority: -20, + reuseExistingChunk: true, + enforceSizeThreshold: 400000, + }, + }, + }, + }, } diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js index aaee625f..6d7c5eb8 100644 --- a/build/webpack.dev.conf.js +++ b/build/webpack.dev.conf.js @@ -5,7 +5,8 @@ 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 HtmlWebpackPlugin = require('html-webpack-plugin') +const CopyWebpackPlugin = require('copy-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') @@ -17,49 +18,49 @@ 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 }) + //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, - } + proxy: config.dev.proxyTable, + client: { + overlay: { + errors: config.dev.errorOverlay, + warnings: false, + }, + }, }, plugins: [ new webpack.DefinePlugin({ + 'process.env.ASSET_PATH': resolve ("/assets/"), 'process.env': require('../config/dev.env') }), - new webpack.HotModuleReplacementPlugin(), - new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: 'index.html', + new HtmlWebpackPlugin({ template: 'index.html', inject: true, favicon: resolve('favicon.ico'), - title: 'vue-element-admin', - path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory + title: 'mdp-arc', }), - new webpack.ProvidePlugin({ - 'window.Quill': 'quill' + + // copy custom static assets + new CopyWebpackPlugin( { + patterns: [ + { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory }, + ] }) ] }) diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js index d08661b7..bcaf14c9 100644 --- a/build/webpack.prod.conf.js +++ b/build/webpack.prod.conf.js @@ -4,63 +4,30 @@ const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') -const baseWebpackConfig = require('./webpack.base.conf') +const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const ExtractTextPlugin = require('extract-text-webpack-plugin') -const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') -const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') + +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); +const TerserPlugin = require("terser-webpack-plugin"); + +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') function resolve (dir) { return path.join(__dirname, '..', dir) } -const env = require('../config/'+process.env.env_config+'.env') +const env = require('../config/'+process.env.ENV_CONFIG+'.env') -const webpackConfig = merge(baseWebpackConfig, { - 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].js'), - chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') - }, +const webpackConfig = merge(baseWebpackConfig, { + mode:'production', + devtool: config.build.productionSourceMap ? config.build.devtool : false, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env - }), - new UglifyJsPlugin({ - uglifyOptions: { - compress: { - warnings: false - } - }, - sourceMap: config.build.productionSourceMap, - parallel: true, - cache:true - }), - // extract css into its own file - new ExtractTextPlugin({ - filename: utils.assetsPath('css/[name].[contenthash].css'), - // Setting the following option to `false` will not extract CSS from codesplit chunks. - // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. - // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 - allChunks: false, - }), - // Compress extracted CSS. We are using this plugin so that possible - // duplicated CSS from different components can be deduped. - new OptimizeCSSPlugin({ - cssProcessorOptions: config.build.productionSourceMap - ? { safe: true, map: { inline: false } } - : { safe: true } - }), + }), // 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 @@ -78,89 +45,58 @@ const webpackConfig = merge(baseWebpackConfig, { // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, - // necessary to consistently work with multiple chunks via CommonsChunkPlugin - chunksSortMode: 'dependency' - }), - // keep module.id stable when vender modules does not change - new webpack.HashedModuleIdsPlugin(), - - - new webpack.ProvidePlugin({ - 'window.Quill': 'quill' - }), + chunksSortMode: 'auto' + }), // enable scope hoisting new webpack.optimize.ModuleConcatenationPlugin(), - // split vendor js into its own file - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks (module) { - // 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 - ) - } - }), - // 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', - minChunks: Infinity - }), - // This instance extracts shared chunks from code splitted chunks and bundles them - // in a separate chunk, similar to the vendor chunk - // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk - new webpack.optimize.CommonsChunkPlugin({ - name: 'app', - async: 'vendor-async', - children: true, - minChunks: 3 - }), - // 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); - } + + new MiniCssExtractPlugin({ + filename: "css/[name].[contenthash].css", + chunkFilename: "css/[id].[contenthash].css", }), - // split xlsx into its own file - new webpack.optimize.CommonsChunkPlugin({ - async: 'xlsx', - minChunks(module) { - var context = module.context; - return context && (context.indexOf('xlsx') >= 0); - } + + // copy custom static assets + new CopyWebpackPlugin({ + patterns: [ + { + from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory + } + ], }), - // split codemirror into its own file - new webpack.optimize.CommonsChunkPlugin({ - async: 'codemirror', - minChunks(module) { - var context = module.context; - return context && (context.indexOf('codemirror') >= 0); - } + new FriendlyErrorsPlugin({ + onErrors: utils.createNotifierCallback() }), - - // copy custom static assets - new CopyWebpackPlugin([ - { - from: path.resolve(__dirname, '../static'), - to: config.build.assetsSubDirectory, - ignore: ['.*'] - } - ]) - ] + ], + optimization: { + moduleIds:'hashed', + minimize: true, + minimizer:[ + new CssMinimizerPlugin({ + parallel:true + }), + new TerserPlugin({ + extractComments: false, + minify: TerserPlugin.uglifyJsMinify, + // `terserOptions` options will be passed to `uglify-js` + // Link to options - https://github.com/mishoo/UglifyJS#minify-options + terserOptions: {}, + }) + ], + splitChunks: { + chunks: 'all', + minSize: { + javascript: 80000, + webassembly: 80000, + }, + }, + }, }) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( - new CompressionWebpackPlugin({ - asset: '[path].gz[query]', + new CompressionWebpackPlugin({ algorithm: 'gzip', test: new RegExp( '\\.(' + diff --git a/package.json b/package.json index 8fa9d2f3..6156f510 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "MIT", "private": true, "scripts": { - "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "dev": "webpack-dev-server --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", "build:m1prod": "cross-env NODE_ENV=production env_config=m1prod node build/build.js", @@ -17,33 +17,27 @@ "@jiaminghi/data-view": "^2.10.0", "axios": "0.17.1", "clipboard": "1.7.1", + "vue-clipboard2": "^0.3.3", "codemirror": "5.32.0", "dayjs": "^1.8.29", "decimal.js": "^10.2.0", "dropzone": "5.2.0", - "echarts": "^3.8.5", + "echarts": "3.8.5", "element-ui": "^2.13.0", - "file-saver": "^2.0.1", - "font-awesome": "4.7.0", + "file-saver": "2.0.1", "gantt-elastic": "^1.0.11", "gantt-elastic-header": "^0.1.11", - "highlight.js": "^9.12.0", + "font-awesome": "4.7.0", "html2canvas": "^1.0.0-alpha.9", - "i": "^0.3.6", "js-cookie": "2.2.0", "js-md5": "^0.7.3", "jsonlint": "1.6.2", "jszip": "3.2.1", - "less": "^3.12.2", - "less-loader": "^4.1.0", "mockjs": "1.0.1-beta3", "moment": "^2.24.0", "normalize.css": "7.0.0", "nprogress": "0.2.0", "object-assign": "^4.1.1", - "qrcodejs2": "0.0.2", - "quill-image-drop-module": "^1.0.3", - "quill-image-resize-module": "^3.0.0", "screenfull": "3.3.2", "showdown": "1.8.5", "simplemde": "1.11.2", @@ -55,67 +49,85 @@ "vue-cropper": "^0.2.9", "vue-gantt-schedule-timeline-calendar": "^1.0.33", "vue-i18n": "7.3.2", - "vue-image-crop-upload": "^1.3.14", - "vue-multiselect": "2.0.8", - "vue-quill-editor": "^3.0.6", "vue-router": "3.0.1", - "vue-splitpane": "1.0.2", - "vuedraggable": "^2.24.3", + "vuedraggable": "2.15.0", "vuex": "3.0.1", "wl-gantt": "^1.0.4", "xlsx": "^0.14.5" }, "devDependencies": { - "autoprefixer": "7.2.3", - "babel-core": "6.26.0", - "babel-eslint": "8.0.3", - "babel-helper-vue-jsx-merge-props": "2.0.3", - "babel-loader": "7.1.2", - "babel-plugin-syntax-jsx": "6.18.0", - "babel-plugin-transform-runtime": "6.23.0", - "babel-plugin-transform-vue-jsx": "3.5.0", - "babel-preset-env": "1.6.1", - "babel-preset-stage-2": "6.24.1", + "@babel/core": "^7.15.8", + "@babel/preset-env": "^7.15.8", + "@babel/preset-react": "^7.14.5", + "acorn": "^8.5.0", + "acorn-import-assertions": "^1.8.0", + "autoprefixer": "^10.3.7", + "babel-core": "^6.26.3", + "babel-loader": "^7.1.5", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-plugin-transform-vue-jsx": "^3.7.0", + "babel-polyfill": "^6.26.0", + "babel-preset-env": "^1.7.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "babel-runtime": "^6.26.0", "chalk": "2.3.0", - "copy-webpack-plugin": "4.3.0", + "compression-webpack-plugin": "^9.0.0", + "copy-webpack-plugin": "^9.0.1", "cross-env": "5.1.1", - "css-loader": "0.28.7", + "css-loader": "^6.4.0", + "css-minimizer-webpack-plugin": "^3.1.1", + "cssnano": "^5.0.8", "eslint": "4.13.1", "eslint-friendly-formatter": "3.0.0", "eslint-loader": "1.9.0", "eslint-plugin-html": "4.0.1", - "extract-text-webpack-plugin": "3.0.2", - "file-loader": "1.1.5", - "friendly-errors-webpack-plugin": "1.6.1", - "html-webpack-plugin": "2.30.1", + "extract-text-webpack-plugin": "^3.0.2", + "file-loader": "^6.2.0", + "friendly-errors-plugin": "^1.1.2", + "friendly-errors-webpack-plugin": "^1.7.0", + "happypack": "^4.0.0", + "html-webpack-plugin": "^5.4.0", + "less": "^4.1.2", + "less-loader": "^10.2.0", + "mini-css-extract-plugin": "^2.4.3", + "node-loader": "^2.0.0", "node-notifier": "5.1.2", - "node-sass": "^4.5.0", - "optimize-css-assets-webpack-plugin": "3.2.0", + "node-sass": "^4.14.1", "ora": "1.3.0", "portfinder": "1.0.13", + "postcss": "^8.3.11", + "postcss-cssnext": "^3.1.1", "postcss-import": "11.0.0", - "postcss-loader": "2.0.9", + "postcss-loader": "^6.2.0", + "postcss-merge-rules": "^5.0.2", "postcss-url": "7.3.0", "pushstate-server": "3.0.1", - "quill-image-extend-module": "^1.1.2", "rimraf": "2.6.2", - "sass-loader": "6.0.6", - "script-loader": "^0.7.2", + "sass-loader": "^12.2.0", + "script-loader": "0.7.2", "semver": "5.4.1", "shelljs": "0.7.8", - "svg-sprite-loader": "3.5.2", - "uglifyjs-webpack-plugin": "1.1.3", - "url-loader": "0.6.2", - "vue-loader": "13.5.0", - "vue-style-loader": "3.0.3", - "vue-template-compiler": "2.6.10", - "webpack": "3.10.0", + "stream": "0.0.2", + "style-loader": "^3.3.1", + "svg-sprite-loader": "^6.0.10", + "terser-webpack-plugin": "^5.2.4", + "thread-loader": "^3.0.4", + "uglifyjs-webpack-plugin": "^2.2.0", + "url-loader": "^4.1.1", + "vue-loader": "^15.9.8", + "vue-style-loader": "^4.1.3", + "vue-template-compiler": "^2.6.14", + "webpack": "^5.59.1", "webpack-bundle-analyzer": "2.9.1", - "webpack-dev-server": "2.9.7", + "webpack-cli": "^4.9.1", + "webpack-dev-middleware": "^5.2.1", + "webpack-dev-server": "^4.3.1", "webpack-merge": "4.1.1" }, "engines": { - "node": ">= 4.0.0", + "node": ">= 10.13.0", "npm": ">= 3.0.0" }, "browserslist": [ diff --git a/src/components/Image/ImageCategoryTree.vue b/src/components/Image/ImageCategoryTree.vue index 482e5bd2..1b9010ab 100644 --- a/src/components/Image/ImageCategoryTree.vue +++ b/src/components/Image/ImageCategoryTree.vue @@ -1,87 +1,125 @@ - \ No newline at end of file + diff --git a/src/components/Image/More/Index.vue b/src/components/Image/More/Index.vue index d9ac04f2..e5150128 100644 --- a/src/components/Image/More/Index.vue +++ b/src/components/Image/More/Index.vue @@ -2,7 +2,7 @@
- +
@@ -126,7 +126,7 @@ }, addImg(){ if(parseInt(this.limit)<=this.imageLists.length){ - this.$message({showClose: true, message: "图片数量已经超过", type: 'error' }); + this.$message({ message: "图片数量已经超过", type: 'error' }); return; } this.addFormVisible = true; diff --git a/src/components/Image/More/IndexOneUpdate.vue b/src/components/Image/More/IndexOneUpdate.vue index 3f64b0a0..3ea4b8c0 100644 --- a/src/components/Image/More/IndexOneUpdate.vue +++ b/src/components/Image/More/IndexOneUpdate.vue @@ -2,7 +2,7 @@
- +
@@ -12,7 +12,23 @@
{{index+1}},  - {{o[valueName]}} + {{o[desName]}} + + + 图片标题: + + + 跳转链接: + + + + 扩展信息: + + 编辑 + 删除 @@ -30,7 +46,7 @@ - + @@ -49,11 +65,11 @@ export default { props:['branchId','categoryId','remark','showAdd','limit','urlName','desName','value','valueName','deptid','imgWidth','imgHeight'], watch: { - 'value':function(val){ - this.imageLists = val; + value(val){ + this.imageLists=val }, - 'imageLists':function(val){ - this.$emit('input',val); + imageLists(val){ + this.$emit("input",val) } }, data() { @@ -67,48 +83,35 @@ imageLists:[],//存放图片信息的数组 {urlName:,desName:,opflag:add/del/edit,order:} selectedImgIndex:this.value.length, opflag:'',//add/del/edit + imageEditVisible:false, /**end 在上面加自定义属性**/ }//end return },//end data methods: { selectedImage(index){ this.selectedImgIndex = index;//注意修改图片url后清空 + this.image=this.imageLists[index] this.opflag='edit'; this.addFormVisible = true; }, - handleConfirm(img){ - this.image=img; - this.uploadSuccess(this.image) - console.log(this.image); + handleConfirm(imgs){ + this.selectedImgIndex=0 + this.image=imgs[0] + this.imageLists=imgs.map(i=>{ + var img= { ...i } + img[this.urlName]=i.url + img[this.desName]=i.remark + img[this.valueName]=i.url + return img; + }) //this.shearMngVisible=true; }, //上传64图片后,指定回调父组件的方法,一般用于保存该图片的信息到另一张表 - uploadSuccess(parm){ - //商品相册中,过滤添加图片和修改图片,获取图片url添加到该集合的指定url中 - if(this.opflag=='edit'){ - this.imageLists[this.selectedImgIndex][this.urlName] = parm.url; //该方式修改图片后是否不会立即显示url。 - //this.$emit('input',this.imageLists); - this.$emit('editImg',this.imageLists[this.selectedImgIndex]); - this.shearMngVisible=false; - }else if(this.opflag=='add'){ - //在此处为添加按钮 - //获取添加图片的信息,并且添加,删除是同时删除数据 - var g={}; - g[this.urlName]=parm.url; - if(this.desName!=null&&this.desName!=''&&this.desName!='undefined'){ - g[this.desName]=parm.remark; - } - this.imageLists.push(g); - this.shearMngVisible=false; - this.$emit('addImg',g); - //this.$emit('input',this.imageLists); - } - //商品相册可以修改图片和添加图片 - /*this.imageUrl = this.converUrl(parm.url); - this.shearMngVisible=false; */ + uploadSuccess(parms){ + }, /**begin 在下面加自定义方法,记得补上面的一个逗号**/ - converUrl(o){ + converUrl(o){ if(!o[this.urlName].indexOf('http')==0 && !o[this.urlName].indexOf('www')==0){ return config.getArcImagePath()+"/"+o[this.urlName]; } @@ -127,7 +130,7 @@ }, addImg(){ if(parseInt(this.limit)<=this.imageLists.length){ - this.$message({showClose: true, message: "图片数量已经超过", type: 'error' }); + this.$message({ message: "图片数量已经超过", type: 'error' }); return; } this.addFormVisible = true; @@ -142,6 +145,10 @@ this.$emit('delImg',returnDate); }); + }, + showEditImage(img,index){ + this.image=img; + this.imageEditVisible=true; } /**end 在上面加自定义方法**/ },//end method diff --git a/src/components/Image/More/sizeimg.vue b/src/components/Image/More/sizeimg.vue index 75772235..154bc5f5 100644 --- a/src/components/Image/More/sizeimg.vue +++ b/src/components/Image/More/sizeimg.vue @@ -124,7 +124,7 @@ }, addImg(){ if(parseInt(this.limit)<=this.imageLists.length){ - this.$message({showClose: true, message: "图片数量已经超过", type: 'error' }); + this.$message({ message: "图片数量已经超过", type: 'error' }); return; } this.addFormVisible = true; diff --git a/src/components/Image/ShearSelectUpload.vue b/src/components/Image/ShearSelectUpload.vue index 7fbac129..08f4425e 100644 --- a/src/components/Image/ShearSelectUpload.vue +++ b/src/components/Image/ShearSelectUpload.vue @@ -63,7 +63,7 @@