vue版本升级为2.6 优化cdn加载,优化部分样式,删除某部分图片,修改店铺bug

master
lemon橪 2021-09-06 17:01:38 +08:00
parent 43349a51d1
commit b0021a759f
56 changed files with 5319 additions and 29769 deletions

View File

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

View File

View File

@ -1,25 +1,19 @@
### 全局css src/assets/styles # new
### 工具类 src/plugins ## Project setup
```
npm install
```
### 顶部广告页 src/components/advertising ### Compiles and hot-reloads for development
```
### 全部商品分类 components/nav npm run serve
```
### 底部导航栏 components/footer
### 发票模态框 components/invoiceModal
### 商品详情 pages/GoodsDetail.vue
#### 商品详情组件 components/goodsDetail
### 全部商品分类 pages/AllCategories.vue
### 意见反馈 pages/Feedback.vue
### 卡片的封装 components/card
### 购物车 pages/Cart.vue
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
buyer/babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@ -1,41 +0,0 @@
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
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')
const spinner = ora('building for production...')
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, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
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'
))
})
})

View File

@ -1,54 +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)
}
}

View File

@ -1,110 +0,0 @@
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath: '../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less' , { javascriptEnabled : true }),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass').concat(
{
loader: 'sass-resources-loader',
options: {
//你自己的scss全局文件的路径
resources: path.resolve(__dirname, '../src/assets/styles/global.scss')
}
}
),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
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')
})
}
}

View File

@ -1,22 +0,0 @@
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}

View File

@ -1,111 +0,0 @@
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
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: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
// ...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
// {
// test: /\.less$/,
// loader: "style-loader!css-loader!less-loader",
// },
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
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]')
}
},
{
test: /\.(cur)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('cur/[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'
}
}

View File

@ -1,95 +0,0 @@
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
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: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
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(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
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)
}
})
})

View File

@ -1,145 +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 ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: false,
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')
},
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
}),
// 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.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// 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
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// 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 vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// 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
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
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.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig

View File

@ -1,41 +0,0 @@
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
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')
const spinner = ora('building for production...')
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, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
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'
))
})
})

View File

@ -1,54 +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)
}
}

View File

@ -1,110 +0,0 @@
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath: '../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less' , { javascriptEnabled : true }),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass').concat(
{
loader: 'sass-resources-loader',
options: {
//你自己的scss全局文件的路径
resources: path.resolve(__dirname, '../src/assets/styles/global.scss')
}
}
),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
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')
})
}
}

View File

@ -1,22 +0,0 @@
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}

View File

@ -1,111 +0,0 @@
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
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: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
// ...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
// {
// test: /\.less$/,
// loader: "style-loader!css-loader!less-loader",
// },
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
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]')
}
},
{
test: /\.(cur)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('cur/[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'
}
}

View File

@ -1,95 +0,0 @@
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
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: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
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(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
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)
}
})
})

View File

@ -1,145 +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 ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: false,
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')
},
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
}),
// 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.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// 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
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// 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 vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// 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
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
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.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig

View File

@ -1,8 +0,0 @@
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL:''
})

View File

@ -1,84 +0,0 @@
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
// const api = 'http://www.baidu.com'
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
// '/api': {
// target:api,
// changeOrigin:true,
// pathRewrite:{
// '^/api':''
// }
// }
},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 10000, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
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: false,
// 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-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: true,
// 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 --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}

View File

@ -1,5 +0,0 @@
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_URL:'http://www.baidu.com'
}

BIN
buyer/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="./static/logo.ico" type="image/x-icon">
<script src="https://yzf.qq.com/xv/web/static/chat_sdk/yzf_chat.min.js"></script>
<title>LILI</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

32569
buyer/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,26 @@
{ {
"name": "lilishop-vue", "name": "lilishop",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "dev": "vue-cli-service serve",
"start": "npm run dev", "serve": "vue-cli-service serve",
"lint": "eslint --ext .js,.vue src", "build": "vue-cli-service build"
"build": "node build/build.js"
}, },
"dependencies": { "dependencies": {
"@amap/amap-jsapi-loader": "0.0.7", "@amap/amap-jsapi-loader": "0.0.7",
"axios": "^0.19.2", "axios": "^0.19.2",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"less": "^3.12.2", "less": "^2.7.0",
"less-loader": "^5.0.0", "less-loader": "^5.0.0",
"mv-count-down": "^0.1.15", "mv-count-down": "^0.1.15",
"node-sass": "^4.14.1",
"psl": "^1.8.0", "psl": "^1.8.0",
"qs": "^6.9.4", "qs": "^6.9.4",
"sass-loader": "^7.3.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"v-distpicker": "^1.0.17",
"view-design": "^4.3.2", "view-design": "^4.3.2",
"vue": "^2.5.2", "vue": "^2.6.11",
"vue-awesome-swiper": "^3.1.3", "vue-awesome-swiper": "^3.1.3",
"vue-piczoom": "^1.0.6", "vue-piczoom": "^1.0.6",
"vue-qr": "^2.3.0", "vue-qr": "^2.3.0",
@ -28,62 +28,15 @@
"vuex": "^3.0.1" "vuex": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^7.1.2", "@vue/cli-service": "~4.5.0",
"babel-core": "^6.22.1", "compression-webpack-plugin": "^5.0.0",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"node-notifier": "^5.1.2",
"node-sass": "^4.14.1",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"sass-loader": "^7.3.1", "sass-loader": "^7.3.1",
"sass-resources-loader": "^2.0.3", "uglifyjs-webpack-plugin": "^2.2.0",
"semver": "^5.3.0", "vue-template-compiler": "^2.6.11"
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}, },
"browserslist": [ "browserslist": [
"> 1%", "> 1%",
"last 2 versions", "last 2 versions",
"not ie <= 8" "not dead"
] ]
} }

23
buyer/public/index.html Normal file
View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>logo.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%=css%>" />
<% } %>
</head>
<body>
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%=js%>"></script>
<% } %>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

BIN
buyer/public/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,3 +1,5 @@
// coupon
.coupon-list { .coupon-list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@ -13,15 +15,16 @@
.c-left { .c-left {
width: 100%; width: 100%;
padding: 20px; padding: 20px;
>div, > p { > div,
> p {
margin-bottom: 10px; margin-bottom: 10px;
} }
>div { > div {
.price{ .price {
color: $theme_color; color: $theme_color;
font-size: 20px; font-size: 20px;
} }
.describe{ .describe {
background-color: #fff4ec; background-color: #fff4ec;
color: $theme_color; color: $theme_color;
padding: 0 5px; padding: 0 5px;
@ -29,14 +32,14 @@
font-size: 13px; font-size: 13px;
} }
} }
p:nth-of-type(1){ p:nth-of-type(1) {
font-weight: bold; font-weight: bold;
} }
p:nth-of-type(2){ p:nth-of-type(2) {
color: #999; color: #999;
} }
} }
b{ b {
position: absolute; position: absolute;
z-index: 2; z-index: 2;
top: 0; top: 0;
@ -56,7 +59,7 @@
font-size: 16px; font-size: 16px;
padding: 20px; padding: 20px;
} }
i{ i {
position: absolute; position: absolute;
width: 20px; width: 20px;
height: 20px; height: 20px;
@ -64,25 +67,24 @@
border: 1px solid #eee; border: 1px solid #eee;
background-color: #fff; background-color: #fff;
border-radius: 20px; border-radius: 20px;
&:after{ &:after {
content: ''; content: "";
position: absolute; position: absolute;
width: 25px; width: 25px;
height: 20px; height: 20px;
left: -2px; left: -2px;
background-color: #fff; background-color: #fff;
} }
} }
i.circle-top{ i.circle-top {
top: -10px; top: -10px;
&::after{ &::after {
top: -11px; top: -11px;
} }
} }
i.circle-bottom{ i.circle-bottom {
bottom: -10px; bottom: -10px;
&::after{ &::after {
bottom: -11px; bottom: -11px;
} }
} }

View File

@ -1,17 +1,111 @@
/*
* @Author: LMR
* @Date: 2020-08-11 10:12:34
* @Last Modified by: LMR
* @Last Modified time: 2020-08-18 16:00:10
*/
// //
@import "./theme.scss";
.global_color{
//
$primary_color: #2d8cf0;
$primary_light_color: #0f1011;
$primary_dark_color: #2b85e4;
$success_color: #19be6b;
$warning_color: #ff9900;
$error_color: #ed3f14;
$handle-btn-color: #438cde;
$theme_color: #ed3f14;
$border_color: #dddee1;
$title_color: #8c8c8c;
$light_title_color: #1c2438;
$light_content_color: #495060;
$light_sub_color: #80848f;
$light_background_color: #f8f8f9;
$light_white_background_color: #fff;
//
$dark_background_color: #141414;
$dark_sub_background_color: #1d1d1d; //
$dark_content_color: #d5d5d5;
/***** 封装一些方法可用于 黑暗主题 ,明亮主题 *****/
//
@mixin background_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_background_color;
}
[data-theme="light"] & {
background-color: $light_background_color;
}
}
//
@mixin sub_background_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_sub_background_color;
}
[data-theme="light"] & {
background-color: $light_background_color;
}
}
@mixin white_background_color() {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $light_white_background_color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_sub_background_color;
}
[data-theme="light"] & {
background-color: $light_white_background_color;
}
}
//
@mixin content_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_content_color;
}
}
//
@mixin sub_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_sub_color;
}
}
//
@mixin title_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_title_color;
}
}
//
.global_color {
color: $theme_color; color: $theme_color;
} }
.global_background_color{ .global_background_color {
background-color: $theme_color; background-color: $theme_color;
} }
.global_text_left { .global_text_left {
@ -26,44 +120,96 @@
.global_float_right { .global_float_right {
float: right; float: right;
} }
.clearfix::after{ .clearfix::after {
content: ''; content: "";
display: block; display: block;
clear: both; clear: both;
} }
.width_1200{width: 1200px;} .width_1200 {
.width_800{width: 800px;} width: 1200px;
.width_400{width: 400px;} }
.width_300{width: 300px;} .width_800 {
.width_200{width: 200px;} width: 800px;
.width_100{width: 100px;} }
.width_400 {
width: 400px;
}
.width_300 {
width: 300px;
}
.width_200 {
width: 200px;
}
.width_100 {
width: 100px;
}
.fontsize_12{font-size: 12px;} .fontsize_12 {
.fontsize_14{font-size: 14px;} font-size: 12px;
.fontsize_16{font-size: 16px;} }
.fontsize_18{font-size: 18px;} .fontsize_14 {
font-size: 14px;
}
.fontsize_16 {
font-size: 16px;
}
.fontsize_18 {
font-size: 18px;
}
.mb_20{margin-bottom: 20px;} .mb_20 {
.mt_20{margin-top: 20px;} margin-bottom: 20px;
.ml_20{margin-left: 20px;} }
.mr_20{margin-right: 20px;} .mt_20 {
margin-top: 20px;
}
.ml_20 {
margin-left: 20px;
}
.mr_20 {
margin-right: 20px;
}
.mb_10{margin-bottom: 10px;} .mb_10 {
.mt_10{margin-top: 10px;} margin-bottom: 10px;
.ml_10{margin-left: 10px;} }
.mr_10{margin-right: 10px;} .mt_10 {
margin-top: 10px;
}
.ml_10 {
margin-left: 10px;
}
.mr_10 {
margin-right: 10px;
}
.pb_20{padding-bottom: 20px;} .pb_20 {
.pt_20{padding-top: 20px;} padding-bottom: 20px;
.pl_20{padding-left: 20px;} }
.pr_20{padding-right: 20px;} .pt_20 {
padding-top: 20px;
}
.pl_20 {
padding-left: 20px;
}
.pr_20 {
padding-right: 20px;
}
.pb_10{padding-bottom: 10px;} .pb_10 {
.pt_10{padding-top: 10px;} padding-bottom: 10px;
.pl_10{padding-left: 10px;} }
.pr_10{padding-right: 10px;} .pt_10 {
padding-top: 10px;
}
.pl_10 {
padding-left: 10px;
}
.pr_10 {
padding-right: 10px;
}
.color999{ .color999 {
color: #999; color: #999;
} }
@ -71,42 +217,43 @@ html,
body { body {
height: 100%; height: 100%;
width: 100%; width: 100%;
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial,
sans-serif;
// overflow: hidden; // overflow: hidden;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
li{ li {
list-style: none; list-style: none;
} }
.hover-color:hover{ .hover-color:hover {
color: $theme_color!important; color: $theme_color !important;
cursor: pointer; cursor: pointer;
} }
.hover-pointer{ .hover-pointer {
cursor: pointer; cursor: pointer;
} }
.center{ .center {
margin: 0 auto; margin: 0 auto;
} }
.relative{ .relative {
position: relative; position: relative;
} }
.ellipsis{ .ellipsis {
overflow: hidden; overflow: hidden;
text-overflow:ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.promotion-decorate{ .promotion-decorate {
width: 200px; width: 200px;
text-align: center; text-align: center;
font-size: 25px; font-size: 25px;
position: relative; position: relative;
font-weight: bold; font-weight: bold;
margin: 30px auto 30px; margin: 30px auto 30px;
&::before,&::after{ &::before,
content: ''; &::after {
content: "";
display: inline-block; display: inline-block;
width: 25px; width: 25px;
height: 20px; height: 20px;
@ -117,9 +264,76 @@ li{
top: 10px; top: 10px;
left: -3px; left: -3px;
} }
&::after{ &::after {
background-position: -24px 0; background-position: -24px 0;
right: -3px; right: -3px;
left: auto; left: auto;
} }
}
// goodsList
.text-danger {
color: $theme_color;
}
.seckill-price{
margin-right: 5px;
font-size: 25px;
font-weight: bold;
}
.goods-list {
display: flex;
flex-wrap: wrap;
width: 1200px;
margin: 0 auto;
}
.goods-show-info {
width: 235px;
padding: 6px;
margin: 10px 0px;
margin-left: 5px;
position: relative;
border: 1px solid #fff;
cursor: pointer;
background-color: #fff;
}
.goods-show-info:hover {
border: 1px solid #ccc;
box-shadow: 0px 0px 15px #ccc;
}
.goods-show-price {
margin-top: 6px;
}
.goods-show-detail {
font-size: 12px;
margin: 6px 0px;
}
.goods-show-num {
font-size: 12px;
margin-bottom: 6px;
color: #666;
}
.goods-show-num {
font-size: 12px;
margin-bottom: 6px;
color: #009688;
}
.goods-show-num span {
color: #005aa0;
font-weight: bold;
}
.goods-show-seller {
font-size: 12px;
color: $theme_color;
}
.goods-page {
margin:10px auto ;
text-align: right;
width: 1200px;
} }

View File

@ -7,78 +7,3 @@
@table-td-stripe-bg : #f8f8f9; @table-td-stripe-bg : #f8f8f9;
@table-td-hover-bg : #ededed; @table-td-hover-bg : #ededed;
@table-td-highlight-bg : #ededed; @table-td-highlight-bg : #ededed;
//
//.colorPaletteMixin() {
// @functions: ~`(function() {
// var hueStep = 2;
// var saturationStep = 0.16;
// var saturationStep2 = 0.05;
// var brightnessStep1 = 0.05;
// var brightnessStep2 = 0.15;
// var lightColorCount = 5;
// var darkColorCount = 4;
//
// var getHue = function(hsv, i, isLight) {
// var hue;
// if (hsv.h >= 60 && hsv.h <= 240) {
// hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
// } else {
// hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
// }
// if (hue < 0) {
// hue += 360;
// } else if (hue >= 360) {
// hue -= 360;
// }
// return Math.round(hue);
// };
// var getSaturation = function(hsv, i, isLight) {
// var saturation;
// if (isLight) {
// saturation = hsv.s - saturationStep * i;
// } else if (i === darkColorCount) {
// saturation = hsv.s + saturationStep;
// } else {
// saturation = hsv.s + saturationStep2 * i;
// }
// if (saturation > 1) {
// saturation = 1;
// }
// if (isLight && i === lightColorCount && saturation > 0.1) {
// saturation = 0.1;
// }
// if (saturation < 0.06) {
// saturation = 0.06;
// }
// return Number(saturation.toFixed(2));
// };
// var getValue = function(hsv, i, isLight) {
// var value;
// if (isLight) {
// value = hsv.v + brightnessStep1 * i;
// }else{
// value = hsv.v - brightnessStep2 * i
// }
// if (value > 1) {
// value = 1;
// }
// return Number(value.toFixed(2))
// };
//
// this.colorPalette = function(color, index) {
// var isLight = index <= 6;
// var hsv = tinycolor(color).toHsv();
// var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1;
// return tinycolor({
// h: getHue(hsv, i, isLight),
// s: getSaturation(hsv, i, isLight),
// v: getValue(hsv, i, isLight),
// }).toHexString();
// };
//})()`;
//}
//.colorPaletteMixin();

View File

@ -1,114 +0,0 @@
/*
* @Author: LMR
* @Date: 2020-08-14 11:04:12
* @Last Modified by: LMR
* @Last Modified time: 2020-08-18 14:21:41
*/
//
//
$primary_color: #2d8cf0;
$primary_light_color: #0f1011;
$primary_dark_color: #2b85e4;
$success_color: #19be6b;
$warning_color: #ff9900;
$error_color: #ed3f14;
$handle-btn-color: #438cde;
$theme_color: #ed3f14;
$border_color: #dddee1;
$title_color: #8c8c8c;
$light_title_color: #1c2438;
$light_content_color: #495060;
$light_sub_color: #80848f;
$light_background_color: #f8f8f9;
$light_white_background_color :#fff;
//
$dark_background_color: #141414;
$dark_sub_background_color: #1d1d1d; //
$dark_content_color: #d5d5d5;
/***** 封装一些方法可用于 黑暗主题 ,明亮主题 *****/
//
@mixin background_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_background_color;
}
[data-theme="light"] & {
background-color: $light_background_color;
}
}
//
@mixin sub_background_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_sub_background_color;
}
[data-theme="light"] & {
background-color: $light_background_color;
}
}
@mixin white_background_color() {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $light_white_background_color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_sub_background_color;
}
[data-theme="light"] & {
background-color: $light_white_background_color;
}
}
//
@mixin content_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_content_color;
}
}
//
@mixin sub_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_sub_color;
}
}
//
@mixin title_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_title_color;
}
}

View File

@ -157,6 +157,6 @@ export default {
position: relative; position: relative;
height: 0px; height: 0px;
top: -38px; top: -38px;
left: 336px; left: 339px;
} }
</style> </style>

View File

@ -35,6 +35,6 @@ export default {
} }
p { p {
cursor: pointer; cursor: pointer;
@include sub_color($light_sub_color);
} }
</style> </style>

View File

@ -346,7 +346,7 @@ export default {
} }
.inventory { .inventory {
padding-left: 4px; padding-left: 4px;
@include sub_color($light_sub_color);
} }
.global_color { .global_color {
@ -597,6 +597,9 @@ export default {
.add-buy-car { .add-buy-car {
margin-top: 15px; margin-top: 15px;
>*{
margin: 0 4px;
}
} }
.goodsConfig { .goodsConfig {

View File

@ -421,9 +421,6 @@ export default {
} }
} }
img:hover{
cursor: url(require('../../../static/small.cur')),auto;
}
} }
} }

View File

@ -17,10 +17,10 @@
</li> </li>
<li v-show="!!userInfo.username"> <li v-show="!!userInfo.username">
<div class="username-p"> <div class="username-p">
<p> <div>
<Avatar class="person-icon" :src="userInfo.face" icon="person" size="small" /> <Avatar class="person-icon" :src="userInfo.face" icon="person" size="small" />
<span class="username">{{ userInfo.nickName? userInfo.nickName : userInfo.username | secrecyMobile }}</span> <span class="username">{{ userInfo.nickName? userInfo.nickName : userInfo.username | secrecyMobile }}</span>
</p> </div>
<transition name='fade'> <transition name='fade'>
<ul class="drop-items"> <ul class="drop-items">
<li @click="goUserCenter('/home')"></li> <li @click="goUserCenter('/home')"></li>
@ -184,7 +184,7 @@ export default {
.first, .first,
.username, .username,
.shopping-cart-null span { .shopping-cart-null span {
@include sub_color($light_sub_color);
} }
.box { .box {
@ -308,8 +308,11 @@ export default {
} }
.username-p { .username-p {
position: relative; position: relative;
p{ div{
cursor: pointer; cursor: pointer;
>span{
margin-left: 5px;
}
} }
.drop-items { .drop-items {
position: absolute; position: absolute;

View File

@ -152,15 +152,7 @@ export default {
} }
} }
} }
/** 限时秒杀 */
.limit-img {
display: flex;
flex-direction: row;
img {
width: 300px;
height: 100px;
}
}
/** 折扣广告 */ /** 折扣广告 */
.discountAdvert { .discountAdvert {
width: 1300px; width: 1300px;
@ -173,7 +165,7 @@ export default {
padding-left: 295px; padding-left: 295px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: start; align-items: flex-start;
img { img {
margin-top: 10px; margin-top: 10px;
margin-right: 10px; margin-right: 10px;
@ -185,16 +177,6 @@ export default {
} }
} }
/** 装修模态框 内部样式start */
.modal-top-advert {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
> * {
margin-bottom: 10px;
}
}
.width_1200_auto{ .width_1200_auto{
width: 1200px; width: 1200px;
margin: 0 auto; margin: 0 auto;

View File

@ -3,7 +3,7 @@ import App from './App';
import router from './router'; import router from './router';
import ViewUI from 'view-design'; import ViewUI from 'view-design';
import './assets/styles/theme.less'; import './assets/styles/theme.less';
import './assets/iconfont/iconfont.css'; // import './assets/iconfont/iconfont.css';
import * as filters from './plugins/filters'; import * as filters from './plugins/filters';
import store from '@/vuex/store' import store from '@/vuex/store'
import storage from '@/plugins/storage'; import storage from '@/plugins/storage';
@ -47,9 +47,7 @@ Vue.prototype.connectCs = function (sign = '37ef9b97807d03c6741298ed4eb5b536d2d2
Vue.prototype.Cookies = storage Vue.prototype.Cookies = storage
/* eslint-disable no-new */ /* eslint-disable no-new */
new Vue({ new Vue({
el: '#app',
router, router,
store, store,
components: { App }, render: h => h(App)
template: '<App/>' }).$mount("#app")
});

View File

@ -41,23 +41,23 @@
class="goods-show-info" class="goods-show-info"
v-for="(item, index) in goodsList" v-for="(item, index) in goodsList"
:key="index" :key="index"
@click="goGoodsDetail(item.id, item.goodsId)" @click="goGoodsDetail(item.content.id, item.content.goodsId)"
> >
<div class="goods-show-img"> <div class="goods-show-img">
<img width="220" height="220" :src="item.thumbnail" /> <img width="220" height="220" :src="item.content.thumbnail" />
</div> </div>
<div class="goods-show-price"> <div class="goods-show-price">
<span> <span>
<span class="seckill-price text-danger">{{ <span class="seckill-price text-danger">{{
item.price | unitPrice("¥") item.content.price | unitPrice("¥")
}}</span> }}</span>
</span> </span>
</div> </div>
<div class="goods-show-detail"> <div class="goods-show-detail">
<span>{{ item.goodsName }}</span> <span>{{ item.content.goodsName }}</span>
</div> </div>
<div class="goods-show-num"> <div class="goods-show-num">
已有<span>{{ item.commentNum || 0 }}</span>人评价 已有<span>{{ item.content.commentNum || 0 }}</span>人评价
</div> </div>
</div> </div>
</div> </div>
@ -237,6 +237,6 @@ export default {
} }
} }
.promotion-decorate::before,.promotion-decorate::after{ .promotion-decorate::before,.promotion-decorate::after{
background-image: url('../../static/sprite@2x.png'); background-image: url('/src/assets/images/sprite@2x.png');
} }
</style> </style>

View File

@ -342,7 +342,7 @@ export default {
font-weight: bold; font-weight: bold;
} }
.subTips { .subTips {
@include sub_color($light_sub_color);
} }
.fontsize_48 { .fontsize_48 {
font-size: 48px; font-size: 48px;

View File

@ -110,7 +110,7 @@ export default {
} }
.address-content-title { .address-content-title {
@include sub_color($light_sub_color);
} }
.address-action span { .address-action span {

View File

@ -496,7 +496,7 @@ export default {
font-weight: bold; font-weight: bold;
} }
.subTips { .subTips {
@include sub_color($light_sub_color);
} }
.account-btns { .account-btns {
margin: 10px 0; margin: 10px 0;

View File

@ -21,7 +21,7 @@ export default {
}; };
</script> </script>
<style scoped> <style scoped lang='scss'>
.pay-done-box { .pay-done-box {
margin: 100px; margin: 100px;
display: flex; display: flex;
@ -31,5 +31,8 @@ export default {
.pay-btn{ .pay-btn{
width: 300px; width: 300px;
margin: 0 auto; margin: 0 auto;
>*{
margin:0 4px;
}
} }
</style> </style>

View File

@ -285,6 +285,9 @@ export default {
.add-buy-car { .add-buy-car {
margin-top: 15px; margin-top: 15px;
>*{
margin: 0 4px;
}
} }
.item-select { .item-select {
display: flex; display: flex;

View File

@ -150,7 +150,7 @@ export default {
justify-content: flex-end; justify-content: flex-end;
} }
.promotion-decorate::before,.promotion-decorate::after{ .promotion-decorate::before,.promotion-decorate::after{
background-image: url('../../../static/sprite@2x.png'); background-image: url('/src/assets/images/sprite@2x.png');
} }
.cate-select-con{ .cate-select-con{
display: block; display: block;

View File

@ -164,7 +164,7 @@ export default {
background-color: #666; background-color: #666;
} }
.promotion-decorate::before,.promotion-decorate::after{ .promotion-decorate::before,.promotion-decorate::after{
background-image: url('../../../static/sprite@2x.png'); background-image: url('/src/assets/images/sprite@2x.png');
} }
.time-line{ .time-line{
width: 1200px; width: 1200px;

View File

@ -2,7 +2,7 @@
<div class="shop-entry"> <div class="shop-entry">
<div style="height: 20px"></div> <div style="height: 20px"></div>
<div class="content"> <div class="content">
<h3>店铺入驻</h3> <h1>店铺入驻</h1>
<Steps :current="currentIndex" class="margin"> <Steps :current="currentIndex" class="margin">
<Step title="企业资质信息"></Step> <Step title="企业资质信息"></Step>
<Step title="财务资质信息"></Step> <Step title="财务资质信息"></Step>
@ -22,7 +22,8 @@
<span v-if="storeDisable == 'REFUSED'">,</span> <span v-if="storeDisable == 'REFUSED'">,</span>
</div> </div>
<Button v-if="currentIndex === 3" @click="$router.push('/')"></Button> <Button v-if="currentIndex === 3" @click="$router.push('/')"></Button>
<Button type="primary" @click='currentIndex = 0' v-if="storeDisable === 'REFUSED' && currentIndex === 3"></Button> <Button type="primary" @click='currentIndex = 0'
v-if="storeDisable === 'REFUSED' && currentIndex === 3">重新申请</Button>
</div> </div>
<Modal title="店铺入驻协议" v-model="showAgreement" width="1200" :closable="false" :mask-closable="false"> <Modal title="店铺入驻协议" v-model="showAgreement" width="1200" :closable="false" :mask-closable="false">
@ -38,37 +39,38 @@
</div> </div>
</template> </template>
<script> <script>
import { agreement, applyStatus } from '@/api/shopentry'; import { agreement, applyStatus } from "@/api/shopentry";
import firstApply from './FirstApply'; import firstApply from "./FirstApply";
import secondApply from './SecondApply'; import secondApply from "./SecondApply";
import thirdApply from './ThirdApply'; import thirdApply from "./ThirdApply";
export default { export default {
components: { components: {
firstApply, firstApply,
secondApply, secondApply,
thirdApply thirdApply,
}, },
data () { data() {
return { return {
currentIndex: 0, // currentIndex: 0, //
showAgreement: false, // showAgreement: false, //
agreementCon: '', // agreementCon: "", //
checked: false, // checked: false, //
firstData: {}, // firstData: {}, //
secondData: {}, // secondData: {}, //
thirdData: {}, // thirdData: {}, //
storeDisable: '', // APPLY OPEN CLOSED REFUSED APPLYING storeDisable: "", // APPLY OPEN CLOSED REFUSED APPLYING
dataReview: true // dataReview: true, //
}; };
}, },
methods: { methods: {
getArticle () { getArticle() {
// //
agreement().then((res) => { agreement().then((res) => {
this.agreementCon = res.result.content; this.agreementCon = res.result.content;
}); });
}, },
getData (status) { // getData(status) {
//
applyStatus().then((res) => { applyStatus().then((res) => {
if (res.success) { if (res.success) {
if (!res.result) { if (!res.result) {
@ -77,38 +79,38 @@ export default {
this.dataReview = false; this.dataReview = false;
let data = res.result; let data = res.result;
let first = [ let first = [
'companyAddressPath', "companyAddressPath",
'companyAddress', "companyAddress",
'companyAddressIdPath', "companyAddressIdPath",
'companyEmail', "companyEmail",
'companyName', "companyName",
'employeeNum', "employeeNum",
'companyPhone', "companyPhone",
'legalId', "legalId",
'legalName', "legalName",
'licencePhoto', "licencePhoto",
'legalPhoto', "legalPhoto",
'licenseNum', "licenseNum",
'linkName', "linkName",
'linkPhone', "linkPhone",
'registeredCapital', "registeredCapital",
'scope' "scope",
]; ];
let second = [ let second = [
'settlementBankAccountName', "settlementBankAccountName",
'settlementBankAccountNum', "settlementBankAccountNum",
'settlementBankBranchName', "settlementBankBranchName",
'settlementBankJointName' "settlementBankJointName",
]; ];
let third = [ let third = [
'goodsManagementCategory', "goodsManagementCategory",
'storeCenter', "storeCenter",
'storeDesc', "storeDesc",
'storeLogo', "storeLogo",
'storeName', "storeName",
'storeAddressIdPath', "storeAddressIdPath",
'storeAddressPath', "storeAddressPath",
'storeAddressDetail' "storeAddressDetail",
]; ];
this.storeDisable = data.storeDisable; this.storeDisable = data.storeDisable;
@ -122,8 +124,8 @@ export default {
third.forEach((e) => { third.forEach((e) => {
this.thirdData[e] = data[e]; this.thirdData[e] = data[e];
}); });
if (status === 'init') { if (status === "init") {
if (this.storeDisable === 'APPLY') { if (this.storeDisable === "APPLY") {
this.currentIndex = 0; this.currentIndex = 0;
} else { } else {
this.currentIndex = 3; this.currentIndex = 3;
@ -132,37 +134,36 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.dataReview = true; this.dataReview = true;
this.$forceUpdate(); this.$forceUpdate();
}) });
} }
} }
}); });
}, },
// //
nextPage (step) { nextPage(step) {
this.currentIndex = step; this.currentIndex = step;
this.getData('next') this.getData("next");
}
}, },
mounted () { },
this.getData('init'); mounted() {
this.getData("init");
this.getArticle(); this.getArticle();
} },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.content { .content {
width: 1200px; width: 1200px;
margin: 0 auto; margin: 0 auto;
border: 1px solid #eee; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
min-height: 500px; min-height: 500px;
border-radius: 5px; border-radius: 20px;
box-shadow: 3px 3px 10px #999;
background: #fff; background: #fff;
padding: 10px 20px; padding: 10px 20px;
h3 { h1 {
text-align: center;
margin-bottom: 10px; margin-top: 20px;
} }
} }
@ -179,4 +180,8 @@ export default {
text-align: center; text-align: center;
font-size: 20px; font-size: 20px;
} }
.shop-entry {
min-height: 100vh;
padding: 32px 0;
}
</style> </style>

View File

@ -1,13 +1,10 @@
/** import Cookies from "js-cookie";
* Created by Andste on 2018/5/3. const psl = require("psl");
*/
import Cookies from 'js-cookie';
const psl = require('psl');
export default { export default {
setItem: (key, value, options = {}) => { setItem: (key, value, options = {}) => {
if (process.client) { if (process.client) {
console.log(process.client);
const pPsl = psl.parse(document.domain); const pPsl = psl.parse(document.domain);
let domain = pPsl.domain; let domain = pPsl.domain;
if (/\d+\.\d+\.\d+\.\d+/.test(pPsl.input)) domain = pPsl.input; if (/\d+\.\d+\.\d+\.\d+/.test(pPsl.input)) domain = pPsl.input;
@ -15,7 +12,7 @@ export default {
} }
Cookies.set(key, value, options); Cookies.set(key, value, options);
}, },
getItem: (key) => { getItem: key => {
return Cookies.get(key); return Cookies.get(key);
}, },
removeItem: (key, options = {}) => { removeItem: (key, options = {}) => {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,5 +1,134 @@
const path = require("path");
const CompressionPlugin = require("compression-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const resolve = dir => {
return path.join(__dirname, dir);
};
/**
* 在项目开发的时候将生产环境以及开发环境进行判断
* 将生产环境中的路径用cdn来进行优化处理
* 将开发环境中替换为本地的内容方便处理bug以及开启vueDev
* 我们可以根据环境变量进行相应的处理只有在产品的时候才让插件去自动注入相应的资源文件到html页面
*/
const enableProduction = process.env.NODE_ENV === "production"; // 是否生产环境
let externals = {
vue: "Vue",
axios: "axios",
"vue-router": "VueRouter",
vuex: "Vuex",
"view-design": "iview",
"js-cookie": "Cookies"
};
// 使用CDN的内容
let cdn = {
css: ["https://cdn.jsdelivr.net/npm/view-design@4.1.1/dist/styles/iview.css"],
js: [
// vue must at first!
"https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js",
"https://cdn.jsdelivr.net/npm/vuex@3.1.2/dist/vuex.min.js",
"https://cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js",
"https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js",
"https://cdn.jsdelivr.net/npm/view-design@4.1.1/dist/iview.min.js",
"https://cdn.jsdelivr.net/npm/js-cookie@2.2.1/src/js.cookie.min.js"
]
};
// 删除注释
let jsPlugin = [
new UglifyJsPlugin({
uglifyOptions: {
// 删除注释
output: {
comments: false
},
compress: {
drop_console: true, // 删除所有调式带有console的
drop_debugger: true,
pure_funcs: ["console.log"] // 删除console.log
}
}
})
];
// 判断是否需要加载CDN
cdn = enableProduction ? cdn : { css: [], js: [] };
externals = enableProduction ? externals : {};
jsPlugin = enableProduction ? jsPlugin : [];
// 关闭eslint
module.exports = { module.exports = {
// 输出文件目录,当运行 vue-cli-service build 时生成的生产环境构建文件的目录。注意目标目录在构建之前会被清除
outputDir: "dist",
// 放置生成的静态资源 (js、css、img、fonts) 的目录。
assetsDir: "static",
} css: {
// 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能。
sourceMap: false,
loaderOptions: {
sass: {
data: `@import "@/assets/styles/global.scss";` //全局加载scss
},
// 向 CSS 相关的 loader 传递选项
less: {
lessOptions: {
javascriptEnabled: true
}
}
}
},
devServer: {
port: 10000
},
// 打包时不生成.map文件 避免看到源码
productionSourceMap: false,
// 部署优化
configureWebpack: {
performance: {
maxEntrypointSize: 10000000,
maxAssetSize: 30000000
},
externals,
// GZIP压缩
plugins: [
new CompressionPlugin({
test: /\.js$|\.html$|\.css/, // 匹配文件
threshold: 10240 // 对超过10k文件压缩
})
],
optimization: {
minimizer: jsPlugin,
runtimeChunk: "single",
splitChunks: {
chunks: "all",
maxInitialRequests: Infinity,
minSize: 20000,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1];
return `npm.${packageName.replace("@", "")}`;
}
}
}
}
}
},
// 将cdn的资源挂载到插件上
chainWebpack(config) {
// @ 对应 src目录
config.resolve.alias.set("@", resolve("src"));
config.plugin("html").tap(args => {
args[0].cdn = cdn;
return args;
});
}
};