├── .babelrc ├── .editorconfig ├── .gitignore ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── db.json ├── index.html ├── package.json ├── screenshots ├── about.png ├── analysis.png ├── bankChooser.png ├── checkOrder.png ├── index.png ├── login.png └── orderList.png ├── src ├── App.vue ├── assets │ ├── banks │ │ └── banks.png │ ├── images │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ └── 4.png │ ├── logo.png │ └── slideShow │ │ ├── pic1.jpg │ │ ├── pic2.jpg │ │ ├── pic3.jpg │ │ └── pic4.jpg ├── components │ ├── HelloWorld.vue │ ├── bankChooser.vue │ ├── base │ │ ├── chooser.vue │ │ ├── counter.vue │ │ ├── datepicker.vue │ │ ├── dialog.vue │ │ ├── multiplyChooser.vue │ │ └── selection.vue │ ├── checkOrder.vue │ ├── layout.vue │ ├── logForm.vue │ ├── regForm.vue │ └── slideShow.vue ├── main.js └── pages │ ├── detail.vue │ ├── detail │ ├── analysis.vue │ ├── count.vue │ ├── forecast.vue │ └── publish.vue │ ├── index.vue │ └── orderList.vue └── static └── .gitkeep /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-import": {}, 6 | "postcss-url": {}, 7 | // to edit target browsers: use "browserslist" field in package.json 8 | "autoprefixer": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于Vue2.0 + vue-router + webpack + ES6/7 + nodejs + express 实现web端购物商城网站 2 | 3 | 4 | ## 前端构架 5 | *** 6 | - 页面结构(H5,CSS3,原生JS) 7 | - 框架(基于Vue脚手架:vue-cli)进行搭建 8 | - 数据请求处理框架(vue-resource或者Axios) 9 | - Vue-Router进行路由处理 10 | - 使用json-server模拟REST API(目前项目使用express) 11 | 12 | ## 目前项目已实现功能 13 | *** 14 | 1. 登录 15 | 2. 注册 (没有实现,点击按钮跳转回登录页面) 16 | 3. 首页数据的展示 17 | 4. 产品数据与最新消息的展示 18 | 5. 商品详情页 19 | 6. 购物车 20 | 7. 购物确认银行支付选择 21 | 8. 购买订单 (排序 ( 高->低 ) ) 22 | 23 | ## 项目运行 24 | *** 25 | 通过npm安装本地服务第三方依赖模块(需要已安装[Node.js](https://nodejs.org/ "nodejs")) 26 | #### 注意:由于涉及大量的 ES6/7 等新属性,node 需要 6.0 以上版本 27 | ``` 28 | cd vue-shop 29 | 30 | npm install 或 cnpm install(个人比较喜欢使用后者,下载依赖模块速度较快) 31 | 32 | npm run dev 33 | 34 | ``` 35 | 36 | ## 总结 37 | - 了解vue - 数据渲染、前端模块化、路由 38 | - 熟悉VueJs的接口功能 - 指令的用法、选项的用法 39 | - 了解vue组件 - 组件的交互 40 | - 了解vue工程化方案 - 单文件组件Webpack测试数据 41 | - vue项目的搭建流程 42 | - 使用Ajax请求后端数据 43 | - 组件的设计与交互 44 | - 路由和子路由(嵌套路由通信) 45 | 46 | ## 目录结构 47 | 48 | ``` 49 | . 50 | ├── build 51 | ├── config 52 | ├── screenshots 53 | ├── src 54 | │ ├── assets 55 | │ │ ├── banks 56 | │ │ ├── images 57 | │ │ └── slideShow 58 | │ ├── components 59 | │ │ ├── base 60 | │ │ │ ├── chooser.vue 61 | │ │ │ ├── counter.vue 62 | │ │ │ ├── datepicker.vue 63 | │ │ │ ├── dialog.vue 64 | │ │ │ ├── multiplyChooser.vue 65 | │ │ │ └── selection.vue 66 | │ │ ├── bankChooser.vue 67 | │ │ ├── checkOrder.vue 68 | │ │ ├── HelloWorld.vue 69 | │ │ ├── layout.vue 70 | │ │ ├── logForm.vue 71 | │ │ ├── regForm.vue 72 | │ │ └── slideShow.vue 73 | │ ├── pages 74 | │ │ ├── detail 75 | │ │ │ ├── analysis.vue 76 | │ │ │ ├── count.vue 77 | │ │ │ ├── forecast.vue 78 | │ │ │ └── publish.vue 79 | │ │ ├── detail.vue 80 | │ │ ├── index.vue 81 | │ │ └── orderList.vue 82 | │ ├── App.vue 83 | │ └── main.js 84 | ├── static 85 | │ └── .gitkeep 86 | ├── .babelrc 87 | ├── .editorconfig 88 | ├── .gitgnore 89 | ├── .postcssrc.js 90 | ├── db.json 91 | ├── index.html 92 | ├── package.json 93 | └── README.md 94 | . 95 | ``` 96 | 97 | ## 项目效果图 98 |  99 |  100 |  101 |  102 |  103 |  104 |  105 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuChenDi/vue-shop/6204dc526e0d4aa94056162c3c50c5edb4e60397/build/logo.png -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | 12 | return path.posix.join(assetsSubDirectory, _path) 13 | } 14 | 15 | exports.cssLoaders = function (options) { 16 | options = options || {} 17 | 18 | const cssLoader = { 19 | loader: 'css-loader', 20 | options: { 21 | sourceMap: options.sourceMap 22 | } 23 | } 24 | 25 | const postcssLoader = { 26 | loader: 'postcss-loader', 27 | options: { 28 | sourceMap: options.sourceMap 29 | } 30 | } 31 | 32 | // generate loader string to be used with extract text plugin 33 | function generateLoaders (loader, loaderOptions) { 34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 35 | 36 | if (loader) { 37 | loaders.push({ 38 | loader: loader + '-loader', 39 | options: Object.assign({}, loaderOptions, { 40 | sourceMap: options.sourceMap 41 | }) 42 | }) 43 | } 44 | 45 | // Extract CSS when that option is specified 46 | // (which is the case during production build) 47 | if (options.extract) { 48 | return ExtractTextPlugin.extract({ 49 | use: loaders, 50 | fallback: 'vue-style-loader' 51 | }) 52 | } else { 53 | return ['vue-style-loader'].concat(loaders) 54 | } 55 | } 56 | 57 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 58 | return { 59 | css: generateLoaders(), 60 | postcss: generateLoaders(), 61 | less: generateLoaders('less'), 62 | sass: generateLoaders('sass', { indentedSyntax: true }), 63 | scss: generateLoaders('sass'), 64 | stylus: generateLoaders('stylus'), 65 | styl: generateLoaders('stylus') 66 | } 67 | } 68 | 69 | // Generate loaders for standalone style files (outside of .vue) 70 | exports.styleLoaders = function (options) { 71 | const output = [] 72 | const loaders = exports.cssLoaders(options) 73 | 74 | for (const extension in loaders) { 75 | const loader = loaders[extension] 76 | output.push({ 77 | test: new RegExp('\\.' + extension + '$'), 78 | use: loader 79 | }) 80 | } 81 | 82 | return output 83 | } 84 | 85 | exports.createNotifierCallback = () => { 86 | const notifier = require('node-notifier') 87 | 88 | return (severity, errors) => { 89 | if (severity !== 'error') return 90 | 91 | const error = errors[0] 92 | const filename = error.file && error.file.split('!').pop() 93 | 94 | notifier.notify({ 95 | title: packageConfig.name, 96 | message: severity + ': ' + error.name, 97 | subtitle: filename || '', 98 | icon: path.join(__dirname, 'logo.png') 99 | }) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | 12 | 13 | module.exports = { 14 | context: path.resolve(__dirname, '../'), 15 | entry: { 16 | app: './src/main.js' 17 | }, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: '[name].js', 21 | publicPath: process.env.NODE_ENV === 'production' 22 | ? config.build.assetsPublicPath 23 | : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | } 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.vue$/, 36 | loader: 'vue-loader', 37 | options: vueLoaderConfig 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 43 | }, 44 | { 45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 46 | loader: 'url-loader', 47 | options: { 48 | limit: 10000, 49 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 50 | } 51 | }, 52 | { 53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 54 | loader: 'url-loader', 55 | options: { 56 | limit: 10000, 57 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 58 | } 59 | }, 60 | { 61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 62 | loader: 'url-loader', 63 | options: { 64 | limit: 10000, 65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 66 | } 67 | } 68 | ] 69 | }, 70 | node: { 71 | // prevent webpack from injecting useless setImmediate polyfill because Vue 72 | // source contains it (although only uses it if it's native). 73 | setImmediate: false, 74 | // prevent webpack from injecting mocks to Node native modules 75 | // that does not make sense for the client 76 | dgram: 'empty', 77 | fs: 'empty', 78 | net: 'empty', 79 | tls: 'empty', 80 | child_process: 'empty' 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const express = require('express') 5 | const config = require('../config') // config.dev.port 6 | const merge = require('webpack-merge') 7 | const path = require('path') 8 | const baseWebpackConfig = require('./webpack.base.conf') 9 | const CopyWebpackPlugin = require('copy-webpack-plugin') 10 | const HtmlWebpackPlugin = require('html-webpack-plugin') 11 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 12 | const portfinder = require('portfinder') 13 | 14 | const HOST = process.env.HOST 15 | const PORT = process.env.PORT && Number(process.env.PORT) 16 | 17 | // const port = require(../config/index.js) 18 | // const jsonServer = require('json-server') 19 | // var jsonServer = new jsonServer() 20 | // 21 | // var jsonServer = require('json-server') 22 | // var apiServer = jsonServer.create() 23 | // var apiRouter = jsonServer.router('db.json') 24 | // var middlewares = jsonServer.defaults() 25 | // 26 | // apiServer.use(middlewares) 27 | // apiServer.use(apiRouter) 28 | // apiServer.listen(port + 1, function () { 29 | // console.log('JSON Server is runing') 30 | // }) 31 | 32 | // jsonServer 33 | // const jsonServer = require('json-server') 34 | // const apiServer = jsonServer.create() 35 | // const apiRouter = jsonServer.router('db.json') 36 | // const middlewares = jsonServer.defaults() 37 | // 38 | // // Set default middlewares (logger, static, cors and no-cache) 39 | // apiServer.use(middlewares) 40 | // apiServer.use('/api', apiRouter) 41 | // apiServer.use(apiRouter) 42 | // 43 | // apiServer.listen(config.dev.port + 1, () => { 44 | // console.log('JSON apiServer is running') 45 | // }) 46 | // jsonServer 47 | 48 | // express 49 | var apiServer = express() 50 | var bodyParser = require('body-parser') 51 | apiServer.use(bodyParser.urlencoded({ extended: true })) 52 | apiServer.use(bodyParser.json()) 53 | var apiRouter = express.Router() 54 | var fs = require('fs') 55 | apiRouter.route('/:apiName') 56 | .all(function (req, res) { 57 | fs.readFile('./db.json', 'utf8', function (err, data) { 58 | if (err) throw err 59 | var data = JSON.parse(data) 60 | if (data[req.params.apiName]) { 61 | res.json(data[req.params.apiName]) 62 | } else { 63 | res.send('no such api name') 64 | } 65 | }) 66 | }) 67 | 68 | apiServer.use('/api', apiRouter); 69 | apiServer.listen(config.dev.port + 1, function (err) { 70 | if (err) { 71 | console.log(err) 72 | return 73 | } 74 | console.log('Listening at http://localhost:' + (config.dev.port + 1) + '\n') 75 | }) 76 | // express 77 | 78 | const devWebpackConfig = merge(baseWebpackConfig, { 79 | module: { 80 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 81 | }, 82 | // cheap-module-eval-source-map is faster for development 83 | devtool: config.dev.devtool, 84 | 85 | // these devServer options should be customized in /config/index.js 86 | devServer: { 87 | clientLogLevel: 'warning', 88 | historyApiFallback: { 89 | rewrites: [ 90 | { from: /.*/, to: path.join(config.dev.assetsPublicPath, 'index.html') }, 91 | ], 92 | }, 93 | hot: true, 94 | contentBase: false, // since we use CopyWebpackPlugin. 95 | compress: true, 96 | host: HOST || config.dev.host, 97 | port: PORT || config.dev.port, 98 | open: config.dev.autoOpenBrowser, 99 | overlay: config.dev.errorOverlay 100 | ? { warnings: false, errors: true } 101 | : false, 102 | publicPath: config.dev.assetsPublicPath, 103 | proxy: config.dev.proxyTable, 104 | quiet: true, // necessary for FriendlyErrorsPlugin 105 | watchOptions: { 106 | poll: config.dev.poll, 107 | } 108 | }, 109 | plugins: [ 110 | new webpack.DefinePlugin({ 111 | 'process.env': require('../config/dev.env') 112 | }), 113 | new webpack.HotModuleReplacementPlugin(), 114 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 115 | new webpack.NoEmitOnErrorsPlugin(), 116 | // https://github.com/ampedandwired/html-webpack-plugin 117 | new HtmlWebpackPlugin({ 118 | filename: 'index.html', 119 | template: 'index.html', 120 | inject: true 121 | }), 122 | // copy custom static assets 123 | new CopyWebpackPlugin([ 124 | { 125 | from: path.resolve(__dirname, '../static'), 126 | to: config.dev.assetsSubDirectory, 127 | ignore: ['.*'] 128 | } 129 | ]) 130 | ] 131 | }) 132 | 133 | module.exports = new Promise((resolve, reject) => { 134 | portfinder.basePort = process.env.PORT || config.dev.port 135 | portfinder.getPort((err, port) => { 136 | if (err) { 137 | reject(err) 138 | } else { 139 | // publish the new Port, necessary for e2e tests 140 | process.env.PORT = port 141 | // add port to devServer config 142 | devWebpackConfig.devServer.port = port 143 | 144 | // Add FriendlyErrorsPlugin 145 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 146 | compilationSuccessInfo: { 147 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 148 | }, 149 | onErrors: config.dev.notifyOnErrors 150 | ? utils.createNotifierCallback() 151 | : undefined 152 | })) 153 | 154 | resolve(devWebpackConfig) 155 | } 156 | }) 157 | }) 158 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = require('../config/prod.env') 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | 'process.env': env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath('css/[name].[contenthash].css'), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true, 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | new OptimizeCSSPlugin({ 56 | cssProcessorOptions: config.build.productionSourceMap 57 | ? { safe: true, map: { inline: false } } 58 | : { safe: true } 59 | }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: 'index.html', 66 | inject: true, 67 | minify: { 68 | removeComments: true, 69 | collapseWhitespace: true, 70 | removeAttributeQuotes: true 71 | // more options: 72 | // https://github.com/kangax/html-minifier#options-quick-reference 73 | }, 74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 75 | chunksSortMode: 'dependency' 76 | }), 77 | // keep module.id stable when vendor modules does not change 78 | new webpack.HashedModuleIdsPlugin(), 79 | // enable scope hoisting 80 | new webpack.optimize.ModuleConcatenationPlugin(), 81 | // split vendor js into its own file 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'vendor', 84 | minChunks (module) { 85 | // any required modules inside node_modules are extracted to vendor 86 | return ( 87 | module.resource && 88 | /\.js$/.test(module.resource) && 89 | module.resource.indexOf( 90 | path.join(__dirname, '../node_modules') 91 | ) === 0 92 | ) 93 | } 94 | }), 95 | // extract webpack runtime and module manifest to its own file in order to 96 | // prevent vendor hash from being updated whenever app bundle is updated 97 | new webpack.optimize.CommonsChunkPlugin({ 98 | name: 'manifest', 99 | minChunks: Infinity 100 | }), 101 | // This instance extracts shared chunks from code splitted chunks and bundles them 102 | // in a separate chunk, similar to the vendor chunk 103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 104 | new webpack.optimize.CommonsChunkPlugin({ 105 | name: 'app', 106 | async: 'vendor-async', 107 | children: true, 108 | minChunks: 3 109 | }), 110 | 111 | // copy custom static assets 112 | new CopyWebpackPlugin([ 113 | { 114 | from: path.resolve(__dirname, '../static'), 115 | to: config.build.assetsSubDirectory, 116 | ignore: ['.*'] 117 | } 118 | ]) 119 | ] 120 | }) 121 | 122 | if (config.build.productionGzip) { 123 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 124 | 125 | webpackConfig.plugins.push( 126 | new CompressionWebpackPlugin({ 127 | asset: '[path].gz[query]', 128 | algorithm: 'gzip', 129 | test: new RegExp( 130 | '\\.(' + 131 | config.build.productionGzipExtensions.join('|') + 132 | ')$' 133 | ), 134 | threshold: 10240, 135 | minRatio: 0.8 136 | }) 137 | ) 138 | } 139 | 140 | if (config.build.bundleAnalyzerReport) { 141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.8 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | // proxyTable: {}, 14 | proxyTable: { 15 | '/api/': 'http://localhost:8081/' 16 | }, 17 | 18 | // Various Dev Server settings 19 | host: 'localhost', // can be overwritten by process.env.HOST 20 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 21 | autoOpenBrowser: false, 22 | errorOverlay: true, 23 | notifyOnErrors: true, 24 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 25 | 26 | 27 | /** 28 | * Source Maps 29 | */ 30 | 31 | // https://webpack.js.org/configuration/devtool/#development 32 | devtool: 'cheap-module-eval-source-map', 33 | 34 | // If you have problems debugging vue-files in devtools, 35 | // set this to false - it *may* help 36 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 37 | cacheBusting: true, 38 | 39 | cssSourceMap: true, 40 | }, 41 | 42 | build: { 43 | // Template for index.html 44 | index: path.resolve(__dirname, '../dist/index.html'), 45 | 46 | // Paths 47 | assetsRoot: path.resolve(__dirname, '../dist'), 48 | assetsSubDirectory: 'static', 49 | assetsPublicPath: '/', 50 | 51 | /** 52 | * Source Maps 53 | */ 54 | 55 | productionSourceMap: true, 56 | // https://webpack.js.org/configuration/devtool/#production 57 | devtool: '#source-map', 58 | 59 | // Gzip off by default as many popular static hosts such as 60 | // Surge or Netlify already gzip all static assets for you. 61 | // Before setting to `true`, make sure to: 62 | // npm install --save-dev compression-webpack-plugin 63 | productionGzip: false, 64 | productionGzipExtensions: ['js', 'css'], 65 | 66 | // Run the build command with an extra argument to 67 | // View the bundle analyzer report after build finishes: 68 | // `npm run build --report` 69 | // Set to `true` or `false` to always turn it on or off 70 | bundleAnalyzerReport: process.env.npm_config_report 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /db.json: -------------------------------------------------------------------------------- 1 | { 2 | "getNewsList": [ 3 | { 4 | "id": 1, 5 | "title": "新闻条目1新闻条目1新闻条目1新闻条目1", 6 | "url": "https://github.com/WuChenDi" 7 | }, 8 | { 9 | "id": 2, 10 | "title": "新闻条目2新闻条目2新闻条目2新闻条目2", 11 | "url": "https://github.com/WuChenDi" 12 | }, 13 | { 14 | "id": 3, 15 | "title": "新闻条3新闻条3新闻条3", 16 | "url": "https://github.com/WuChenDi" 17 | }, 18 | { 19 | "id": 4, 20 | "title": "新闻条4广告发布", 21 | "url": "https://github.com/WuChenDi" 22 | } 23 | ], 24 | "login": { 25 | "username": "wuchendi", 26 | "userId": 123456 27 | }, 28 | "getPrice": { 29 | "amount": 678 30 | }, 31 | "createOrder": { 32 | "orderId": "6djk979" 33 | }, 34 | "getOrderList": { 35 | "list": [ 36 | { 37 | "orderId": "ddj123", 38 | "product": "数据统计", 39 | "version": "高级版", 40 | "period": "1年", 41 | "buyNum": 2, 42 | "date": "2016-10-10", 43 | "amount": "500元" 44 | }, 45 | { 46 | "orderId": "yuj583", 47 | "product": "流量分析", 48 | "version": "户外版", 49 | "period": "3个月", 50 | "buyNum": 1, 51 | "date": "2016-5-2", 52 | "amount": "2200元" 53 | }, 54 | { 55 | "orderId": "pmd201", 56 | "product": "广告发布", 57 | "version": "商铺版", 58 | "period": "3年", 59 | "buyNum": 12, 60 | "date": "2016-8-3", 61 | "amount": "7890元" 62 | } 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |124 | < 125 | {{now.getFullYear()}} 126 | > 127 | | 128 |129 | < 130 | {{months[now.getMonth()]}} 131 | > 132 | | 133 ||||||
---|---|---|---|---|---|---|
{{day}} | 136 |||||||
{{date[i * 7 + j] && date[i * 7 + j].text}} 144 | | 145 |
x
8 |© 2018 WuChenDi
29 |本报告在调研数据的基础上,采用定性与定量相结合的方式深入分析了专车市场发展的驱动因素与阻碍因素、专车市场背后的产业格局、专车企业的竞争格局、用户对专车市场的依赖程度、专车对其他交通工具运力的补充效应等,通过这五个章节的研究反映专车市场的发展态势和面临的问题。报告力求客观、深入、准确地反映中国专车市场发展情况,为政府、企事业单位和社会各界提供决策依据。
32 |{{ errorText }}
26 |是指在获得网站访问量基本数据的情况下对有关数据进行统计、分析,从中发现用户访问网站的规律,并将这些规律与网络营销策略等相结合,从而发现目前网络营销活动中可能存在的问题,并为进一步修正或重新制定网络营销策略提供依据。当然这样的定义是站在网络营销管理的角度来考虑的
6 |网站访问统计分析报告的基础数据源于网站流量统计信息,但其价值远高于原始数据资料。专业的网站访问统计分析报告对网络营销的价值,正如专业的财务分析报告对企业经营策略的价值。
64 | 65 |购买数量 | 87 |产品类型 | 88 |有效时间 | 89 |产品版本 | 90 |总价 | 91 |
---|---|---|---|---|
{{ buyNum }} | 94 |{{ buyType.label }} | 95 |{{ period.label }} | 96 |97 | {{ item.label }} 98 | | 99 |{{ price }} | 100 |
历史资料、科学实验、检验、统计等所获得的和用于科学研究、技术设计、查证、决策等的数值加以统计为解决方案做前期准备。
6 |历史资料、科学实验、检验、统计等所获得的和用于科学研究、技术设计、查证、决策等的数值加以统计为解决方案做前期准备。
52 | 53 |
57 |
58 |
59 |
60 | |
61 |
62 |
63 |
64 |
65 | |
66 |
67 |
68 |
69 |
70 | |
71 |
72 |
73 |
74 |
75 | |
76 |
77 |
78 |
79 |
80 | |
81 |
82 |
83 |
84 |
85 | |
86 |
87 |
88 |
89 |
90 | |
91 |
94 |
95 |
96 |
97 | |
98 |
99 |
100 |
101 |
102 | |
103 |
104 |
105 |
106 |
107 | |
108 |
109 |
110 |
111 |
112 | |
113 |
114 |
115 |
116 |
117 | |
118 |
119 |
120 |
121 |
122 | |
123 |
124 |
125 |
126 |
127 | |
128 |
131 |
132 |
133 |
134 | |
135 |
136 |
137 |
138 |
139 | |
140 |
141 |
142 |
143 |
144 | |
145 |
146 |
147 |
148 |
149 | |
150 |
151 |
152 |
153 |
154 | |
155 |
156 |
157 |
158 |
159 | |
160 |
161 |
162 |
163 |
164 | |
165 |
168 |
169 |
170 |
171 | |
172 |
173 |
174 |
175 |
176 | |
177 |
178 |
179 |
180 |
181 | |
182 |
183 |
184 |
185 |
186 | |
187 |
188 |
189 |
190 |
191 | |
192 |
193 |
194 |
195 |
196 | |
197 |
198 |
199 |
200 |
201 | |
202 |
205 |
206 |
207 |
208 | |
209 |
210 |
211 |
212 |
213 | |
214 |
215 |
216 |
217 |
218 | |
219 |
220 |
221 |
222 |
223 | |
224 |
225 |
226 |
227 |
228 | |
229 |
230 |
231 |
232 |
233 | |
234 |
235 |
236 |
237 |
238 | |
239 |
未来,大数据会变得越来越重要,其核心应用预测也会成为互联网行业以及产业变革的重要力量,我们很有必要对数据预测及其分析方法进行全面且深入的了解。在这一点上,《大数据预测》是本很好的读物,适合大数据所有相关行业的人阅读。
6 |2020年的一天,在你驱车前往公司的路上,导航系统通过预测交通流量,会自动帮你选择一条最合适的交通路线;车内推荐系统会根据你的饮食习惯预测你可能会喜欢吃什么,并推荐沿途的早餐店;你的电子社交助理已经为你自动选择了你可能感兴趣的社交网信息;当车内系统预测到你驾车有些分心时,座椅会自动震动进行提醒…… 52 | 以上这些情景不是科幻大片独有的,它们有的已经或会在未来的某一天成为现实。而这一切所倚靠的就是预测分析技术。 53 | 大数据时代下,作为其核心,预测分析已在商业和社会中得到广泛应用。随着越来越多的数据被记录和整理,未来预测分析必定会成为所有领域的关键技术。 54 | 作为预测分析领域的专家,埃里克·西格尔博士深谙预测分析界已经实现和正在发生的事情、面临的问题和将来可能的前景。在《大数据预测》一书中,他结合预测分析的应用实例,对其进行了深入、细致且全面的解读。 55 | 关于预测分析,你想了解的全部,你的生活以及这个世界会因为预测分析改变到什么程度,《大数据预测》都会告诉你。
56 |广告活动按照广告计划执行,到完成广告创作并形成广告作品之后,经过广告主的最后审核同意,即可送到预定的媒介发布刊播。这项工作一般由媒介部门的有关专业人员负责,他们的任务就是专门负责与有关媒介单位接洽,安排有关广告的发播事宜,并对发播质量实施监督。
6 |广告活动按照广告计划执行,到完成广告创作并形成广告作品之后,经过广告主的最后审核同意,即可送到预定的媒介发布刊播。这项工作一般由媒介部门的有关专业人员负责,他们的任务就是专门负责与有关媒介单位接洽,安排有关广告的发播事宜,并对发播质量实施监督。
60 | 61 |
65 |
66 |
67 |
68 | |
69 |
70 |
71 |
72 |
73 | |
74 |
75 |
76 |
77 |
78 | |
79 |
80 |
81 |
82 |
83 | |
84 |
85 |
86 |
87 |
88 | |
89 |
90 |
91 |
92 |
93 | |
94 |
95 |
96 |
97 |
98 | |
99 |
102 |
103 |
104 |
105 | |
106 |
107 |
108 |
109 |
110 | |
111 |
112 |
113 |
114 |
115 | |
116 |
117 |
118 |
119 |
120 | |
121 |
122 |
123 |
124 |
125 | |
126 |
127 |
128 |
129 |
130 | |
131 |
132 |
133 |
134 |
135 | |
136 |
139 |
140 |
141 |
142 | |
143 |
144 |
145 |
146 |
147 | |
148 |
149 |
150 |
151 |
152 | |
153 |
154 |
155 |
156 |
157 | |
158 |
159 |
160 |
161 |
162 | |
163 |
164 |
165 |
166 |
167 | |
168 |
169 |
170 |
171 |
172 | |
173 |
176 |
177 |
178 |
179 | |
180 |
181 |
182 |
183 |
184 | |
185 |
186 |
187 |
188 |
189 | |
190 |
191 |
192 |
193 |
194 | |
195 |
196 |
197 |
198 |
199 | |
200 |
201 |
202 |
203 |
204 | |
205 |
206 |
207 |
208 |
209 | |
210 |
213 |
214 |
215 |
216 | |
217 |
218 |
219 |
220 |
221 | |
222 |
223 |
224 |
225 |
226 | |
227 |
228 |
229 |
230 |
231 | |
232 |
233 |
234 |
235 |
236 | |
237 |
238 |
239 |
240 |
241 | |
242 |
243 |
244 |
245 |
246 | |
247 |
{{ item.description }}
49 | 52 |29 | {{ head.label }} 30 | | 31 |
---|
34 | {{ item[head.key] }} 35 | | 36 |