├── .DS_Store
├── client
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build
│ ├── build.js
│ ├── check-versions.js
│ ├── dev-client.js
│ ├── dev-server.js
│ ├── utils.js
│ ├── vue-loader.conf.js
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ ├── webpack.prod.conf.js
│ └── webpack.test.conf.js
├── config
│ ├── api.config.js
│ ├── dev.env.js
│ ├── index.js
│ ├── prod.env.js
│ └── test.env.js
├── index.html
├── mock
│ └── goods.json
├── package.json
├── src
│ ├── App.vue
│ ├── api
│ │ └── index.js
│ ├── assets
│ │ ├── css
│ │ │ ├── app.css
│ │ │ ├── base.css
│ │ │ ├── checkout.css
│ │ │ ├── login.css
│ │ │ ├── product.css
│ │ │ └── style.css
│ │ ├── img
│ │ │ ├── 1.jpg
│ │ │ ├── 10.jpg
│ │ │ ├── 11.jpg
│ │ │ ├── 12.jpg
│ │ │ ├── 13.jpg
│ │ │ ├── 14.jpg
│ │ │ ├── 15.jpg
│ │ │ ├── 16.jpg
│ │ │ ├── 2.jpg
│ │ │ ├── 3.jpg
│ │ │ ├── 4.jpg
│ │ │ ├── 5.jpg
│ │ │ ├── 6.jpg
│ │ │ ├── 7.jpg
│ │ │ ├── 8.jpg
│ │ │ ├── 9.jpg
│ │ │ ├── bnt_subOrder.gif
│ │ │ ├── icon.png
│ │ │ ├── logo-footer.png
│ │ │ ├── logo.gif
│ │ │ ├── logo.png
│ │ │ ├── mi6.jpg
│ │ │ ├── note.jpg
│ │ │ ├── ok-2.png
│ │ │ ├── photo.jpg
│ │ │ ├── pingheng.jpg
│ │ │ ├── user_purchase20150409154845.gif
│ │ │ ├── v-face1.jpg
│ │ │ ├── v-face2.jpg
│ │ │ ├── v-face3.jpg
│ │ │ ├── v-face4.jpg
│ │ │ ├── vn-logo.png
│ │ │ ├── vn_logo.png
│ │ │ └── zipai.jpg
│ │ └── logo.png
│ ├── components
│ │ ├── Footer.vue
│ │ ├── Head.vue
│ │ ├── Hello.vue
│ │ ├── Modal.vue
│ │ └── NavBread.vue
│ ├── main.js
│ ├── router
│ │ └── index.js
│ └── view
│ │ ├── Address.vue
│ │ ├── Cart.vue
│ │ ├── GoodsList.vue
│ │ ├── OrderConfirm.vue
│ │ ├── OrderSuccess.vue
│ │ └── user
│ │ └── index.vue
├── static
│ ├── .gitkeep
│ ├── images
│ │ ├── 201507
│ │ │ ├── 27_thumb_G_1437074702008.jpg
│ │ │ ├── 28_thumb_G_1437074792369.jpg
│ │ │ ├── 29_thumb_G_1437074933275.jpg
│ │ │ ├── 30_thumb_G_1437075007558.jpg
│ │ │ ├── 31_thumb_G_1437075539254.jpg
│ │ │ ├── 32_thumb_G_1437075765802.jpg
│ │ │ ├── 33_thumb_G_1437075865379.jpg
│ │ │ ├── 34_thumb_G_1437076036973.jpg
│ │ │ ├── 35_thumb_G_1437081702649.jpg
│ │ │ ├── 36_thumb_G_1437082145888.jpg
│ │ │ ├── 37_thumb_G_1437082214575.jpg
│ │ │ ├── 38_thumb_G_1437082667838.jpg
│ │ │ ├── 39_thumb_G_1437082747983.jpg
│ │ │ ├── 40_thumb_G_1437082798686.jpg
│ │ │ ├── 41_thumb_G_1437082849514.jpg
│ │ │ ├── 42_thumb_G_1437082936092.jpg
│ │ │ ├── 43_thumb_G_1437091900155.jpg
│ │ │ ├── 44_thumb_G_1437092148601.jpg
│ │ │ ├── 45_thumb_G_1437092199733.jpg
│ │ │ └── 46_thumb_G_1437092278369.jpg
│ │ ├── 201508
│ │ │ ├── 47_thumb_G_1439331077002.jpg
│ │ │ ├── 53_thumb_G_1439511514539.jpg
│ │ │ ├── 56_thumb_G_1440717641715.jpg
│ │ │ ├── 57_thumb_G_1440717888680.jpg
│ │ │ ├── 59_thumb_G_1440983020324.jpg
│ │ │ ├── 60_thumb_G_1440983103483.jpg
│ │ │ ├── 64_thumb_G_1440983246324.jpg
│ │ │ ├── 65_thumb_G_1440983430401.jpg
│ │ │ ├── 66_thumb_G_1440983490045.jpg
│ │ │ ├── 67_thumb_G_1440983638116.jpg
│ │ │ ├── 68_thumb_G_1440983695997.jpg
│ │ │ ├── 69_thumb_G_1440983751530.jpg
│ │ │ ├── 70_thumb_G_1440983810214.jpg
│ │ │ ├── 71_thumb_G_1440983839269.jpg
│ │ │ ├── 72_thumb_G_1440983887661.jpg
│ │ │ ├── 73_thumb_G_1440983937959.jpg
│ │ │ ├── 74_thumb_G_1440983959230.jpg
│ │ │ ├── 75_thumb_G_1440984011595.jpg
│ │ │ ├── 76_thumb_G_1440984280864.jpg
│ │ │ └── 77_thumb_G_1440984390480.jpg
│ │ └── 201509
│ │ │ ├── 101_thumb_G_1441738730692.jpg
│ │ │ ├── 102_thumb_G_1441738765271.jpg
│ │ │ ├── 103_thumb_G_1441738795942.jpg
│ │ │ ├── 78_thumb_G_1441050387337.jpg
│ │ │ ├── 79_thumb_G_1441050485953.jpg
│ │ │ ├── 80_thumb_G_1441050558701.jpg
│ │ │ ├── 81_thumb_G_1441050609661.jpg
│ │ │ ├── 82_thumb_G_1441050801926.jpg
│ │ │ ├── 83_thumb_G_1441052403875.jpg
│ │ │ ├── 84_thumb_G_1441056023645.jpg
│ │ │ ├── 85_thumb_G_1441056112107.jpg
│ │ │ ├── 86_thumb_G_1441056239670.jpg
│ │ │ ├── 87_thumb_G_1441056303542.jpg
│ │ │ ├── 88_thumb_G_1441056484072.jpg
│ │ │ ├── 89_thumb_G_1441056597778.jpg
│ │ │ ├── 90_thumb_G_1441056659073.jpg
│ │ │ ├── 91_thumb_G_1441056702928.jpg
│ │ │ ├── 92_thumb_G_1441056728120.jpg
│ │ │ ├── 93_thumb_G_1441056767939.jpg
│ │ │ ├── 94_thumb_G_1441056891849.jpg
│ │ │ ├── 96_thumb_G_1441738537157.jpg
│ │ │ └── 98_thumb_G_1441738620606.jpg
│ └── img
│ │ ├── 1.jpg
│ │ ├── 10.jpg
│ │ ├── 11.jpg
│ │ ├── 12.jpg
│ │ ├── 13.jpg
│ │ ├── 14.jpg
│ │ ├── 15.jpg
│ │ ├── 16.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ ├── 7.jpg
│ │ ├── 8.jpg
│ │ ├── 9.jpg
│ │ ├── bnt_subOrder.gif
│ │ ├── icon.png
│ │ ├── logo-footer.png
│ │ ├── logo.gif
│ │ ├── logo.png
│ │ ├── mi6.jpg
│ │ ├── note.jpg
│ │ ├── ok-2.png
│ │ ├── photo.jpg
│ │ ├── pingheng.jpg
│ │ ├── user_purchase20150409154845.gif
│ │ ├── v-face1.jpg
│ │ ├── v-face2.jpg
│ │ ├── v-face3.jpg
│ │ ├── v-face4.jpg
│ │ ├── vn-logo.png
│ │ ├── vn_logo.1.png
│ │ ├── vn_logo.png
│ │ └── zipai.jpg
└── test
│ ├── e2e
│ ├── custom-assertions
│ │ └── elementCount.js
│ ├── nightwatch.conf.js
│ ├── runner.js
│ └── specs
│ │ └── test.js
│ └── unit
│ ├── .eslintrc
│ ├── index.js
│ ├── karma.conf.js
│ └── specs
│ └── Hello.spec.js
├── node_modules
├── debug
│ ├── .coveralls.yml
│ ├── .eslintrc
│ ├── .npmignore
│ ├── .travis.yml
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── Makefile
│ ├── README.md
│ ├── component.json
│ ├── karma.conf.js
│ ├── node.js
│ ├── package.json
│ └── src
│ │ ├── browser.js
│ │ ├── debug.js
│ │ ├── index.js
│ │ ├── inspector-log.js
│ │ └── node.js
├── jsonp
│ ├── .npmignore
│ ├── .travis.yml
│ ├── .zuul.yml
│ ├── History.md
│ ├── Readme.md
│ ├── bower.json
│ ├── component.json
│ ├── index.js
│ ├── package.json
│ └── test
│ │ └── basic.js
└── ms
│ ├── index.js
│ ├── license.md
│ ├── package.json
│ └── readme.md
├── note
├── 01.开发goodlist组件.md
├── 02.vue项目中的@符号的意思.md
├── 03.在项目中引入css样式的方法.md
├── 04.当后端接口还没写完的时候.此时怎么做才不影响开发进度.md
├── 05.部组件拆分使用.md
├── 06.模拟mock数据.md
├── 07.图片懒加载.md
├── 08.使用express-generator生成express项目.md
├── 09.express连接mongodb数据库.md
├── 10.mongoose.操作指南.md
├── 11.根据价格排序.md
├── 12.按照价格区间筛选商品.md
├── 13.在vue中实现下拉加载数据,瀑布流.md
├── 14.域名注册.md
├── 15.表驱动法.md
├── 16.加入购物车.md
├── 17.登录逻辑.md
├── 18.登录前后台实现.md
├── 19.在项目前后分离的状态下,刷新页面,怎么保持用户登录.md
├── 20.退出登录.md
├── 21.如何在vue里面优雅的解决跨域,路由冲突问题.md
├── 22.登录拦截.md
├── 23.开发购物车页面.md
├── 24.调试问题的框架.md
├── 25.购物车列表里面的商品数量增加和减少,和是否被选中.md
├── 26.全选,全不选.md
├── 27.总价格实时变化.md
├── 28.商品删除.md
├── 29.封装全局模态框组件.购物车判断登录与未登录情况的弹出不同模态框.md
├── 30.在购物车列表页面去结账.md
├── 31.地址页面.md
├── 32.设置默认地址.md
├── 33.订单确认页面.md
├── 34.项目上线.md
├── 35.服务器购买.md
├── 36.域名购买.md
├── 36.连接阿里云工具.md
├── 37.【全栈项目上线(vue+node+mongodb)】安装lnmp环境.md
├── 38.项目上线解决方案.md
├── 39.怎么在一台主机上面部署多个网站.md
├── 40.nodejs服务上线.md
├── 41.homework.md
├── 42.项目上线使用webhooks.md
├── day.log.md
├── homework.md
├── item.guide.md
├── 分析需求.md
├── 常用工具.md
├── 思想.md
├── 接口文档.md
├── 推荐工具.md
└── 项目需求.md
├── note01
├── 01.技术栈.md
├── 02.项目结构.md
├── 03.项目初始化.md
├── 04.组件.md
├── 05.懒加载图片.md
├── 06.利用本地的vue项目里面express.模拟数据.md
├── 07.使用express-generator生成项目.md
├── 08.前端与后端交互的介质.md
├── 09.跨域.md
├── 10.价格排序.md
├── 11.按照价格区间筛选商品.md
├── 12.商品分页,瀑布流,下拉加载.md
├── 13.解决node修改完重启问题.md
├── 14.加入购物车.md
├── 15.mongoose.md
├── 16.用户登陆.md
├── 19.在vue中怎么优雅的配置本地代理.md
├── 20.登陆拦截.md
├── 21.国庆作业.md
├── 23.全选.全不选.md
├── 24.登录流程.md
├── 25.删除购物车.md
├── 26.设计数据库.md
├── 27.支付生成订单号.md
├── 28.项目上线.md
├── mongodb 安装连接方式.pdf
├── vue+express+mongodb项目上线 (1).pdf
└── 学习效率.md
├── readme.md
└── server
├── .gitignore
├── app.js
├── bin
└── www
├── models
├── goods.js
└── user.js
├── package-lock.json
├── package.json
├── public
└── stylesheets
│ └── style.css
├── routes
├── goods.js
├── index.js
└── users.js
├── util
└── util.js
└── views
├── error.jade
├── index.jade
└── layout.jade
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/.DS_Store
--------------------------------------------------------------------------------
/client/.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-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"],
15 | "plugins": ["istanbul"]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/client/.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 |
--------------------------------------------------------------------------------
/client/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | config/*.js
3 |
--------------------------------------------------------------------------------
/client/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // http://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | 'rules': {
20 | // allow paren-less arrow functions
21 | 'arrow-parens': 0,
22 | // allow async-await
23 | 'generator-star-spacing': 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | test/unit/coverage
8 | test/e2e/reports
9 | selenium-debug.log
10 |
11 | # Editor directories and files
12 | .idea
13 | *.suo
14 | *.ntvs*
15 | *.njsproj
16 | *.sln
17 |
--------------------------------------------------------------------------------
/client/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "autoprefixer": {}
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | # vnshop
2 |
3 | > vue&&node shop
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # build for production with minification
15 | npm run build
16 |
17 | # build for production and view the bundle analyzer report
18 | npm run build --report
19 |
20 | # run unit tests
21 | npm run unit
22 |
23 | # run e2e tests
24 | npm run e2e
25 |
26 | # run all tests
27 | npm test
28 | ```
29 |
30 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
31 | 教程视频地址:
32 | 链接: https://pan.baidu.com/s/1qXB5BkS 密码: 6nru
--------------------------------------------------------------------------------
/client/build/build.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | process.env.NODE_ENV = 'production'
4 |
5 | var ora = require('ora')
6 | var rm = require('rimraf')
7 | var path = require('path')
8 | var chalk = require('chalk')
9 | var webpack = require('webpack')
10 | var config = require('../config')
11 | var webpackConfig = require('./webpack.prod.conf')
12 |
13 | var spinner = ora('building for production...')
14 | spinner.start()
15 |
16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
17 | if (err) throw err
18 | webpack(webpackConfig, function (err, stats) {
19 | spinner.stop()
20 | if (err) throw err
21 | process.stdout.write(stats.toString({
22 | colors: true,
23 | modules: false,
24 | children: false,
25 | chunks: false,
26 | chunkModules: false
27 | }) + '\n\n')
28 |
29 | if (stats.hasErrors()) {
30 | console.log(chalk.red(' Build failed with errors.\n'))
31 | process.exit(1)
32 | }
33 |
34 | console.log(chalk.cyan(' Build complete.\n'))
35 | console.log(chalk.yellow(
36 | ' Tip: built files are meant to be served over an HTTP server.\n' +
37 | ' Opening index.html over file:// won\'t work.\n'
38 | ))
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/client/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var chalk = require('chalk')
2 | var semver = require('semver')
3 | var packageConfig = require('../package.json')
4 | var shell = require('shelljs')
5 | function exec (cmd) {
6 | return require('child_process').execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | }
15 | ]
16 |
17 | if (shell.which('npm')) {
18 | versionRequirements.push({
19 | name: 'npm',
20 | currentVersion: exec('npm --version'),
21 | versionRequirement: packageConfig.engines.npm
22 | })
23 | }
24 |
25 | module.exports = function () {
26 | var warnings = []
27 | for (var i = 0; i < versionRequirements.length; i++) {
28 | var mod = versionRequirements[i]
29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
30 | warnings.push(mod.name + ': ' +
31 | chalk.red(mod.currentVersion) + ' should be ' +
32 | chalk.green(mod.versionRequirement)
33 | )
34 | }
35 | }
36 |
37 | if (warnings.length) {
38 | console.log('')
39 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
40 | console.log()
41 | for (var i = 0; i < warnings.length; i++) {
42 | var warning = warnings[i]
43 | console.log(' ' + warning)
44 | }
45 | console.log()
46 | process.exit(1)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/client/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/client/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | var config = require('../config')
4 | if (!process.env.NODE_ENV) {
5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
6 | }
7 |
8 | var opn = require('opn')
9 | var path = require('path')
10 | var express = require('express')
11 | var webpack = require('webpack')
12 | var proxyMiddleware = require('http-proxy-middleware')
13 | var webpackConfig = (process.env.NODE_ENV === 'testing' || process.env.NODE_ENV === 'production') ?
14 | require('./webpack.prod.conf') :
15 | require('./webpack.dev.conf')
16 |
17 | // default port where dev server listens for incoming traffic
18 | var port = process.env.PORT || config.dev.port
19 | // automatically open browser, if not set will be false
20 | var autoOpenBrowser = !!config.dev.autoOpenBrowser
21 | // Define HTTP proxies to your custom API backend
22 | // https://github.com/chimurai/http-proxy-middleware
23 | var proxyTable = config.dev.proxyTable
24 |
25 | var app = express()
26 | var compiler = webpack(webpackConfig)
27 | // var router = express.Router();
28 | // var goodsList = require('../mock/goods.json');
29 |
30 | // // 对外暴漏一个路由,然后当你访问的时候给你做点事情
31 | // router.get("/goods", function(req, res, next) {
32 | // // req 请求
33 | // // res 响应
34 | // res.json(goodsList);
35 | // })
36 |
37 | // app.use(router);
38 |
39 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
40 | publicPath: webpackConfig.output.publicPath,
41 | quiet: true
42 | })
43 |
44 | var hotMiddleware = require('webpack-hot-middleware')(compiler, {
45 | log: false,
46 | heartbeat: 2000
47 | })
48 | // force page reload when html-webpack-plugin template changes
49 | compiler.plugin('compilation', function(compilation) {
50 | compilation.plugin('html-webpack-plugin-after-emit', function(data, cb) {
51 | hotMiddleware.publish({ action: 'reload' })
52 | cb()
53 | })
54 | })
55 |
56 | // proxy api requests
57 | Object.keys(proxyTable).forEach(function(context) {
58 | var options = proxyTable[context]
59 | if (typeof options === 'string') {
60 | options = { target: options }
61 | }
62 | app.use(proxyMiddleware(options.filter || context, options))
63 | })
64 |
65 | // handle fallback for HTML5 history API
66 | app.use(require('connect-history-api-fallback')())
67 |
68 | // serve webpack bundle output
69 | app.use(devMiddleware)
70 |
71 | // enable hot-reload and state-preserving
72 | // compilation error display
73 | app.use(hotMiddleware)
74 |
75 | // serve pure static assets
76 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
77 | app.use(staticPath, express.static('./static'))
78 |
79 | var uri = 'http://localhost:' + port
80 |
81 | var _resolve
82 | var readyPromise = new Promise(resolve => {
83 | _resolve = resolve
84 | })
85 |
86 | console.log('> Starting dev server...')
87 | devMiddleware.waitUntilValid(() => {
88 | console.log('> Listening at ' + uri + '\n')
89 | // when env is testing, don't need open it
90 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
91 | opn(uri)
92 | }
93 | _resolve()
94 | })
95 |
96 | var server = app.listen(port)
97 |
98 | module.exports = {
99 | ready: readyPromise,
100 | close: () => {
101 | server.close()
102 | }
103 | }
--------------------------------------------------------------------------------
/client/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 |
5 | exports.assetsPath = function (_path) {
6 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
7 | ? config.build.assetsSubDirectory
8 | : config.dev.assetsSubDirectory
9 | return path.posix.join(assetsSubDirectory, _path)
10 | }
11 |
12 | exports.cssLoaders = function (options) {
13 | options = options || {}
14 |
15 | var cssLoader = {
16 | loader: 'css-loader',
17 | options: {
18 | minimize: process.env.NODE_ENV === 'production',
19 | sourceMap: options.sourceMap
20 | }
21 | }
22 |
23 | // generate loader string to be used with extract text plugin
24 | function generateLoaders (loader, loaderOptions) {
25 | var loaders = [cssLoader]
26 | if (loader) {
27 | loaders.push({
28 | loader: loader + '-loader',
29 | options: Object.assign({}, loaderOptions, {
30 | sourceMap: options.sourceMap
31 | })
32 | })
33 | }
34 |
35 | // Extract CSS when that option is specified
36 | // (which is the case during production build)
37 | if (options.extract) {
38 | return ExtractTextPlugin.extract({
39 | use: loaders,
40 | fallback: 'vue-style-loader'
41 | })
42 | } else {
43 | return ['vue-style-loader'].concat(loaders)
44 | }
45 | }
46 |
47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
48 | return {
49 | css: generateLoaders(),
50 | postcss: generateLoaders(),
51 | less: generateLoaders('less'),
52 | sass: generateLoaders('sass', { indentedSyntax: true }),
53 | scss: generateLoaders('sass'),
54 | stylus: generateLoaders('stylus'),
55 | styl: generateLoaders('stylus')
56 | }
57 | }
58 |
59 | // Generate loaders for standalone style files (outside of .vue)
60 | exports.styleLoaders = function (options) {
61 | var output = []
62 | var loaders = exports.cssLoaders(options)
63 | for (var extension in loaders) {
64 | var loader = loaders[extension]
65 | output.push({
66 | test: new RegExp('\\.' + extension + '$'),
67 | use: loader
68 | })
69 | }
70 | return output
71 | }
72 |
--------------------------------------------------------------------------------
/client/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var config = require('../config')
3 | var isProduction = process.env.NODE_ENV === 'production'
4 |
5 | module.exports = {
6 | loaders: utils.cssLoaders({
7 | sourceMap: isProduction
8 | ? config.build.productionSourceMap
9 | : config.dev.cssSourceMap,
10 | extract: isProduction
11 | }),
12 | transformToRequire: {
13 | video: 'src',
14 | source: 'src',
15 | img: 'src',
16 | image: 'xlink:href'
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/client/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var config = require('../config')
4 | var vueLoaderConfig = require('./vue-loader.conf')
5 |
6 | function resolve(dir) {
7 | return path.join(__dirname, '..', dir)
8 | }
9 |
10 | module.exports = {
11 | entry: {
12 | app: './src/main.js'
13 | },
14 | output: {
15 | path: config.build.assetsRoot,
16 | filename: '[name].js',
17 | publicPath: process.env.NODE_ENV === 'production' ?
18 | config.build.assetsPublicPath : config.dev.assetsPublicPath
19 | },
20 | resolve: {
21 | extensions: ['.js', '.vue', '.json', '.css'],
22 | alias: {
23 | 'vue$': 'vue/dist/vue.esm.js',
24 | '@': resolve('src'),
25 | }
26 | },
27 | module: {
28 | rules: [
29 | // {
30 | // test: /\.(js|vue)$/,
31 | // loader: 'eslint-loader',
32 | // enforce: 'pre',
33 | // include: [resolve('src'), resolve('test')],
34 | // options: {
35 | // formatter: require('eslint-friendly-formatter')
36 | // }
37 | // },
38 | {
39 | test: /\.vue$/,
40 | loader: 'vue-loader',
41 | options: vueLoaderConfig
42 | },
43 | {
44 | test: /\.js$/,
45 | loader: 'babel-loader',
46 | include: [resolve('src'), resolve('test')]
47 | },
48 | {
49 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
50 | loader: 'url-loader',
51 | options: {
52 | limit: 10000,
53 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
54 | }
55 | },
56 | {
57 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
58 | loader: 'url-loader',
59 | options: {
60 | limit: 10000,
61 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
62 | }
63 | },
64 | {
65 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
66 | loader: 'url-loader',
67 | options: {
68 | limit: 10000,
69 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
70 | }
71 | }
72 | ]
73 | }
74 | }
--------------------------------------------------------------------------------
/client/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var webpack = require('webpack')
3 | var config = require('../config')
4 | var merge = require('webpack-merge')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | var HtmlWebpackPlugin = require('html-webpack-plugin')
7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
8 |
9 | // add hot-reload related code to entry chunks
10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
12 | })
13 |
14 | module.exports = merge(baseWebpackConfig, {
15 | module: {
16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
17 | },
18 | // cheap-module-eval-source-map is faster for development
19 | devtool: '#cheap-module-eval-source-map',
20 | plugins: [
21 | new webpack.DefinePlugin({
22 | 'process.env': config.dev.env
23 | }),
24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
25 | new webpack.HotModuleReplacementPlugin(),
26 | new webpack.NoEmitOnErrorsPlugin(),
27 | // https://github.com/ampedandwired/html-webpack-plugin
28 | new HtmlWebpackPlugin({
29 | filename: 'index.html',
30 | template: 'index.html',
31 | inject: true
32 | }),
33 | new FriendlyErrorsPlugin()
34 | ]
35 | })
36 |
--------------------------------------------------------------------------------
/client/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var webpack = require('webpack')
4 | var config = require('../config')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var CopyWebpackPlugin = require('copy-webpack-plugin')
8 | var HtmlWebpackPlugin = require('html-webpack-plugin')
9 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
11 |
12 | var env = process.env.NODE_ENV === 'testing'
13 | ? require('../config/test.env')
14 | : config.build.env
15 |
16 | var webpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({
19 | sourceMap: config.build.productionSourceMap,
20 | extract: true
21 | })
22 | },
23 | devtool: config.build.productionSourceMap ? '#source-map' : false,
24 | output: {
25 | path: config.build.assetsRoot,
26 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
28 | },
29 | plugins: [
30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
31 | new webpack.DefinePlugin({
32 | 'process.env': env
33 | }),
34 | new webpack.optimize.UglifyJsPlugin({
35 | compress: {
36 | warnings: false
37 | },
38 | sourceMap: true
39 | }),
40 | // extract css into its own file
41 | new ExtractTextPlugin({
42 | filename: utils.assetsPath('css/[name].[contenthash].css')
43 | }),
44 | // Compress extracted CSS. We are using this plugin so that possible
45 | // duplicated CSS from different components can be deduped.
46 | new OptimizeCSSPlugin({
47 | cssProcessorOptions: {
48 | safe: true
49 | }
50 | }),
51 | // generate dist index.html with correct asset hash for caching.
52 | // you can customize output by editing /index.html
53 | // see https://github.com/ampedandwired/html-webpack-plugin
54 | new HtmlWebpackPlugin({
55 | filename: process.env.NODE_ENV === 'testing'
56 | ? 'index.html'
57 | : config.build.index,
58 | template: 'index.html',
59 | inject: true,
60 | minify: {
61 | removeComments: true,
62 | collapseWhitespace: true,
63 | removeAttributeQuotes: true
64 | // more options:
65 | // https://github.com/kangax/html-minifier#options-quick-reference
66 | },
67 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
68 | chunksSortMode: 'dependency'
69 | }),
70 | // keep module.id stable when vender modules does not change
71 | new webpack.HashedModuleIdsPlugin(),
72 | // split vendor js into its own file
73 | new webpack.optimize.CommonsChunkPlugin({
74 | name: 'vendor',
75 | minChunks: function (module, count) {
76 | // any required modules inside node_modules are extracted to vendor
77 | return (
78 | module.resource &&
79 | /\.js$/.test(module.resource) &&
80 | module.resource.indexOf(
81 | path.join(__dirname, '../node_modules')
82 | ) === 0
83 | )
84 | }
85 | }),
86 | // extract webpack runtime and module manifest to its own file in order to
87 | // prevent vendor hash from being updated whenever app bundle is updated
88 | new webpack.optimize.CommonsChunkPlugin({
89 | name: 'manifest',
90 | chunks: ['vendor']
91 | }),
92 | // copy custom static assets
93 | new CopyWebpackPlugin([
94 | {
95 | from: path.resolve(__dirname, '../static'),
96 | to: config.build.assetsSubDirectory,
97 | ignore: ['.*']
98 | }
99 | ])
100 | ]
101 | })
102 |
103 | if (config.build.productionGzip) {
104 | var CompressionWebpackPlugin = require('compression-webpack-plugin')
105 |
106 | webpackConfig.plugins.push(
107 | new CompressionWebpackPlugin({
108 | asset: '[path].gz[query]',
109 | algorithm: 'gzip',
110 | test: new RegExp(
111 | '\\.(' +
112 | config.build.productionGzipExtensions.join('|') +
113 | ')$'
114 | ),
115 | threshold: 10240,
116 | minRatio: 0.8
117 | })
118 | )
119 | }
120 |
121 | if (config.build.bundleAnalyzerReport) {
122 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
123 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
124 | }
125 |
126 | module.exports = webpackConfig
127 |
--------------------------------------------------------------------------------
/client/build/webpack.test.conf.js:
--------------------------------------------------------------------------------
1 | // This is the webpack config used for unit tests.
2 |
3 | var utils = require('./utils')
4 | var webpack = require('webpack')
5 | var merge = require('webpack-merge')
6 | var baseConfig = require('./webpack.base.conf')
7 |
8 | var webpackConfig = merge(baseConfig, {
9 | // use inline sourcemap for karma-sourcemap-loader
10 | module: {
11 | rules: utils.styleLoaders()
12 | },
13 | devtool: '#inline-source-map',
14 | resolveLoader: {
15 | alias: {
16 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
17 | // see discussion at https://github.com/vuejs/vue-loader/issues/724
18 | 'scss-loader': 'sass-loader'
19 | }
20 | },
21 | plugins: [
22 | new webpack.DefinePlugin({
23 | 'process.env': require('../config/test.env')
24 | })
25 | ]
26 | })
27 |
28 | // no need for app entry during tests
29 | delete webpackConfig.entry
30 |
31 | module.exports = webpackConfig
32 |
--------------------------------------------------------------------------------
/client/config/api.config.js:
--------------------------------------------------------------------------------
1 | const isProdMode = Object.is(process.env.NODE_ENV, 'production')
2 |
3 | module.exports = {
4 | baseUrl: isProdMode ? 'http://vnshop.shudong.wang/api/' : 'api/'
5 | }
--------------------------------------------------------------------------------
/client/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"'
6 | })
7 |
--------------------------------------------------------------------------------
/client/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 |
4 | module.exports = {
5 | build: {
6 | env: require('./prod.env'),
7 | index: path.resolve(__dirname, '../dist/index.html'),
8 | assetsRoot: path.resolve(__dirname, '../dist'),
9 | assetsSubDirectory: 'static',
10 | assetsPublicPath: '/',
11 | productionSourceMap: true,
12 | // Gzip off by default as many popular static hosts such as
13 | // Surge or Netlify already gzip all static assets for you.
14 | // Before setting to `true`, make sure to:
15 | // npm install --save-dev compression-webpack-plugin
16 | productionGzip: false,
17 | productionGzipExtensions: ['js', 'css'],
18 | // Run the build command with an extra argument to
19 | // View the bundle analyzer report after build finishes:
20 | // `npm run build --report`
21 | // Set to `true` or `false` to always turn it on or off
22 | bundleAnalyzerReport: process.env.npm_config_report
23 | },
24 | dev: {
25 | env: require('./dev.env'),
26 | port: 8080,
27 | autoOpenBrowser: true,
28 | assetsSubDirectory: 'static',
29 | assetsPublicPath: '/',
30 | proxyTable: {
31 | // '/goods/**': {
32 | // target: 'http://localhost:3000'
33 | // },
34 | '/users/**': {
35 | target: 'http://localhost:3000'
36 | },
37 | '/api/**': {
38 | target: 'http://localhost:3000',
39 | pathRewrite: {
40 | '^/api': '/'
41 | }
42 | }
43 | },
44 | // CSS Sourcemaps off by default because relative paths are "buggy"
45 | // with this option, according to the CSS-Loader README
46 | // (https://github.com/webpack/css-loader#sourcemaps)
47 | // In our experience, they generally work as expected,
48 | // just be aware of this issue when enabling this option.
49 | cssSourceMap: false
50 | }
51 | }
--------------------------------------------------------------------------------
/client/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"'
3 | }
4 |
--------------------------------------------------------------------------------
/client/config/test.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var devEnv = require('./dev.env')
3 |
4 | module.exports = merge(devEnv, {
5 | NODE_ENV: '"testing"'
6 | })
7 |
--------------------------------------------------------------------------------
/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vnshop
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/client/mock/goods.json:
--------------------------------------------------------------------------------
1 | { "data": [{ "_id": { "$oid": "58c284b13a1bb9aa7033801b" }, "productId": "201710003", "productName": "平衡车", "salePrice": 1999, "productImage": "pingheng.jpg", "productUrl": "" }, { "_id": { "$oid": "58c284d7117a2e6599abef5e" }, "productId": "201710004", "productName": "头戴式耳机-3", "salePrice": 80, "productImage": "2.jpg", "productUrl": "" }, { "_id": { "$oid": "58c284e6117a2e6599abef5f" }, "productId": "201710005", "productName": "小米笔记本", "salePrice": 3549, "productImage": "note.jpg", "productUrl": "" }, { "_id": { "$oid": "58c284f4117a2e6599abef60" }, "productId": "201710006", "productName": "小米6", "salePrice": 2499, "productImage": "mi6.jpg", "productUrl": "" }, { "_id": { "$oid": "58e704ef98dab115d336b3f1" }, "productId": "201710002", "productName": "智能插线板", "salePrice": 59, "productImage": "6.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7050398dab115d336b3f2" }, "productId": "201710007", "productName": "自拍杆", "salePrice": 39, "productImage": "zipai.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7050c98dab115d336b3f3" }, "productId": "201710008", "productName": "小米净水器", "salePrice": 1999, "productImage": "8.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7051698dab115d336b3f4" }, "productId": "201710009", "productName": "IH 电饭煲", "salePrice": 999, "productImage": "9.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7052198dab115d336b3f5" }, "productId": "201710010", "productName": "小米电视4A", "salePrice": 2099, "productImage": "10.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7052a98dab115d336b3f6" }, "productId": "201710011", "productName": "Ear1000", "salePrice": 1000, "productImage": "11.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7053298dab115d336b3f7" }, "productId": "201710012", "productName": "Ear1100", "salePrice": 1100, "productImage": "12.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7053c98dab115d336b3f8" }, "productId": "201710013", "productName": "Ear2000", "salePrice": 2000, "productImage": "13.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7054798dab115d336b3f9" }, "productId": "201710014", "productName": "Ear1600", "salePrice": 1600, "productImage": "14.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7055198dab115d336b3fa" }, "productId": "201710015", "productName": "Ear1200", "salePrice": 1200, "productImage": "15.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7057798dab115d336b3fb" }, "productId": "201710016", "productName": "Ear700", "salePrice": 700, "productImage": "16.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7058498dab115d336b3fc" }, "productId": "201710017", "productName": "小钢炮蓝牙音箱", "salePrice": 129, "productImage": "1.jpg", "productUrl": "" }, { "_id": { "$oid": "58e7058d98dab115d336b3fd" }, "productId": "201710018", "productName": "智能摄像机", "salePrice": 389, "productImage": "photo.jpg", "productUrl": "" }] }
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vnshop",
3 | "version": "1.0.0",
4 | "description": "vue&&node shop",
5 | "author": "stark.wang",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "start": "node build/dev-server.js",
10 | "build": "node build/build.js",
11 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
12 | "e2e": "node test/e2e/runner.js",
13 | "test": "npm run unit && npm run e2e",
14 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
15 | },
16 | "dependencies": {
17 | "vue": "^2.4.2",
18 | "vue-infinite-scroll": "^2.0.1",
19 | "vue-router": "^2.7.0"
20 | },
21 | "devDependencies": {
22 | "autoprefixer": "^7.1.2",
23 | "axios": "^0.16.2",
24 | "babel-core": "^6.22.1",
25 | "babel-eslint": "^7.1.1",
26 | "babel-loader": "^7.1.1",
27 | "babel-plugin-istanbul": "^4.1.1",
28 | "babel-plugin-transform-runtime": "^6.22.0",
29 | "babel-preset-env": "^1.3.2",
30 | "babel-preset-stage-2": "^6.22.0",
31 | "babel-register": "^6.22.0",
32 | "chai": "^3.5.0",
33 | "chalk": "^2.0.1",
34 | "chromedriver": "^2.27.2",
35 | "connect-history-api-fallback": "^1.3.0",
36 | "copy-webpack-plugin": "^4.0.1",
37 | "cross-env": "^5.0.1",
38 | "cross-spawn": "^5.0.1",
39 | "css-loader": "^0.28.0",
40 | "cssnano": "^3.10.0",
41 | "eslint": "^3.19.0",
42 | "eslint-config-standard": "^6.2.1",
43 | "eslint-friendly-formatter": "^3.0.0",
44 | "eslint-loader": "^1.7.1",
45 | "eslint-plugin-html": "^3.0.0",
46 | "eslint-plugin-promise": "^3.4.0",
47 | "eslint-plugin-standard": "^2.0.1",
48 | "eventsource-polyfill": "^0.9.6",
49 | "express": "^4.14.1",
50 | "extract-text-webpack-plugin": "^2.0.0",
51 | "file-loader": "^0.11.1",
52 | "friendly-errors-webpack-plugin": "^1.1.3",
53 | "html-webpack-plugin": "^2.28.0",
54 | "http-proxy-middleware": "^0.17.3",
55 | "inject-loader": "^3.0.0",
56 | "karma": "^1.4.1",
57 | "karma-coverage": "^1.1.1",
58 | "karma-mocha": "^1.3.0",
59 | "karma-phantomjs-launcher": "^1.0.2",
60 | "karma-phantomjs-shim": "^1.4.0",
61 | "karma-sinon-chai": "^1.3.1",
62 | "karma-sourcemap-loader": "^0.3.7",
63 | "karma-spec-reporter": "0.0.31",
64 | "karma-webpack": "^2.0.2",
65 | "mocha": "^3.2.0",
66 | "nightwatch": "^0.9.12",
67 | "opn": "^5.1.0",
68 | "optimize-css-assets-webpack-plugin": "^2.0.0",
69 | "ora": "^1.2.0",
70 | "phantomjs-prebuilt": "^2.1.14",
71 | "rimraf": "^2.6.0",
72 | "selenium-server": "^3.0.1",
73 | "semver": "^5.3.0",
74 | "shelljs": "^0.7.6",
75 | "sinon": "^2.1.0",
76 | "sinon-chai": "^2.8.0",
77 | "url-loader": "^0.5.8",
78 | "vue-axios": "^2.0.2",
79 | "vue-lazyload": "^1.1.3",
80 | "vue-loader": "^13.0.4",
81 | "vue-style-loader": "^3.0.1",
82 | "vue-template-compiler": "^2.4.2",
83 | "webpack": "^2.6.1",
84 | "webpack-bundle-analyzer": "^2.2.1",
85 | "webpack-dev-middleware": "^1.10.0",
86 | "webpack-hot-middleware": "^2.18.0",
87 | "webpack-merge": "^4.1.0"
88 | },
89 | "engines": {
90 | "node": ">= 4.0.0",
91 | "npm": ">= 3.0.0"
92 | },
93 | "browserslist": [
94 | "> 1%",
95 | "last 2 versions",
96 | "not ie <= 8"
97 | ]
98 | }
99 |
--------------------------------------------------------------------------------
/client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
15 |
--------------------------------------------------------------------------------
/client/src/api/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import apiConfig from '../../config/api.config';
3 |
4 | const service = axios.create({
5 | baseURL: apiConfig.baseUrl
6 | // baseURL: 'api/'
7 | })
8 |
9 | Vue.prototype.$http = service
10 | export default service
--------------------------------------------------------------------------------
/client/src/assets/css/app.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 | @import './checkout.css';
3 | @import './login.css';
4 | @import './product.css';
5 | @import './style.css';
--------------------------------------------------------------------------------
/client/src/assets/css/login.css:
--------------------------------------------------------------------------------
1 | /*nav*/
2 | .header {
3 | width: 100%;
4 | background-color: white;
5 | font-family: "moderat",sans-serif;
6 | font-size: 16px;
7 | }
8 | .navbar {
9 | display: flex;
10 | justify-content: space-between;
11 | align-content: center;
12 | width: 100%;
13 | height: 70px;
14 | max-width: 1280px;
15 | margin: 0 auto;
16 | padding: 5px 20px 10px 20px;
17 | }
18 | .navbar-left-container {
19 | display: flex;
20 | justify-content: flex-start;
21 | align-items: center;
22 | margin-left: -20px;
23 | }
24 | .navbar-brand-logo {
25 | /*width: 120px;*/
26 | }
27 | .header a, .footer a {
28 | color: #666;
29 | text-decoration: none;
30 | }
31 | a {
32 | -webkit-transition: color .3s ease-out;
33 | transition: color .3s ease-out;
34 | }
35 | .navbar-right-container {
36 | display: none;
37 | justify-content: flex-start;
38 | align-items: center;
39 | }
40 | .navbar-menu-container {
41 | display: flex;
42 | justify-content: flex-end;
43 | align-items: center;
44 | padding-top: 10px;
45 | }
46 | .navbar-link {
47 | padding-left: 15px;
48 | }
49 | .navbar-cart-container {
50 | position: relative;
51 | }
52 | .navbar-cart-count {
53 | justify-content: center;
54 | align-items: center;
55 | position: absolute;
56 | top: -9px;
57 | right: -11px;
58 | width: 20px;
59 | border-radius: 10px;
60 | color: white;
61 | background-color: #eb767d;
62 | font-size: 16px;
63 | font-weight: bold;
64 | text-align: center;
65 | }
66 | .navbar-cart-logo {
67 | width: 25px;
68 | height: 25px;
69 | transform: scaleX(-1);
70 | }
71 | /*login*/
72 | .regi_form_input{
73 | position: relative;
74 | height: 42px;
75 | line-height: 42px;
76 | background: none;
77 | margin-bottom: 15px;
78 | font-size: 14px;
79 | overflow: hidden;
80 | border:1px solid #ccc;
81 | padding-bottom: 0;
82 | }
83 | .regi_form_input .icon {
84 | display: inline-block;
85 | float: left;
86 | width: 25px;
87 | height: 29px;
88 | margin: 6px 0 0 14px;
89 | background-position: 4px 5px;
90 | background-image: url("/static/icon.png");
91 | background-repeat: no-repeat;
92 | }
93 | .regi_form_input .IconPwd {
94 | background-position: -198px 3px;
95 | }
96 | .regi_form_input .regi_login_input{
97 | position: absolute;
98 | left:45px;
99 | top:0;
100 | padding: 9px 0 10px;
101 | width: 270px;
102 | font-size: 14px;
103 | zoom: 1;
104 | border: none;
105 | color: #333;
106 | /*height: 23px;*/
107 | line-height: 23px;
108 | background: 0 0!important;
109 | }
110 | .md-title{
111 | position: absolute;
112 | top: 14px;
113 | line-height: 24px;
114 | padding: 8px 0;
115 | color: #333;
116 | font-size: 18px;
117 | font-weight: 400;
118 | font-style: normal;
119 | }
120 | .login-wrap{
121 | margin-top:30px;
122 | }
123 | .md-content .btn-login{
124 | display: block;
125 | height: 38px;
126 | line-height: 38px;
127 | border: 2px solid #009de6;
128 | background: #009de6;
129 | color: #fff;
130 | font-size: 18px;
131 | text-align: center;
132 | }
133 | .btn-login:hover {
134 | background: #61b1ef;
135 | border: 2px solid #61b1ef;
136 | }
137 | .error-wrap .error{
138 | font-size: 12px;
139 | color: #d31723;
140 | visibility: hidden;
141 | display: block;
142 | padding: 0 0 7px 17px;
143 | line-height: 16px;
144 | height: 16px;
145 | text-align: left;
146 | background: url("/static/icon.png") 0 -100px no-repeat;
147 | }
148 | .md-content .error-wrap .error-show{
149 | visibility: visible;
150 | height: auto;
151 | }
152 |
--------------------------------------------------------------------------------
/client/src/assets/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/1.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/10.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/11.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/12.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/13.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/14.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/15.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/16.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/2.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/3.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/4.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/5.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/6.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/7.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/8.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/9.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/bnt_subOrder.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/bnt_subOrder.gif
--------------------------------------------------------------------------------
/client/src/assets/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/icon.png
--------------------------------------------------------------------------------
/client/src/assets/img/logo-footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/logo-footer.png
--------------------------------------------------------------------------------
/client/src/assets/img/logo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/logo.gif
--------------------------------------------------------------------------------
/client/src/assets/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/logo.png
--------------------------------------------------------------------------------
/client/src/assets/img/mi6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/mi6.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/note.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/note.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/ok-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/ok-2.png
--------------------------------------------------------------------------------
/client/src/assets/img/photo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/photo.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/pingheng.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/pingheng.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/user_purchase20150409154845.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/user_purchase20150409154845.gif
--------------------------------------------------------------------------------
/client/src/assets/img/v-face1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/v-face1.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/v-face2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/v-face2.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/v-face3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/v-face3.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/v-face4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/v-face4.jpg
--------------------------------------------------------------------------------
/client/src/assets/img/vn-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/vn-logo.png
--------------------------------------------------------------------------------
/client/src/assets/img/vn_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/vn_logo.png
--------------------------------------------------------------------------------
/client/src/assets/img/zipai.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/img/zipai.jpg
--------------------------------------------------------------------------------
/client/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/src/assets/logo.png
--------------------------------------------------------------------------------
/client/src/components/Head.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
33 |
34 |
35 |
36 |
37 |
38 |
login in
39 |
40 |
41 |
42 |
43 |
44 | 用户名或密码错误
45 |
46 |
55 |
56 |
57 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
111 |
114 |
115 |
--------------------------------------------------------------------------------
/client/src/components/Hello.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
Essential Links
5 |
13 |
Ecosystem
14 |
20 |
21 |
22 |
23 |
33 |
34 |
35 |
54 |
--------------------------------------------------------------------------------
/client/src/components/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/client/src/components/NavBread.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/client/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 | import '@/assets/css/app'
7 | import VueLazyLoad from 'vue-lazyload'
8 |
9 | import apiConfig from '../config/api.config'
10 | import Axios from 'axios'
11 | import VueAxios from 'vue-axios'
12 |
13 | import infiniteScroll from 'vue-infinite-scroll'
14 | Vue.use(infiniteScroll)
15 |
16 | Vue.use(VueAxios, Axios);
17 | Axios.defaults.baseURL = apiConfig.baseUrl;
18 |
19 |
20 | Vue.use(VueLazyLoad, {
21 | loading: '/static/img/ok-2.png'
22 | })
23 | Vue.config.productionTip = false
24 |
25 | /* eslint-disable no-new */
26 | new Vue({
27 | el: '#app',
28 | router,
29 | template: '',
30 | components: { App }
31 | })
--------------------------------------------------------------------------------
/client/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Hello from '@/components/Hello'
4 | import GoodsList from '@/view/GoodsList'
5 | import User from '@/view/user/index'
6 | import Cart from '@/view/Cart'
7 | import Address from '@/view/Address'
8 | import OrderConfirm from '@/view/OrderConfirm'
9 | import OrderSuccess from '@/view/OrderSuccess'
10 |
11 | Vue.use(Router)
12 |
13 | export default new Router({
14 | routes: [{
15 | path: '/',
16 | name: 'GoodsList',
17 | component: GoodsList
18 | },
19 | {
20 | path: '/cart', //?代表可写,也可以不写 /user/1
21 | component: Cart
22 | },
23 | {
24 | path: '/address',
25 | component: Address
26 | },
27 | {
28 | path: '/orderConfirm',
29 | component: OrderConfirm
30 | },
31 | {
32 | path: '/orderSuccess',
33 | component: OrderSuccess
34 | },
35 | {
36 | path: '/user/:stark?/:xiaorong?', //?代表可写,也可以不写 /user/1
37 | component: User
38 | },
39 | ]
40 | })
--------------------------------------------------------------------------------
/client/src/view/OrderSuccess.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
购买完毕
5 |
6 |
7 |
check out
8 |
9 |
10 |
11 |
12 | - Confirm address
13 | - View your order
14 | - Make payment
15 | - Order confirmation
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Congratulations!
Your order is under processing!
23 |
24 | Order ID:{{orderId}}
25 | Order total:{{orderTotal}}
26 |
27 |
28 |
29 | 购物车列表
30 |
31 |
32 |
33 | 商品列表
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/client/src/view/user/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{item.userName}}
5 |
6 |
姓名:{{userInfo.userName}}
7 |
性别:{{userInfo.sex}}
8 |
爱好:{{userInfo.hobby}}
9 |
10 |
11 |
12 |
他的关注
13 |
他的分享
14 |
15 |
16 | {{$route.query}}
17 |
18 |
19 |
20 |
21 |
22 |
90 |
91 |
--------------------------------------------------------------------------------
/client/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/.gitkeep
--------------------------------------------------------------------------------
/client/static/images/201507/27_thumb_G_1437074702008.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/27_thumb_G_1437074702008.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/28_thumb_G_1437074792369.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/28_thumb_G_1437074792369.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/29_thumb_G_1437074933275.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/29_thumb_G_1437074933275.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/30_thumb_G_1437075007558.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/30_thumb_G_1437075007558.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/31_thumb_G_1437075539254.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/31_thumb_G_1437075539254.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/32_thumb_G_1437075765802.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/32_thumb_G_1437075765802.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/33_thumb_G_1437075865379.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/33_thumb_G_1437075865379.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/34_thumb_G_1437076036973.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/34_thumb_G_1437076036973.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/35_thumb_G_1437081702649.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/35_thumb_G_1437081702649.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/36_thumb_G_1437082145888.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/36_thumb_G_1437082145888.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/37_thumb_G_1437082214575.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/37_thumb_G_1437082214575.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/38_thumb_G_1437082667838.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/38_thumb_G_1437082667838.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/39_thumb_G_1437082747983.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/39_thumb_G_1437082747983.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/40_thumb_G_1437082798686.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/40_thumb_G_1437082798686.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/41_thumb_G_1437082849514.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/41_thumb_G_1437082849514.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/42_thumb_G_1437082936092.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/42_thumb_G_1437082936092.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/43_thumb_G_1437091900155.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/43_thumb_G_1437091900155.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/44_thumb_G_1437092148601.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/44_thumb_G_1437092148601.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/45_thumb_G_1437092199733.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/45_thumb_G_1437092199733.jpg
--------------------------------------------------------------------------------
/client/static/images/201507/46_thumb_G_1437092278369.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201507/46_thumb_G_1437092278369.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/47_thumb_G_1439331077002.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/47_thumb_G_1439331077002.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/53_thumb_G_1439511514539.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/53_thumb_G_1439511514539.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/56_thumb_G_1440717641715.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/56_thumb_G_1440717641715.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/57_thumb_G_1440717888680.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/57_thumb_G_1440717888680.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/59_thumb_G_1440983020324.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/59_thumb_G_1440983020324.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/60_thumb_G_1440983103483.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/60_thumb_G_1440983103483.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/64_thumb_G_1440983246324.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/64_thumb_G_1440983246324.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/65_thumb_G_1440983430401.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/65_thumb_G_1440983430401.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/66_thumb_G_1440983490045.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/66_thumb_G_1440983490045.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/67_thumb_G_1440983638116.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/67_thumb_G_1440983638116.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/68_thumb_G_1440983695997.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/68_thumb_G_1440983695997.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/69_thumb_G_1440983751530.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/69_thumb_G_1440983751530.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/70_thumb_G_1440983810214.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/70_thumb_G_1440983810214.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/71_thumb_G_1440983839269.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/71_thumb_G_1440983839269.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/72_thumb_G_1440983887661.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/72_thumb_G_1440983887661.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/73_thumb_G_1440983937959.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/73_thumb_G_1440983937959.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/74_thumb_G_1440983959230.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/74_thumb_G_1440983959230.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/75_thumb_G_1440984011595.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/75_thumb_G_1440984011595.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/76_thumb_G_1440984280864.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/76_thumb_G_1440984280864.jpg
--------------------------------------------------------------------------------
/client/static/images/201508/77_thumb_G_1440984390480.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201508/77_thumb_G_1440984390480.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/101_thumb_G_1441738730692.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/101_thumb_G_1441738730692.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/102_thumb_G_1441738765271.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/102_thumb_G_1441738765271.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/103_thumb_G_1441738795942.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/103_thumb_G_1441738795942.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/78_thumb_G_1441050387337.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/78_thumb_G_1441050387337.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/79_thumb_G_1441050485953.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/79_thumb_G_1441050485953.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/80_thumb_G_1441050558701.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/80_thumb_G_1441050558701.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/81_thumb_G_1441050609661.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/81_thumb_G_1441050609661.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/82_thumb_G_1441050801926.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/82_thumb_G_1441050801926.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/83_thumb_G_1441052403875.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/83_thumb_G_1441052403875.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/84_thumb_G_1441056023645.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/84_thumb_G_1441056023645.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/85_thumb_G_1441056112107.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/85_thumb_G_1441056112107.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/86_thumb_G_1441056239670.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/86_thumb_G_1441056239670.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/87_thumb_G_1441056303542.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/87_thumb_G_1441056303542.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/88_thumb_G_1441056484072.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/88_thumb_G_1441056484072.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/89_thumb_G_1441056597778.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/89_thumb_G_1441056597778.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/90_thumb_G_1441056659073.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/90_thumb_G_1441056659073.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/91_thumb_G_1441056702928.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/91_thumb_G_1441056702928.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/92_thumb_G_1441056728120.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/92_thumb_G_1441056728120.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/93_thumb_G_1441056767939.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/93_thumb_G_1441056767939.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/94_thumb_G_1441056891849.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/94_thumb_G_1441056891849.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/96_thumb_G_1441738537157.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/96_thumb_G_1441738537157.jpg
--------------------------------------------------------------------------------
/client/static/images/201509/98_thumb_G_1441738620606.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/images/201509/98_thumb_G_1441738620606.jpg
--------------------------------------------------------------------------------
/client/static/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/1.jpg
--------------------------------------------------------------------------------
/client/static/img/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/10.jpg
--------------------------------------------------------------------------------
/client/static/img/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/11.jpg
--------------------------------------------------------------------------------
/client/static/img/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/12.jpg
--------------------------------------------------------------------------------
/client/static/img/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/13.jpg
--------------------------------------------------------------------------------
/client/static/img/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/14.jpg
--------------------------------------------------------------------------------
/client/static/img/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/15.jpg
--------------------------------------------------------------------------------
/client/static/img/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/16.jpg
--------------------------------------------------------------------------------
/client/static/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/2.jpg
--------------------------------------------------------------------------------
/client/static/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/3.jpg
--------------------------------------------------------------------------------
/client/static/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/4.jpg
--------------------------------------------------------------------------------
/client/static/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/5.jpg
--------------------------------------------------------------------------------
/client/static/img/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/6.jpg
--------------------------------------------------------------------------------
/client/static/img/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/7.jpg
--------------------------------------------------------------------------------
/client/static/img/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/8.jpg
--------------------------------------------------------------------------------
/client/static/img/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/9.jpg
--------------------------------------------------------------------------------
/client/static/img/bnt_subOrder.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/bnt_subOrder.gif
--------------------------------------------------------------------------------
/client/static/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/icon.png
--------------------------------------------------------------------------------
/client/static/img/logo-footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/logo-footer.png
--------------------------------------------------------------------------------
/client/static/img/logo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/logo.gif
--------------------------------------------------------------------------------
/client/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/logo.png
--------------------------------------------------------------------------------
/client/static/img/mi6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/mi6.jpg
--------------------------------------------------------------------------------
/client/static/img/note.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/note.jpg
--------------------------------------------------------------------------------
/client/static/img/ok-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/ok-2.png
--------------------------------------------------------------------------------
/client/static/img/photo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/photo.jpg
--------------------------------------------------------------------------------
/client/static/img/pingheng.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/pingheng.jpg
--------------------------------------------------------------------------------
/client/static/img/user_purchase20150409154845.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/user_purchase20150409154845.gif
--------------------------------------------------------------------------------
/client/static/img/v-face1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/v-face1.jpg
--------------------------------------------------------------------------------
/client/static/img/v-face2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/v-face2.jpg
--------------------------------------------------------------------------------
/client/static/img/v-face3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/v-face3.jpg
--------------------------------------------------------------------------------
/client/static/img/v-face4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/v-face4.jpg
--------------------------------------------------------------------------------
/client/static/img/vn-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/vn-logo.png
--------------------------------------------------------------------------------
/client/static/img/vn_logo.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/vn_logo.1.png
--------------------------------------------------------------------------------
/client/static/img/vn_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/vn_logo.png
--------------------------------------------------------------------------------
/client/static/img/zipai.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/client/static/img/zipai.jpg
--------------------------------------------------------------------------------
/client/test/e2e/custom-assertions/elementCount.js:
--------------------------------------------------------------------------------
1 | // A custom Nightwatch assertion.
2 | // the name of the method is the filename.
3 | // can be used in tests like this:
4 | //
5 | // browser.assert.elementCount(selector, count)
6 | //
7 | // for how to write custom assertions see
8 | // http://nightwatchjs.org/guide#writing-custom-assertions
9 | exports.assertion = function (selector, count) {
10 | this.message = 'Testing if element <' + selector + '> has count: ' + count
11 | this.expected = count
12 | this.pass = function (val) {
13 | return val === this.expected
14 | }
15 | this.value = function (res) {
16 | return res.value
17 | }
18 | this.command = function (cb) {
19 | var self = this
20 | return this.api.execute(function (selector) {
21 | return document.querySelectorAll(selector).length
22 | }, [selector], function (res) {
23 | cb.call(self, res)
24 | })
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/client/test/e2e/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | require('babel-register')
2 | var config = require('../../config')
3 |
4 | // http://nightwatchjs.org/gettingstarted#settings-file
5 | module.exports = {
6 | src_folders: ['test/e2e/specs'],
7 | output_folder: 'test/e2e/reports',
8 | custom_assertions_path: ['test/e2e/custom-assertions'],
9 |
10 | selenium: {
11 | start_process: true,
12 | server_path: require('selenium-server').path,
13 | host: '127.0.0.1',
14 | port: 4444,
15 | cli_args: {
16 | 'webdriver.chrome.driver': require('chromedriver').path
17 | }
18 | },
19 |
20 | test_settings: {
21 | default: {
22 | selenium_port: 4444,
23 | selenium_host: 'localhost',
24 | silent: true,
25 | globals: {
26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
27 | }
28 | },
29 |
30 | chrome: {
31 | desiredCapabilities: {
32 | browserName: 'chrome',
33 | javascriptEnabled: true,
34 | acceptSslCerts: true
35 | }
36 | },
37 |
38 | firefox: {
39 | desiredCapabilities: {
40 | browserName: 'firefox',
41 | javascriptEnabled: true,
42 | acceptSslCerts: true
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/client/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | // 1. start the dev server using production config
2 | process.env.NODE_ENV = 'testing'
3 | var server = require('../../build/dev-server.js')
4 |
5 | server.ready.then(() => {
6 | // 2. run the nightwatch test suite against it
7 | // to run in additional browsers:
8 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
9 | // 2. add it to the --env flag below
10 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
11 | // For more information on Nightwatch's config file, see
12 | // http://nightwatchjs.org/guide#settings-file
13 | var opts = process.argv.slice(2)
14 | if (opts.indexOf('--config') === -1) {
15 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
16 | }
17 | if (opts.indexOf('--env') === -1) {
18 | opts = opts.concat(['--env', 'chrome'])
19 | }
20 |
21 | var spawn = require('cross-spawn')
22 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
23 |
24 | runner.on('exit', function (code) {
25 | server.close()
26 | process.exit(code)
27 | })
28 |
29 | runner.on('error', function (err) {
30 | server.close()
31 | throw err
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/client/test/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // For authoring Nightwatch tests, see
2 | // http://nightwatchjs.org/guide#usage
3 |
4 | module.exports = {
5 | 'default e2e tests': function (browser) {
6 | // automatically uses dev Server port from /config.index.js
7 | // default: http://localhost:8080
8 | // see nightwatch.conf.js
9 | const devServer = browser.globals.devServerURL
10 |
11 | browser
12 | .url(devServer)
13 | .waitForElementVisible('#app', 5000)
14 | .assert.elementPresent('.hello')
15 | .assert.containsText('h1', 'Welcome to Your Vue.js App')
16 | .assert.elementCount('img', 1)
17 | .end()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/client/test/unit/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | },
5 | "globals": {
6 | "expect": true,
7 | "sinon": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/client/test/unit/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | Vue.config.productionTip = false
4 |
5 | // require all test files (files that ends with .spec.js)
6 | const testsContext = require.context('./specs', true, /\.spec$/)
7 | testsContext.keys().forEach(testsContext)
8 |
9 | // require all src files except main.js for coverage.
10 | // you can also change this to match only the subset of files that
11 | // you want coverage for.
12 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
13 | srcContext.keys().forEach(srcContext)
14 |
--------------------------------------------------------------------------------
/client/test/unit/karma.conf.js:
--------------------------------------------------------------------------------
1 | // This is a karma config file. For more details see
2 | // http://karma-runner.github.io/0.13/config/configuration-file.html
3 | // we are also using it with karma-webpack
4 | // https://github.com/webpack/karma-webpack
5 |
6 | var webpackConfig = require('../../build/webpack.test.conf')
7 |
8 | module.exports = function (config) {
9 | config.set({
10 | // to run in additional browsers:
11 | // 1. install corresponding karma launcher
12 | // http://karma-runner.github.io/0.13/config/browsers.html
13 | // 2. add it to the `browsers` array below.
14 | browsers: ['PhantomJS'],
15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
16 | reporters: ['spec', 'coverage'],
17 | files: ['./index.js'],
18 | preprocessors: {
19 | './index.js': ['webpack', 'sourcemap']
20 | },
21 | webpack: webpackConfig,
22 | webpackMiddleware: {
23 | noInfo: true
24 | },
25 | coverageReporter: {
26 | dir: './coverage',
27 | reporters: [
28 | { type: 'lcov', subdir: '.' },
29 | { type: 'text-summary' }
30 | ]
31 | }
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/client/test/unit/specs/Hello.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Hello from '@/components/Hello'
3 |
4 | describe('Hello.vue', () => {
5 | it('should render correct contents', () => {
6 | const Constructor = Vue.extend(Hello)
7 | const vm = new Constructor().$mount()
8 | expect(vm.$el.querySelector('.hello h1').textContent)
9 | .to.equal('Welcome to Your Vue.js App')
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/node_modules/debug/.coveralls.yml:
--------------------------------------------------------------------------------
1 | repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve
2 |
--------------------------------------------------------------------------------
/node_modules/debug/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "node": true
5 | },
6 | "rules": {
7 | "no-console": 0,
8 | "no-empty": [1, { "allowEmptyCatch": true }]
9 | },
10 | "extends": "eslint:recommended"
11 | }
12 |
--------------------------------------------------------------------------------
/node_modules/debug/.npmignore:
--------------------------------------------------------------------------------
1 | support
2 | test
3 | examples
4 | example
5 | *.sock
6 | dist
7 | yarn.lock
8 | coverage
9 | bower.json
10 |
--------------------------------------------------------------------------------
/node_modules/debug/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | language: node_js
3 | node_js:
4 | - "6"
5 | - "5"
6 | - "4"
7 |
8 | install:
9 | - make node_modules
10 |
11 | script:
12 | - make lint
13 | - make test
14 | - make coveralls
15 |
--------------------------------------------------------------------------------
/node_modules/debug/LICENSE:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright (c) 2014 TJ Holowaychuk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | and associated documentation files (the 'Software'), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9 | subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or substantial
12 | portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 |
--------------------------------------------------------------------------------
/node_modules/debug/Makefile:
--------------------------------------------------------------------------------
1 | # get Makefile directory name: http://stackoverflow.com/a/5982798/376773
2 | THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
3 | THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
4 |
5 | # BIN directory
6 | BIN := $(THIS_DIR)/node_modules/.bin
7 |
8 | # Path
9 | PATH := node_modules/.bin:$(PATH)
10 | SHELL := /bin/bash
11 |
12 | # applications
13 | NODE ?= $(shell which node)
14 | YARN ?= $(shell which yarn)
15 | PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
16 | BROWSERIFY ?= $(NODE) $(BIN)/browserify
17 |
18 | .FORCE:
19 |
20 | install: node_modules
21 |
22 | node_modules: package.json
23 | @NODE_ENV= $(PKG) install
24 | @touch node_modules
25 |
26 | lint: .FORCE
27 | eslint browser.js debug.js index.js node.js
28 |
29 | test-node: .FORCE
30 | istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
31 |
32 | test-browser: .FORCE
33 | mkdir -p dist
34 |
35 | @$(BROWSERIFY) \
36 | --standalone debug \
37 | . > dist/debug.js
38 |
39 | karma start --single-run
40 | rimraf dist
41 |
42 | test: .FORCE
43 | concurrently \
44 | "make test-node" \
45 | "make test-browser"
46 |
47 | coveralls:
48 | cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
49 |
50 | .PHONY: all install clean distclean
51 |
--------------------------------------------------------------------------------
/node_modules/debug/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "debug",
3 | "repo": "visionmedia/debug",
4 | "description": "small debugging utility",
5 | "version": "2.6.9",
6 | "keywords": [
7 | "debug",
8 | "log",
9 | "debugger"
10 | ],
11 | "main": "src/browser.js",
12 | "scripts": [
13 | "src/browser.js",
14 | "src/debug.js"
15 | ],
16 | "dependencies": {
17 | "rauchg/ms.js": "0.7.1"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/node_modules/debug/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['mocha', 'chai', 'sinon'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | 'dist/debug.js',
19 | 'test/*spec.js'
20 | ],
21 |
22 |
23 | // list of files to exclude
24 | exclude: [
25 | 'src/node.js'
26 | ],
27 |
28 |
29 | // preprocess matching files before serving them to the browser
30 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
31 | preprocessors: {
32 | },
33 |
34 | // test results reporter to use
35 | // possible values: 'dots', 'progress'
36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
37 | reporters: ['progress'],
38 |
39 |
40 | // web server port
41 | port: 9876,
42 |
43 |
44 | // enable / disable colors in the output (reporters and logs)
45 | colors: true,
46 |
47 |
48 | // level of logging
49 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
50 | logLevel: config.LOG_INFO,
51 |
52 |
53 | // enable / disable watching file and executing tests whenever any file changes
54 | autoWatch: true,
55 |
56 |
57 | // start these browsers
58 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
59 | browsers: ['PhantomJS'],
60 |
61 |
62 | // Continuous Integration mode
63 | // if true, Karma captures browsers, runs the tests and exits
64 | singleRun: false,
65 |
66 | // Concurrency level
67 | // how many browser should be started simultaneous
68 | concurrency: Infinity
69 | })
70 | }
71 |
--------------------------------------------------------------------------------
/node_modules/debug/node.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./src/node');
2 |
--------------------------------------------------------------------------------
/node_modules/debug/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_args": [
3 | [
4 | {
5 | "raw": "debug@^2.1.3",
6 | "scope": null,
7 | "escapedName": "debug",
8 | "name": "debug",
9 | "rawSpec": "^2.1.3",
10 | "spec": ">=2.1.3 <3.0.0",
11 | "type": "range"
12 | },
13 | "D:\\stark\\vnshop\\node_modules\\jsonp"
14 | ]
15 | ],
16 | "_from": "debug@>=2.1.3 <3.0.0",
17 | "_id": "debug@2.6.9",
18 | "_inCache": true,
19 | "_location": "/debug",
20 | "_nodeVersion": "8.4.0",
21 | "_npmOperationalInternal": {
22 | "host": "s3://npm-registry-packages",
23 | "tmp": "tmp/debug-2.6.9.tgz_1506087154503_0.5196126794908196"
24 | },
25 | "_npmUser": {
26 | "name": "tootallnate",
27 | "email": "nathan@tootallnate.net"
28 | },
29 | "_npmVersion": "5.3.0",
30 | "_phantomChildren": {},
31 | "_requested": {
32 | "raw": "debug@^2.1.3",
33 | "scope": null,
34 | "escapedName": "debug",
35 | "name": "debug",
36 | "rawSpec": "^2.1.3",
37 | "spec": ">=2.1.3 <3.0.0",
38 | "type": "range"
39 | },
40 | "_requiredBy": [
41 | "/jsonp"
42 | ],
43 | "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
44 | "_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
45 | "_shrinkwrap": null,
46 | "_spec": "debug@^2.1.3",
47 | "_where": "D:\\stark\\vnshop\\node_modules\\jsonp",
48 | "author": {
49 | "name": "TJ Holowaychuk",
50 | "email": "tj@vision-media.ca"
51 | },
52 | "browser": "./src/browser.js",
53 | "bugs": {
54 | "url": "https://github.com/visionmedia/debug/issues"
55 | },
56 | "component": {
57 | "scripts": {
58 | "debug/index.js": "browser.js",
59 | "debug/debug.js": "debug.js"
60 | }
61 | },
62 | "contributors": [
63 | {
64 | "name": "Nathan Rajlich",
65 | "email": "nathan@tootallnate.net",
66 | "url": "http://n8.io"
67 | },
68 | {
69 | "name": "Andrew Rhyne",
70 | "email": "rhyneandrew@gmail.com"
71 | }
72 | ],
73 | "dependencies": {
74 | "ms": "2.0.0"
75 | },
76 | "description": "small debugging utility",
77 | "devDependencies": {
78 | "browserify": "9.0.3",
79 | "chai": "^3.5.0",
80 | "concurrently": "^3.1.0",
81 | "coveralls": "^2.11.15",
82 | "eslint": "^3.12.1",
83 | "istanbul": "^0.4.5",
84 | "karma": "^1.3.0",
85 | "karma-chai": "^0.1.0",
86 | "karma-mocha": "^1.3.0",
87 | "karma-phantomjs-launcher": "^1.0.2",
88 | "karma-sinon": "^1.0.5",
89 | "mocha": "^3.2.0",
90 | "mocha-lcov-reporter": "^1.2.0",
91 | "rimraf": "^2.5.4",
92 | "sinon": "^1.17.6",
93 | "sinon-chai": "^2.8.0"
94 | },
95 | "directories": {},
96 | "dist": {
97 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
98 | "shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
99 | "tarball": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
100 | },
101 | "gitHead": "13abeae468fea297d0dccc50bc55590809241083",
102 | "homepage": "https://github.com/visionmedia/debug#readme",
103 | "keywords": [
104 | "debug",
105 | "log",
106 | "debugger"
107 | ],
108 | "license": "MIT",
109 | "main": "./src/index.js",
110 | "maintainers": [
111 | {
112 | "name": "thebigredgeek",
113 | "email": "rhyneandrew@gmail.com"
114 | },
115 | {
116 | "name": "kolban",
117 | "email": "kolban1@kolban.com"
118 | },
119 | {
120 | "name": "tootallnate",
121 | "email": "nathan@tootallnate.net"
122 | },
123 | {
124 | "name": "tjholowaychuk",
125 | "email": "tj@vision-media.ca"
126 | }
127 | ],
128 | "name": "debug",
129 | "optionalDependencies": {},
130 | "readme": "ERROR: No README data found!",
131 | "repository": {
132 | "type": "git",
133 | "url": "git://github.com/visionmedia/debug.git"
134 | },
135 | "version": "2.6.9"
136 | }
137 |
--------------------------------------------------------------------------------
/node_modules/debug/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Detect Electron renderer process, which is node, but we should
3 | * treat as a browser.
4 | */
5 |
6 | if (typeof process !== 'undefined' && process.type === 'renderer') {
7 | module.exports = require('./browser.js');
8 | } else {
9 | module.exports = require('./node.js');
10 | }
11 |
--------------------------------------------------------------------------------
/node_modules/debug/src/inspector-log.js:
--------------------------------------------------------------------------------
1 | module.exports = inspectorLog;
2 |
3 | // black hole
4 | const nullStream = new (require('stream').Writable)();
5 | nullStream._write = () => {};
6 |
7 | /**
8 | * Outputs a `console.log()` to the Node.js Inspector console *only*.
9 | */
10 | function inspectorLog() {
11 | const stdout = console._stdout;
12 | console._stdout = nullStream;
13 | console.log.apply(console, arguments);
14 | console._stdout = stdout;
15 | }
16 |
--------------------------------------------------------------------------------
/node_modules/jsonp/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/node_modules/jsonp/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | env:
5 | global:
6 | - secure: UOzXsaDRo/x7DYmfkhWHCSMf42tqJY7kuL+YcId8kK84Ffn6UN3FVHQBzIE4Ri7zH3h83lGrjkp8FZeONovRXWC/2HF5idI3FwKDiAFhpRkJvXDH72CcmLr9atMV66WVUWLWUUWbMRL8TNRk5Hhgm/y70fcy+jTYInUyX4X+lqA=
7 | - secure: R0xq3sNFDJRI08/25Vz0cJ14rEo6U/aL3D0J8QkoBb21ZQORqzTL6/3WR3tSnh+X+VKELpjS5L0G4qVgJmFQcQkyBFz+rTkcJHkE/IjO9EMV+P3EAetXirTaHBahcg33i3kOAJl4qCi9b/Y4c3atkt+ooGz3Hc67IEkHddYqp/E=
8 |
--------------------------------------------------------------------------------
/node_modules/jsonp/.zuul.yml:
--------------------------------------------------------------------------------
1 | ui: tape
2 | browsers:
3 | - name: chrome
4 | version: 26..latest
5 | - name: firefox
6 | version: 21..latest
7 | - name: safari
8 | version: 5..latest
9 | - name: ie
10 | version: 6..latest
11 | - name: opera
12 | version: 11..latest
13 | - name: iphone
14 | version: 4.3..latest
15 | - name: ipad
16 | version: 4.3..latest
17 | - name: android
18 | version: 4.0..latest
19 |
--------------------------------------------------------------------------------
/node_modules/jsonp/History.md:
--------------------------------------------------------------------------------
1 |
2 | 0.2.1 / 2016-10-31
3 | ==================
4 |
5 | * loose debug version (#21, @roderickhsiao)
6 | * component: update "repo" field
7 |
8 | 0.2.0 / 2015-03-18
9 | ==================
10 |
11 | * add `bower.json`
12 | * add travis/zuul/saucelabs testing
13 | * add support for custom callback `name`
14 | * pin `debug` dep
15 |
16 | 0.1.0 / 2014-12-30
17 | ==================
18 |
19 | * Make sure `script.parentNode` exists before removing the script element (#12, @azer)
20 | * Return function to cancel in-progress jsonp request (#11, @feross)
21 | * add documentation for `prefix` option (#10, @feross)
22 |
23 | 0.0.4 / 2014-03-11
24 | ==================
25 |
26 | * simplify the variable name "id" creation logic
27 | * Readme: add Installation notes
28 | * fix jshint warnings
29 | * add repository field to `package.json`
30 | * fallback to `document.head` if there is not any script tags in the dom
31 | * remove script safely
32 |
33 | 0.0.3 / 2013-02-03
34 | ==================
35 |
36 | * use `index.js`
37 | * go back to integer ids
38 | * honor `param` option
39 |
40 | 0.0.2 / 2013-02-03
41 | ==================
42 |
43 | * make IE<=8 happy
44 |
45 | 0.0.1 / 2012-07-03
46 | ==================
47 |
48 | * Initial release.
49 |
--------------------------------------------------------------------------------
/node_modules/jsonp/Readme.md:
--------------------------------------------------------------------------------
1 |
2 | # jsonp
3 |
4 | A simple JSONP implementation.
5 |
6 | [![saucelabs][saucelabs-image]][saucelabs-url]
7 |
8 | ## Installation
9 |
10 | Install for node.js or browserify using `npm`:
11 |
12 | ``` bash
13 | $ npm install jsonp
14 | ```
15 |
16 | Install for component(1) using `component`:
17 |
18 | ``` bash
19 | $ component install LearnBoost/jsonp
20 | ```
21 |
22 | Install for browser using `bower`:
23 |
24 | ``` bash
25 | $ bower install jsonp
26 | ```
27 |
28 | ## API
29 |
30 | ### jsonp(url, opts, fn)
31 |
32 | - `url` (`String`) url to fetch
33 | - `opts` (`Object`), optional
34 | - `param` (`String`) name of the query string parameter to specify
35 | the callback (defaults to `callback`)
36 | - `timeout` (`Number`) how long after a timeout error is emitted. `0` to
37 | disable (defaults to `60000`)
38 | - `prefix` (`String`) prefix for the global callback functions that
39 | handle jsonp responses (defaults to `__jp`)
40 | - `name` (`String`) name of the global callback functions that
41 | handle jsonp responses (defaults to `prefix` + incremented counter)
42 | - `fn` callback
43 |
44 | The callback is called with `err, data` parameters.
45 |
46 | If it times out, the `err` will be an `Error` object whose `message` is
47 | `Timeout`.
48 |
49 | Returns a function that, when called, will cancel the in-progress jsonp request
50 | (`fn` won't be called).
51 |
52 | ## License
53 |
54 | MIT
55 |
56 | [saucelabs-image]: https://saucelabs.com/browser-matrix/jsonp.svg
57 | [saucelabs-url]: https://saucelabs.com/u/jsonp
58 |
--------------------------------------------------------------------------------
/node_modules/jsonp/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsonp",
3 | "main": "index.js",
4 | "version": "0.2.1",
5 | "homepage": "https://github.com/webmodules/jsonp",
6 | "description": "A sane JSONP implementation.",
7 | "keywords": [
8 | "jsonp"
9 | ],
10 | "license": "MIT",
11 | "ignore": [
12 | "**/.*",
13 | "node_modules",
14 | "bower_components",
15 | "test",
16 | "tests"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/node_modules/jsonp/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsonp",
3 | "repo": "webmodules/jsonp",
4 | "description": "A sane JSONP implementation.",
5 | "version": "0.2.1",
6 | "dependencies": {
7 | "visionmedia/debug": "*"
8 | },
9 | "scripts": [
10 | "index.js"
11 | ],
12 | "main": "index.js"
13 | }
14 |
--------------------------------------------------------------------------------
/node_modules/jsonp/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module dependencies
3 | */
4 |
5 | var debug = require('debug')('jsonp');
6 |
7 | /**
8 | * Module exports.
9 | */
10 |
11 | module.exports = jsonp;
12 |
13 | /**
14 | * Callback index.
15 | */
16 |
17 | var count = 0;
18 |
19 | /**
20 | * Noop function.
21 | */
22 |
23 | function noop(){}
24 |
25 | /**
26 | * JSONP handler
27 | *
28 | * Options:
29 | * - param {String} qs parameter (`callback`)
30 | * - prefix {String} qs parameter (`__jp`)
31 | * - name {String} qs parameter (`prefix` + incr)
32 | * - timeout {Number} how long after a timeout error is emitted (`60000`)
33 | *
34 | * @param {String} url
35 | * @param {Object|Function} optional options / callback
36 | * @param {Function} optional callback
37 | */
38 |
39 | function jsonp(url, opts, fn){
40 | if ('function' == typeof opts) {
41 | fn = opts;
42 | opts = {};
43 | }
44 | if (!opts) opts = {};
45 |
46 | var prefix = opts.prefix || '__jp';
47 |
48 | // use the callback name that was passed if one was provided.
49 | // otherwise generate a unique name by incrementing our counter.
50 | var id = opts.name || (prefix + (count++));
51 |
52 | var param = opts.param || 'callback';
53 | var timeout = null != opts.timeout ? opts.timeout : 60000;
54 | var enc = encodeURIComponent;
55 | var target = document.getElementsByTagName('script')[0] || document.head;
56 | var script;
57 | var timer;
58 |
59 |
60 | if (timeout) {
61 | timer = setTimeout(function(){
62 | cleanup();
63 | if (fn) fn(new Error('Timeout'));
64 | }, timeout);
65 | }
66 |
67 | function cleanup(){
68 | if (script.parentNode) script.parentNode.removeChild(script);
69 | window[id] = noop;
70 | if (timer) clearTimeout(timer);
71 | }
72 |
73 | function cancel(){
74 | if (window[id]) {
75 | cleanup();
76 | }
77 | }
78 |
79 | window[id] = function(data){
80 | debug('jsonp got', data);
81 | cleanup();
82 | if (fn) fn(null, data);
83 | };
84 |
85 | // add qs component
86 | url += (~url.indexOf('?') ? '&' : '?') + param + '=' + enc(id);
87 | url = url.replace('?&', '?');
88 |
89 | debug('jsonp req "%s"', url);
90 |
91 | // create script
92 | script = document.createElement('script');
93 | script.src = url;
94 | target.parentNode.insertBefore(script, target);
95 |
96 | return cancel;
97 | }
98 |
--------------------------------------------------------------------------------
/node_modules/jsonp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_args": [
3 | [
4 | {
5 | "raw": "jsonp",
6 | "scope": null,
7 | "escapedName": "jsonp",
8 | "name": "jsonp",
9 | "rawSpec": "",
10 | "spec": "latest",
11 | "type": "tag"
12 | },
13 | "D:\\stark\\vnshop"
14 | ]
15 | ],
16 | "_from": "jsonp@latest",
17 | "_id": "jsonp@0.2.1",
18 | "_inCache": true,
19 | "_location": "/jsonp",
20 | "_nodeVersion": "6.9.1",
21 | "_npmOperationalInternal": {
22 | "host": "packages-12-west.internal.npmjs.com",
23 | "tmp": "tmp/jsonp-0.2.1.tgz_1481179988894_0.9502592894714326"
24 | },
25 | "_npmUser": {
26 | "name": "feross",
27 | "email": "feross@feross.org"
28 | },
29 | "_npmVersion": "3.10.8",
30 | "_phantomChildren": {},
31 | "_requested": {
32 | "raw": "jsonp",
33 | "scope": null,
34 | "escapedName": "jsonp",
35 | "name": "jsonp",
36 | "rawSpec": "",
37 | "spec": "latest",
38 | "type": "tag"
39 | },
40 | "_requiredBy": [
41 | "#DEV:/",
42 | "#USER"
43 | ],
44 | "_resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz",
45 | "_shasum": "a65b4fa0f10bda719a05441ea7b94c55f3e15bae",
46 | "_shrinkwrap": null,
47 | "_spec": "jsonp",
48 | "_where": "D:\\stark\\vnshop",
49 | "bugs": {
50 | "url": "https://github.com/LearnBoost/jsonp/issues"
51 | },
52 | "component": {
53 | "scripts": {
54 | "jsonp": "jsonp.js"
55 | }
56 | },
57 | "dependencies": {
58 | "debug": "^2.1.3"
59 | },
60 | "description": "A sane JSONP implementation.",
61 | "devDependencies": {
62 | "tape": "^3.5.0",
63 | "zuul": "^1.17.1"
64 | },
65 | "directories": {},
66 | "dist": {
67 | "shasum": "a65b4fa0f10bda719a05441ea7b94c55f3e15bae",
68 | "tarball": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz"
69 | },
70 | "gitHead": "790398945dc391ad2f06b365193a040a3dc01977",
71 | "homepage": "https://github.com/LearnBoost/jsonp#readme",
72 | "maintainers": [
73 | {
74 | "name": "feross",
75 | "email": "feross@feross.org"
76 | },
77 | {
78 | "name": "rauchg",
79 | "email": "rauchg@gmail.com"
80 | },
81 | {
82 | "name": "tootallnate",
83 | "email": "nathan@tootallnate.net"
84 | }
85 | ],
86 | "name": "jsonp",
87 | "optionalDependencies": {},
88 | "readme": "ERROR: No README data found!",
89 | "repository": {
90 | "type": "git",
91 | "url": "git+https://github.com/LearnBoost/jsonp.git"
92 | },
93 | "scripts": {
94 | "test": "zuul -- test/*.js",
95 | "test-local": "zuul --local -- test/*.js"
96 | },
97 | "version": "0.2.1"
98 | }
99 |
--------------------------------------------------------------------------------
/node_modules/jsonp/test/basic.js:
--------------------------------------------------------------------------------
1 | var jsonp = require('../');
2 | var querystring = require('querystring');
3 | var test = require('tape');
4 |
5 | // See http://doc.jsfiddle.net/use/echo.html
6 | var ENDPOINT = 'http://jsfiddle.net/echo/jsonp/';
7 |
8 | test('basic jsonp', function (t) {
9 | t.plan(1);
10 | var obj = {
11 | beep: 'boop',
12 | yo: 'dawg'
13 | };
14 | var q = querystring.encode(obj);
15 | jsonp(ENDPOINT + '?' + q, function (err, data) {
16 | if (err) throw err;
17 | t.deepEqual(data, obj);
18 | });
19 | });
20 |
21 | test('timeout', function (t) {
22 | t.plan(1);
23 | var obj = {
24 | delay: 5 // time in seconds after which data should be returned
25 | };
26 | var q = querystring.encode(obj);
27 | jsonp(ENDPOINT + '?' + q, { timeout: 3000 }, function (err, data) {
28 | t.ok(err instanceof Error);
29 | });
30 | });
31 |
32 | test('named callback', function (t) {
33 | t.plan(1);
34 | var obj = {
35 | beep: 'boop',
36 | yo: 'dawg'
37 | };
38 | var q = querystring.encode(obj);
39 | jsonp(ENDPOINT + '?' + q, { name: 'namedCb' }, function (err, data) {
40 | if (err) throw err;
41 | t.deepEqual(data, obj);
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/node_modules/ms/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Helpers.
3 | */
4 |
5 | var s = 1000;
6 | var m = s * 60;
7 | var h = m * 60;
8 | var d = h * 24;
9 | var y = d * 365.25;
10 |
11 | /**
12 | * Parse or format the given `val`.
13 | *
14 | * Options:
15 | *
16 | * - `long` verbose formatting [false]
17 | *
18 | * @param {String|Number} val
19 | * @param {Object} [options]
20 | * @throws {Error} throw an error if val is not a non-empty string or a number
21 | * @return {String|Number}
22 | * @api public
23 | */
24 |
25 | module.exports = function(val, options) {
26 | options = options || {};
27 | var type = typeof val;
28 | if (type === 'string' && val.length > 0) {
29 | return parse(val);
30 | } else if (type === 'number' && isNaN(val) === false) {
31 | return options.long ? fmtLong(val) : fmtShort(val);
32 | }
33 | throw new Error(
34 | 'val is not a non-empty string or a valid number. val=' +
35 | JSON.stringify(val)
36 | );
37 | };
38 |
39 | /**
40 | * Parse the given `str` and return milliseconds.
41 | *
42 | * @param {String} str
43 | * @return {Number}
44 | * @api private
45 | */
46 |
47 | function parse(str) {
48 | str = String(str);
49 | if (str.length > 100) {
50 | return;
51 | }
52 | var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
53 | str
54 | );
55 | if (!match) {
56 | return;
57 | }
58 | var n = parseFloat(match[1]);
59 | var type = (match[2] || 'ms').toLowerCase();
60 | switch (type) {
61 | case 'years':
62 | case 'year':
63 | case 'yrs':
64 | case 'yr':
65 | case 'y':
66 | return n * y;
67 | case 'days':
68 | case 'day':
69 | case 'd':
70 | return n * d;
71 | case 'hours':
72 | case 'hour':
73 | case 'hrs':
74 | case 'hr':
75 | case 'h':
76 | return n * h;
77 | case 'minutes':
78 | case 'minute':
79 | case 'mins':
80 | case 'min':
81 | case 'm':
82 | return n * m;
83 | case 'seconds':
84 | case 'second':
85 | case 'secs':
86 | case 'sec':
87 | case 's':
88 | return n * s;
89 | case 'milliseconds':
90 | case 'millisecond':
91 | case 'msecs':
92 | case 'msec':
93 | case 'ms':
94 | return n;
95 | default:
96 | return undefined;
97 | }
98 | }
99 |
100 | /**
101 | * Short format for `ms`.
102 | *
103 | * @param {Number} ms
104 | * @return {String}
105 | * @api private
106 | */
107 |
108 | function fmtShort(ms) {
109 | if (ms >= d) {
110 | return Math.round(ms / d) + 'd';
111 | }
112 | if (ms >= h) {
113 | return Math.round(ms / h) + 'h';
114 | }
115 | if (ms >= m) {
116 | return Math.round(ms / m) + 'm';
117 | }
118 | if (ms >= s) {
119 | return Math.round(ms / s) + 's';
120 | }
121 | return ms + 'ms';
122 | }
123 |
124 | /**
125 | * Long format for `ms`.
126 | *
127 | * @param {Number} ms
128 | * @return {String}
129 | * @api private
130 | */
131 |
132 | function fmtLong(ms) {
133 | return plural(ms, d, 'day') ||
134 | plural(ms, h, 'hour') ||
135 | plural(ms, m, 'minute') ||
136 | plural(ms, s, 'second') ||
137 | ms + ' ms';
138 | }
139 |
140 | /**
141 | * Pluralization helper.
142 | */
143 |
144 | function plural(ms, n, name) {
145 | if (ms < n) {
146 | return;
147 | }
148 | if (ms < n * 1.5) {
149 | return Math.floor(ms / n) + ' ' + name;
150 | }
151 | return Math.ceil(ms / n) + ' ' + name + 's';
152 | }
153 |
--------------------------------------------------------------------------------
/node_modules/ms/license.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Zeit, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/node_modules/ms/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_args": [
3 | [
4 | {
5 | "raw": "ms@2.0.0",
6 | "scope": null,
7 | "escapedName": "ms",
8 | "name": "ms",
9 | "rawSpec": "2.0.0",
10 | "spec": "2.0.0",
11 | "type": "version"
12 | },
13 | "D:\\stark\\vnshop\\node_modules\\debug"
14 | ]
15 | ],
16 | "_from": "ms@2.0.0",
17 | "_id": "ms@2.0.0",
18 | "_inCache": true,
19 | "_location": "/ms",
20 | "_nodeVersion": "7.8.0",
21 | "_npmOperationalInternal": {
22 | "host": "packages-18-east.internal.npmjs.com",
23 | "tmp": "tmp/ms-2.0.0.tgz_1494937565215_0.34005374647676945"
24 | },
25 | "_npmUser": {
26 | "name": "leo",
27 | "email": "leo@zeit.co"
28 | },
29 | "_npmVersion": "4.2.0",
30 | "_phantomChildren": {},
31 | "_requested": {
32 | "raw": "ms@2.0.0",
33 | "scope": null,
34 | "escapedName": "ms",
35 | "name": "ms",
36 | "rawSpec": "2.0.0",
37 | "spec": "2.0.0",
38 | "type": "version"
39 | },
40 | "_requiredBy": [
41 | "/debug"
42 | ],
43 | "_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
44 | "_shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
45 | "_shrinkwrap": null,
46 | "_spec": "ms@2.0.0",
47 | "_where": "D:\\stark\\vnshop\\node_modules\\debug",
48 | "bugs": {
49 | "url": "https://github.com/zeit/ms/issues"
50 | },
51 | "dependencies": {},
52 | "description": "Tiny milisecond conversion utility",
53 | "devDependencies": {
54 | "eslint": "3.19.0",
55 | "expect.js": "0.3.1",
56 | "husky": "0.13.3",
57 | "lint-staged": "3.4.1",
58 | "mocha": "3.4.1"
59 | },
60 | "directories": {},
61 | "dist": {
62 | "shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
63 | "tarball": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
64 | },
65 | "eslintConfig": {
66 | "extends": "eslint:recommended",
67 | "env": {
68 | "node": true,
69 | "es6": true
70 | }
71 | },
72 | "files": [
73 | "index.js"
74 | ],
75 | "gitHead": "9b88d1568a52ec9bb67ecc8d2aa224fa38fd41f4",
76 | "homepage": "https://github.com/zeit/ms#readme",
77 | "license": "MIT",
78 | "lint-staged": {
79 | "*.js": [
80 | "npm run lint",
81 | "prettier --single-quote --write",
82 | "git add"
83 | ]
84 | },
85 | "main": "./index",
86 | "maintainers": [
87 | {
88 | "name": "leo",
89 | "email": "leo@zeit.co"
90 | },
91 | {
92 | "name": "rauchg",
93 | "email": "rauchg@gmail.com"
94 | }
95 | ],
96 | "name": "ms",
97 | "optionalDependencies": {},
98 | "readme": "ERROR: No README data found!",
99 | "repository": {
100 | "type": "git",
101 | "url": "git+https://github.com/zeit/ms.git"
102 | },
103 | "scripts": {
104 | "lint": "eslint lib/* bin/*",
105 | "precommit": "lint-staged",
106 | "test": "mocha tests.js"
107 | },
108 | "version": "2.0.0"
109 | }
110 |
--------------------------------------------------------------------------------
/node_modules/ms/readme.md:
--------------------------------------------------------------------------------
1 | # ms
2 |
3 | [](https://travis-ci.org/zeit/ms)
4 | [](https://zeit.chat/)
5 |
6 | Use this package to easily convert various time formats to milliseconds.
7 |
8 | ## Examples
9 |
10 | ```js
11 | ms('2 days') // 172800000
12 | ms('1d') // 86400000
13 | ms('10h') // 36000000
14 | ms('2.5 hrs') // 9000000
15 | ms('2h') // 7200000
16 | ms('1m') // 60000
17 | ms('5s') // 5000
18 | ms('1y') // 31557600000
19 | ms('100') // 100
20 | ```
21 |
22 | ### Convert from milliseconds
23 |
24 | ```js
25 | ms(60000) // "1m"
26 | ms(2 * 60000) // "2m"
27 | ms(ms('10 hours')) // "10h"
28 | ```
29 |
30 | ### Time format written-out
31 |
32 | ```js
33 | ms(60000, { long: true }) // "1 minute"
34 | ms(2 * 60000, { long: true }) // "2 minutes"
35 | ms(ms('10 hours'), { long: true }) // "10 hours"
36 | ```
37 |
38 | ## Features
39 |
40 | - Works both in [node](https://nodejs.org) and in the browser.
41 | - If a number is supplied to `ms`, a string with a unit is returned.
42 | - If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`).
43 | - If you pass a string with a number and a valid unit, the number of equivalent ms is returned.
44 |
45 | ## Caught a bug?
46 |
47 | 1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
48 | 2. Link the package to the global module directory: `npm link`
49 | 3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, node will now use your clone of ms!
50 |
51 | As always, you can run the tests using: `npm test`
52 |
--------------------------------------------------------------------------------
/note/01.开发goodlist组件.md:
--------------------------------------------------------------------------------
1 | ##把准备好的静态问题复制到 views/Goodlist.vue
2 |
3 | ## 静态文件是指 在仓库里面拉取的 shop-static 项目
4 | ```
5 | https://github.com/itguide/shop-static
6 | ```
7 | ### 创建GoodsList.vue 组件文件
8 | 在src里面创建一个views文件夹
9 | 在这个views里面
10 | 创建一个GoodsList.vue 文件
11 | ### 把静态文件里面的 body里面的文件复制到
12 | GoodsList.vue
13 |
14 |
15 |
16 | 复制的shop-static/views/goodList静态文件里面的body里面的内容
17 |
18 |
19 |
24 |
25 | ### 把静态文件里面 shop-static/img 文件夹复制到 vue 项目 static 里面
26 |
27 | ### 修改路由里面的文件
28 | ```
29 | import Vue from 'vue';
30 | import Router from 'vue-router';
31 | import HelloWorld from '@/components/HelloWorld';
32 | import GoodsList from '@/views/GoodsList'; // 增加了 引入这个组件
33 |
34 | Vue.use(Router);
35 |
36 | export default new Router({
37 | routes: [{
38 | path: '/',
39 | name: 'Hello',
40 | component: GoodsList, //修改这个组件名字
41 | }, ],
42 | });
43 | ```
--------------------------------------------------------------------------------
/note/02.vue项目中的@符号的意思.md:
--------------------------------------------------------------------------------
1 | ## @是什么意思?
2 |
3 | ## @ -> src
4 |
5 | ## 为什么是src
6 |
7 | ```
8 | resolve: {
9 | extensions: ['.js', '.vue', '.json'],
10 | alias: {
11 | 'vue$': 'vue/dist/vue.esm.js',
12 | '@': resolve('src'), // @符号代表 src
13 | }
14 | },
15 | ```
--------------------------------------------------------------------------------
/note/03.在项目中引入css样式的方法.md:
--------------------------------------------------------------------------------
1 | ##在组件里面引入
2 | 使用相对路径
3 | ```
4 |
11 | ```
12 |
13 | ## 在全局引入
14 |
15 | ```
16 | 在入口文件引入
17 | main.js
18 | import '../static/css/index.css'
19 |
20 | 在css里面新建一个index.css
21 | 把所有的css 从这导入
22 |
23 | index.css
24 | @import 'base.css';
25 | @import 'product.css';
26 | @import 'checkout.css';
27 | @import 'login.css';
28 | ```
--------------------------------------------------------------------------------
/note/04.当后端接口还没写完的时候.此时怎么做才不影响开发进度.md:
--------------------------------------------------------------------------------
1 | # 后端接口还没写完,怎么做?
2 | ## 使用mock数据
3 | easy-mock.com
4 |
5 | 看06 笔记
6 |
--------------------------------------------------------------------------------
/note/05.部组件拆分使用.md:
--------------------------------------------------------------------------------
1 | ##把可以拆分组件的内容单独放在一个组件
2 |
3 | ## 在需要的用到的组件里面引入
4 | 以下以 GoodsList.vue 为列子
5 | ```
6 | 在script里面
7 | 先引入需要的子组件
8 | import NavHeader from '@/components/Header'
9 | import NavFooter from '@/components/Footer'
10 | import NavBread from '@/components/NavBread'
11 |
12 | export default{
13 |
14 |
15 | components:{
16 | NavHeader,
17 | NavFooter,
18 | NavBread
19 | },
20 |
21 |
22 | ```
23 | ## 在dom中使用
24 |
25 | ```
26 | 如果不向自组件传递内容
27 | 就直接使用自闭合的标签
28 |
29 | 如果需要传递内容 需要在自组件里面写 插槽 slot
30 | 商品首页
31 | ```
--------------------------------------------------------------------------------
/note/06.模拟mock数据.md:
--------------------------------------------------------------------------------
1 | ## 可以使用第三方平台提供的数据
2 | easy-mock.com
3 | 在这个平台上可以把自己的json 数据方上去,可以修改请求的方式,post get
4 |
5 | ## 在本地新建一个mock的文件夹,里面放置json数据,使用vue cli server的express把这个数据请求,分发接口,供vue里面使用
6 | ```
7 |
8 | 先引入外部json数据
9 | var goodsData = require('../mock/mock-goods.json');
10 | 声明路由
11 | var router = express.Router();
12 | 写一个goods接口
13 | router.get("/goods", function(req, res, next) {
14 | 当别人访问goods接口的时候,把这个数据以json方式返回给用户
15 | res.json(goodsData);
16 | })
17 | 使用路由
18 | app.use(router);
19 |
20 | ```
21 |
22 |
23 | ## 在vuejs里面使用axios请求以上两种接口
24 | ```
25 | methods:{
26 | getGoodsList(){
27 | axios.get('http://easy-mock.com/mock/59664d4d58618039284c7710/example/goods/list').then(res=>{
28 | console.log(res);
29 | this.goods = res.data.data;
30 | })
31 | // axios.get('goods').then(res=>{
32 | // this.goods = res.data.data;
33 | // })
34 | }
35 | }
36 | ```
--------------------------------------------------------------------------------
/note/07.图片懒加载.md:
--------------------------------------------------------------------------------
1 | #在vue中使用图片懒加载详细指南
2 |
3 | https://segmentfault.com/a/1190000011672452
4 | ## 说明
5 | > 当网络请求比较慢的时候,提前给这张图片添加一个像素比较低的占位图片,不至于堆叠在一块,或显示大片空白,让用户体验更好一点。
6 | ## 使用方式
7 | 使用vue的 vue-lazyload 插件
8 | 插件地址:
9 | ```
10 | https://www.npmjs.com/package/vue-lazyload
11 |
12 | ```
13 | ## 案例
14 | demo: [懒加载案例demo](http://hilongjw.github.io/vue-lazyload/)
15 |
16 | # Installation 安装方式
17 |
18 | ## npm
19 |
20 | ```bash
21 |
22 | $ npm i vue-lazyload -D
23 |
24 | ```
25 |
26 | ## CDN
27 |
28 | CDN: [https://unpkg.com/vue-lazyload/vue-lazyload.js](https://unpkg.com/vue-lazyload/vue-lazyload.js)
29 |
30 | ```html
31 |
32 |
36 |
37 | ```
38 |
39 | # 用法
40 |
41 | main.js 在入口文件
42 |
43 | ```javascript
44 |
45 | import Vue from 'vue'
46 | import App from './App.vue'
47 | import VueLazyload from 'vue-lazyload' //引入这个懒加载插件
48 |
49 | Vue.use(VueLazyload)
50 |
51 | // 或者添加VueLazyload 选项
52 | Vue.use(VueLazyload, {
53 | preLoad: 1.3,
54 | error: 'dist/error.png',
55 | loading: 'dist/loading.gif',
56 | attempt: 1
57 | })
58 |
59 | new Vue({
60 | el: 'body',
61 | components: {
62 | App
63 | }
64 | })
65 | ```
66 |
67 | ## 在入口文件添加后,在组件任何地方都可以直接使用把 img 里的:src -> v-lazy
68 | ```
69 |
70 |
![]()
71 |
72 |
73 | 把之前项目中img 标签里面的 :src 属性 改成 v-lazy
74 |
75 |
![]()
76 |
77 | ```
78 |
79 | ## 参数选项说明
80 |
81 | |key|description|default|options|
82 | |:---|---|---|---|
83 | | `preLoad`|proportion of pre-loading height|`1.3`|`Number`|
84 | |`error`|当加载图片失败的时候|`'data-src'`|`String`
85 | |`loading`|当加载图片成功的时候|`'data-src'`|`String`|
86 | |`attempt`|尝试计数|`3`|`Number`|
87 | |`listenEvents`|想要监听的事件|`['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']`| [Desired Listen Events](#desired-listen-events) |
88 | |`adapter`| 动态修改元素属性 |`{ }`| [Element Adapter](#element-adapter) |
89 | |`filter`| 图片监听或过滤器|`{ }`| [Image listener filter](#image-listener-filter) |
90 | |`lazyComponent`| lazyload component | `false` | [Lazy Component](#lazy-component)
91 | | `dispatchEvent`|触发dom事件|`false`|`Boolean`|
92 | | `throttleWait`|throttle wait|`200`|`Number`|
93 | | `observer`|use IntersectionObserver|`false`|`Boolean`|
94 | | `observerOptions`|IntersectionObserver options|{ rootMargin: '0px', threshold: 0.1 }|[IntersectionObserver](#intersectionobserver)|
95 |
96 | ### 想要监听的事件
97 |
98 | 您可以通过传递数组来配置想要使用vue - lazyload的事件
99 | 监听器的名字。
100 |
101 | ```javascript
102 | Vue.use(VueLazyload, {
103 | preLoad: 1.3,
104 | error: 'dist/error.png',
105 | loading: 'dist/loading.gif',
106 | attempt: 1,
107 | // the default is ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend']
108 | listenEvents: [ 'scroll' ]
109 | })
110 | ```
111 |
112 | 如果您遇到这个插件重新设置加载的麻烦,这是很有用的
113 | 当你有某些动画和过渡的时候。
114 |
--------------------------------------------------------------------------------
/note/08.使用express-generator生成express项目.md:
--------------------------------------------------------------------------------
1 | #【express项目脚手架】使用express-generator生成express项目
2 | ## 用法
3 |
4 | ### 安装全局express命令行
5 | ```
6 | npm install express-generator -D
7 | ```
8 |
9 | ### 生成项目,并且安装项目依赖的包
10 | ```
11 | express server
12 | cd server
13 | npm i
14 | ```
15 |
16 | ### 启动方式
17 |
18 | ```
19 | node bin/www
20 | ```
21 |
22 | ### 访问 localhost:3000
23 |
24 | ### 添加git忽略文件 .gitignore
25 | ```
26 | .DS_Store
27 | node_modules/
28 | dist/
29 | npm-debug.log*
30 | yarn-debug.log*
31 | yarn-error.log*
32 | test/unit/coverage
33 | test/e2e/reports
34 | selenium-debug.log
35 |
36 | # Editor directories and files
37 | .idea
38 | .vscode
39 | *.suo
40 | *.ntvs*
41 | *.njsproj
42 | *.sln
43 |
44 | ```
45 |
46 | ## 优化启动方式,让每次修改代码后不需要重启
47 | ### 使用nodemon方式:
48 | [nodemon](https://www.npmjs.com/package/nodemon)
49 | #### 安装
50 | ```
51 | 全局安装:
52 | npm install -g nodemon
53 |
54 | or
55 | 本地安装:
56 | npm install --save-dev nodemon
57 | ```
58 | #### 在package.json里面配置快捷启动方式
59 | > 在package.json 的scripts选项里面添加
60 |
61 | ```
62 | "scripts": {
63 | "start": "node ./bin/www",
64 | "dev": "nodemon ./bin/www"
65 | },
66 | ```
67 |
68 | > 此时启动方式是:
69 | ```
70 | npm run dev
71 | ```
72 |
73 | ### 使用supervisor方式
74 |
75 | #### 使用方式说明
76 | ```
77 | 安装
78 | npm install supervisor -g
79 |
80 | 使用
81 | supervisor bin/www
82 | ```
83 | #### 把supervisor bin/www 的启动的方式添加到package.json
84 | > 在package.json 的scripts选项里面添加
85 |
86 | ```
87 | "scripts": {
88 | "start": "node ./bin/www",
89 | "sup": "supervisor ./bin/www"
90 | },
91 | ```
92 |
93 | > 此时启动方式是:
94 | ```
95 | npm run sup
96 | ```
97 |
98 | ### 使用pm2的方式
99 | >详细使用方式请去官网
100 | [pm2](http://pm2.keymetrics.io/)
101 |
102 | #### 全局安装
103 |
104 | ```
105 | npm install pm2 -g
106 |
107 | 启动方式
108 | pm2 start ./bin/www
109 |
110 | ```
111 |
112 | ####
113 |
114 | > 在package.json 的scripts选项里面添加
115 |
116 | ```
117 | "scripts": {
118 | "start": "node ./bin/www",
119 | "pm2": "pm2 start ./bin/www"
120 | },
121 | ```
122 |
123 | > 此时启动方式是:
124 | ```
125 | npm run pm2
126 | ```
127 |
--------------------------------------------------------------------------------
/note/09.express连接mongodb数据库.md:
--------------------------------------------------------------------------------
1 | ## 安装 mongoose 模块
2 |
3 | ```
4 | npm i mongoose -D
5 | ```
--------------------------------------------------------------------------------
/note/10.mongoose.操作指南.md:
--------------------------------------------------------------------------------
1 | ## 官方手册
2 | [官方手册](http://mongoosejs.com/docs/api.html#model_Model.find)
3 |
4 | ## find 查询
5 |
6 | ```
7 | // named john and at least 18
8 | MyModel.find({ name: 'john', age: { $gte: 18 }});
9 |
10 | // executes immediately, passing results to callback
11 | MyModel.find({ name: 'john', age: { $gte: 18 }}, function (err, docs) {});
12 |
13 | // name LIKE john and only selecting the "name" and "friends" fields, executing immediately
14 | MyModel.find({ name: /john/i }, 'name friends', function (err, docs) { })
15 |
16 | // passing options
17 | MyModel.find({ name: /john/i }, null, { skip: 10 })
18 |
19 | // passing options and executing immediately
20 | MyModel.find({ name: /john/i }, null, { skip: 10 }, function (err, docs) {});
21 |
22 | // executing a query explicitly
23 | var query = MyModel.find({ name: /john/i }, null, { skip: 10 })
24 | query.exec(function (err, docs) {});
25 |
26 | // using the promise returned from executing a query
27 | var query = MyModel.find({ name: /john/i }, null, { skip: 10 });
28 | var promise = query.exec();
29 | promise.addBack(function (err, docs) {});
30 | ```
31 |
32 | ##教程
33 |
34 | [菜鸟教程](http://www.runoob.com/mongodb/mongodb-operators.html)
35 |
36 | ## MongoDB 排序
37 |
38 | MongoDB sort()方法
39 | 在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
40 |
41 | ```
42 | router.get('/list', function(req, res, next) {
43 | let sort = req.param('sort');
44 |
45 | let goodsModel = Goods.find({}).sort({ 'salePrice': sort });
46 |
47 | goodsModel.exec({}, function(err, doc) {
48 | if (err) {
49 | res.json({ status: "1", msg: err.message })
50 | } else {
51 | res.json({ status: '0', msg: '', result: doc })
52 | }
53 | })
54 |
55 | })
56 | ```
--------------------------------------------------------------------------------
/note/11.根据价格排序.md:
--------------------------------------------------------------------------------
1 |
2 | ## 分析需求
3 |
4 | ### 需求1:价格排序:
5 | 点击页面的按钮从大到小排序,然后再点击从小到大排序
6 |
7 | 前台:
8 | 点击页面按钮 让下面的产品安装价格排序
9 | 需要一个api
10 | 同过两次点击,切换正序和倒序 ,给后端传一个参数
11 |
12 | 开始开发:
13 | 先思考,设计的时间越长,需要修改的时间越短
14 | 请求接口的时候,携带参数,1 -1
15 | 这个怎么来的,通过点击按钮来的
16 | 每次点击按钮 都会改变一个变量值
17 | 变量值默认是 1
18 |
19 | 拿到接口:
20 | postman 测试
21 |
22 | 后端api:
23 | baseurl: localhost:3000
24 | 1:表示接口正常
25 | 0:表示接口不正常
26 |
27 | http 状态码
28 | 200 ok
29 | 400 表示错误
30 |
31 | 拿到需求:
32 | 规定两个参数,来判断输出的结果
33 |
34 | 参数:sort
35 |
36 | api:/goods/list?sort=-1
37 | 接受两个参数:
38 | 接收: 1参数
39 | /goods/list?sort=1
40 | 返回数据:
41 | status:1
42 | msg:
43 | result:
44 | 商品正序数据
45 | 接收:-1 参数
46 | /goods/list?sort=-1
47 | 返回数据:商品倒序
48 |
49 | 开始开发:
50 | 在teambition 新建任务
51 | 第一步:从master 检出 最新代码
52 | git pull origin master
53 |
54 | 第二步:git 创建新的分支
55 | git checkout -b sort
56 |
57 | 测试完成:
58 | git checkout master //切换到master
59 | git merge sort // 合并到master
60 |
61 | develop
62 | 每次开发完一个功能,先合并到develop
63 |
64 |
65 |
66 | ## 接口代码:
67 | ```
68 | router.get('/list', function(req, res, next) {
69 | let sort = req.param('sort');
70 |
71 | let goodsModel = Goods.find({}).sort({ 'salePrice': sort });
72 |
73 | goodsModel.exec({}, function(err, doc) {
74 | if (err) {
75 | res.json({ status: "1", msg: err.message })
76 | } else {
77 | res.json({ status: '0', msg: '', result: doc })
78 | }
79 | })
80 |
81 | })
82 | ```
83 |
84 | ## vue前端操作
85 |
86 |
87 | ### 在dom里面添加了一个事件
88 |
89 | ```
90 | 价格
91 | ```
92 |
93 | ### 定义了一个data
94 |
95 | ```
96 | data(){
97 | return {
98 | goods:{},
99 | sortFlag:true
100 | }
101 | },
102 |
103 | ```
104 |
105 | ### 在methods里面定义了一个方法
106 |
107 | ```
108 | sortGoods(){
109 | this.sortFlag = !this.sortFlag;
110 | this.getGoodsList();
111 | }
112 | ```
113 |
114 | ### 修改了之前的请求接口,增加了传sort参数
115 | ```
116 | getGoodsList(){
117 | let sort = this.sortFlag ? 1 : -1;
118 | axios.get('/goods/list',{params:{sort:sort}}).then(res=>{
119 | this.goods = res.data.result;
120 | })
121 | },
122 | ```
--------------------------------------------------------------------------------
/note/12.按照价格区间筛选商品.md:
--------------------------------------------------------------------------------
1 | 按照价格区间筛选商品
2 | 后端:
3 | 每个那个啥,都价格,根据价格,最大值,最小值
4 | 从前台获取两个数,一个最大值,一个最小值,用mongodb条件查询
5 |
6 | 接收参数
7 |
8 | 根据前端传过来的参数,去数据库查询
9 |
10 | 实现思路:
11 | 根据前端传过来的数值,判断价格区间,然后去数据库里面查询
12 |
--------------------------------------------------------------------------------
/note/14.域名注册.md:
--------------------------------------------------------------------------------
1 | ## 域名注册
2 | 网址:
3 |
4 | https://wanwang.aliyun.com/ 推荐阿里云
5 |
6 | http://dnspod.cn/
7 |
8 | http://www.xinnet.com/
9 |
10 | https://www.west.cn/
11 |
12 | 注册完实名认证 审核需要几天
13 |
14 | 到时候买 国外的主机 30 5$
15 |
16 | com cn net shudong.wang
17 |
18 | .top 1元
19 |
20 | vnshop.cn
21 |
22 |
23 |
--------------------------------------------------------------------------------
/note/15.表驱动法.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/note/15.表驱动法.md
--------------------------------------------------------------------------------
/note/16.加入购物车.md:
--------------------------------------------------------------------------------
1 | 需求:
2 | 点击加入购物车的时候,把商品id传给api
3 |
4 | 是否登录
5 |
6 | api:
7 | 接收商品的id
8 | user_id
9 |
10 | 根据用户id查询用户数据,确定好用户
11 | 通过商品id去数据库查询,把商品信息查询出来
12 | if(这个用户是否加入过这个商品){
13 | 就把用户的这个商品数量加一
14 | }else{
15 | 然后把这个商品信息放在这个用户里面
16 | }
17 |
18 | 然后保存在用户里面
--------------------------------------------------------------------------------
/note/17.登录逻辑.md:
--------------------------------------------------------------------------------
1 | 前端:
2 | 输入用户名和密码
3 | 点击登录:
4 | 携带
5 | 用户名
6 | 密码,
7 | 验证码,(输入字母,数字,拖拽的验证码,计算数,图片点击)
8 | 短信验证码,
9 | 短信平台:创蓝短信 ,阿里大鱼,https://www.yunpian.com/
10 | 请求,登录接口
11 |
12 |
13 |
14 | 后端:
15 |
16 | 注册:
17 |
18 | 接收 username
19 | nickname
20 | password
21 | yanzhengma
22 | mail
23 |
24 | 使用正则验证 email 符不符合,邮箱规则
25 | 去数据库查询一下 mail 是否被注册
26 |
27 | password
28 | 检查password 是否是八位 必须包含 大小写 字母 数字 特殊符号
29 |
30 | 数据库里面的密码不是明文
31 | 把你的密码层层加密 base64
32 |
33 | sha1
34 | md5
35 |
36 |
37 |
38 | jwt
39 | passport
40 |
41 | redis
42 |
43 | token
44 |
45 |
46 | 每次请求api的时候
47 | 在header里面携带 token
48 |
49 |
50 | 脱库
51 | 社工库
52 |
53 |
--------------------------------------------------------------------------------
/note/18.登录前后台实现.md:
--------------------------------------------------------------------------------
1 | ##后台登录接口
2 | 接收前台传过来的用户名和密码,去数据库里面查询
3 |
4 | 在rootes 里面的user.js
5 | ### 后台登录接口代码
6 | ```
7 | router.post('/login', function(req, res, next) {
8 | let param = {
9 | userName: req.body.userName,
10 | userPwd: req.body.userPwd
11 | }
12 | console.log(param);
13 | User.findOne(param, function(err, doc) {
14 | console.log(err);
15 | if (err) { res.json({ "status": "1", msg: err.message }) } else {
16 | console.log('doc', doc);
17 | if (!doc) { res.json({ 'status': '1', msg: '', result: '用户名和密码错误' }) }
18 |
19 | //把userId 和 userName 存到cookie里面,在控制台的application里面找到cookie可以查看
20 |
21 | 第一个参数存的是 cookie 名字,第二个参数存的是值,地三个对象,里面
22 | path 是存的路径,maxAge 过期时间,以毫秒为单位
23 | res.cookie('userId', doc.userId, {
24 | path: '/',
25 | maxAge: 1000 * 60 * 60
26 | })
27 |
28 | res.cookie("userName", doc.userName, {
29 | path: '/',
30 | maxAge: 1000 * 60 * 60
31 | })
32 |
33 | if (doc) {
34 | res.json({
35 | status: 0,
36 | msg: '',
37 | result: {
38 | userName: doc.userName //最后返回用户名
39 | }
40 | })
41 | }
42 | }
43 | })
44 | })
45 | ```
46 |
47 | ##前台实现
48 | 在Header组件里面
49 |
50 | 把静态页面的模态框代码拷贝进来
51 |
52 |
53 | 模态框依靠 md-show 来控制显示隐藏
54 |
55 | 遮罩层 依靠v-if 来控制显示隐藏
56 |
57 | ```
58 |
59 |
60 |
61 |
65 |
66 |
67 |
68 | 用户名或密码错误
69 |
70 |
79 |
80 |
81 |
84 |
85 |
86 |
87 |
88 | ```
89 |
90 | ### js代码逻辑实现
91 | ```
92 | import axios from 'axios'
93 | export default {
94 | data(){
95 | return{
96 | nickName:'',
97 | userName:'',
98 | userPwd:'',
99 | loginModalFlag:false // 控制
100 | }
101 | },
102 | methods:{
103 | login(){
104 | axios.post('/users/login',{
105 | userName:this.userName,
106 | userPwd:this.userPwd
107 | }).then(result=>{
108 | let res = result.data;
109 | this.nickName = res.result.userName;
110 | this.loginModalFlag = false;
111 | })
112 | }
113 | }
114 | }
115 | ```
--------------------------------------------------------------------------------
/note/19.在项目前后分离的状态下,刷新页面,怎么保持用户登录.md:
--------------------------------------------------------------------------------
1 | ##在项目前后分离的状态下,刷新页面,怎么保持用户登录
2 |
3 | 在头部组件里面,初始化的时候,调用一个接口检查是否登录
4 |
5 | 如果登录了,就把用户昵称给到这个nickname变量里面
6 | 如果未登录,就提示未登录
7 |
8 | ### 在组件初始化完成之后,自动调用是否登录接口
9 | ```
10 | created(){
11 | this.checkLogin()
12 | },
13 | ```
14 |
15 |
16 | ### 是否登录接口
17 | ```
18 | checkLogin(){
19 | axios.post('/users/checkLogin').then(result=>{
20 | let res = result.data;
21 | 如果登录成功就把,登录的结果赋值到这里
22 | 如果未登录成功,这个结果空字符串
23 | this.nickName = res.result;
24 | })
25 | },
26 | ```
27 |
28 | ```
29 | / 检查是否登录
30 | router.post('/checkLogin', function(req, res, next) {
31 | // 使用cookies读取 cookies
32 | if (req.cookies.userId) {
33 | res.json({
34 | status: '0',
35 | result: req.cookies.userName
36 | })
37 | } else {
38 | res.json({
39 | status: 1,
40 | msg: '未登录',
41 | result: ''
42 | })
43 | }
44 | })
45 |
46 | ```
--------------------------------------------------------------------------------
/note/20.退出登录.md:
--------------------------------------------------------------------------------
1 | ## 退出登录
2 | ```
3 | // 退出登录
4 | router.post('/logout', function(req, res, next) {
5 | //清除 cookie
6 | 把userId的值变为空值
7 | res.cookie("userId", "", {
8 | path: '/',
9 | maxAge: -1 把时间变为负数
10 | })
11 |
12 | res.json({
13 | status: 0,
14 | msg: '',
15 | result: '退出成功'
16 | })
17 | })
18 | ```
19 |
20 |
21 | ## 前台操作
22 |
23 | ### dom操作
24 | ```
25 |
26 |
27 |
登录
28 |
|
29 | 在这点击按钮执行 logout 函数
30 |
退出
31 |
32 |
33 | ```
34 |
35 | ### js操作
36 | ```
37 | logout(){
38 | axios.post('/users/logout').then(result=>{
39 | let res = result.data;
40 | this.nickName = ''; //把nickName 清空
41 | console.log(res);
42 | })
43 | }
44 | ```
--------------------------------------------------------------------------------
/note/21.如何在vue里面优雅的解决跨域,路由冲突问题.md:
--------------------------------------------------------------------------------
1 | # 如何在vue里面优雅的解决跨域,路由冲突问题
2 | ## 当我们在路由里面配置成以下代理可以解决跨域问题
3 | ```
4 | proxyTable: {
5 | '/goods/*': {
6 | target: 'http://localhost:3000'
7 | },
8 | '/users/*': {
9 | target: 'http://localhost:3000'
10 | }
11 | },
12 | ```
13 | > 这种配置方式在一定程度上解决了跨域问题,但是会带来一些问题,
14 | 比如我们的vue 路由 也命名为 goods,这时候就会产生了冲突,
15 | 如果项目中接口很多,都在这里配置是很麻烦的,也容易产生路由冲突。
16 |
17 | ## 正确的姿势
18 | ## 如果把所有的接口,统一规范为一个入口,在一定程度上会解决冲突
19 |
20 | 把以上配置统一前面加上 /api/
21 |
22 | ```
23 | proxyTable: {
24 | '/api/**': {
25 | target: 'http://localhost:3000'
26 | },
27 | },
28 | ```
29 |
30 | ## 如果我们配置成这种方式,在使用http请求的时候就会发生变化,会在请求前面加上一个api,相对路由也会发生变化,也会在接口前面加上api,这样也会很麻烦,我们可以使用以下方式来解决这个问题
31 |
32 | ```
33 | proxyTable: {
34 | '/api/**': {
35 | target: 'http://localhost:3000',
36 | pathRewrite:{
37 | '^/api':'/'
38 | }
39 | },
40 | },
41 | ```
42 |
43 | ## 上面这个代码,就是把咱们虚拟的这个api接口,去掉,此时真正去后端请求的时候,不会加上api这个前缀了,那么这样我们前台http请求的时候,还必须加上api前缀才能匹配到这个代理,代码如下:
44 |
45 | ```
46 | logout(){
47 | axios.post('/api/users/logout').then(result=>{
48 | let res = result.data;
49 | this.nickName = '';
50 | console.log(res);
51 | })
52 | },
53 | getGoods(){
54 | axios.post('/api/goods/list').then(result=>{
55 | let res = result.data;
56 | this.nickName = '';
57 | console.log(res);
58 | })
59 | }
60 | ```
61 |
62 | ## 我们可以利用axios的baseUrl直接默认值是 api,这样我们每次访问的时候,自动补上这个api前缀,就不需要我们自己手工在每个接口上面写这个前缀了
63 |
64 | 在入口文件里面配置如下:
65 | ```
66 | import Axios from 'axios'
67 | import VueAxios from 'vue-axios'
68 |
69 | Vue.use(VueAxios, Axios)
70 | Axios.defaults.baseURL = 'api'
71 |
72 | 如果这配置 'api/' 会默认读取本地的域
73 | ```
74 |
75 | ### 上面这样配置的话,不会区分生产和开发环境
76 | 在config 文件夹里面新建一个 api.config.js 配置文件
77 |
78 | ```
79 | const isPro = Object.is(process.env.NODE_ENV, 'production')
80 |
81 | module.exports = {
82 | baseUrl: isPro ? 'http://www.vnshop.cn/api/' : 'api/'
83 | }
84 | ```
85 |
86 | ### 然后在main.js 里面引入,这样可以保证动态的匹配生产和开发的定义前缀
87 |
88 | ```
89 | import apiConfig from '../config/api.config'
90 |
91 | import Axios from 'axios'
92 | import VueAxios from 'vue-axios'
93 |
94 | Vue.use(VueAxios, Axios)
95 | Axios.defaults.baseURL = apiConfig.baseUrl
96 | ```
97 | ### 经过上面配置后,在dom里面可以这样轻松的访问,也不需要在任何组件里面引入axios模块了。
98 |
99 | ```
100 | logout(){
101 | this.$http.post('/users/logout').then(result=>{
102 | let res = result.data;
103 | this.nickName = '';
104 | console.log(res);
105 | })
106 | },
107 | getGoods(){
108 | this.$http.post('/goods/list').then(result=>{
109 | let res = result.data;
110 | this.nickName = '';
111 | console.log(res);
112 | })
113 | }
114 | ```
115 |
116 | ## 最终代码
117 |
118 | ### 在代理里面配置
119 |
120 | ```
121 | proxyTable: {
122 | '/api/**': {
123 | target: 'http://localhost:3000',
124 | pathRewrite:{
125 | '^/api':'/'
126 | }
127 | },
128 | },
129 | ```
130 |
131 | ### 在config里面的api.config.js 配置
132 |
133 | 在config 文件夹里面新建一个 api.config.js 配置文件
134 |
135 | ```
136 | const isPro = Object.is(process.env.NODE_ENV, 'production')
137 |
138 | module.exports = {
139 | baseUrl: isPro ? 'http://www.vnshop.cn/api/' : 'api/'
140 | }
141 | ```
142 |
143 |
144 | ### 在main.js 入口文件里面配置
145 |
146 | ```
147 | import apiConfig from '../config/api.config'
148 |
149 | import Axios from 'axios'
150 | import VueAxios from 'vue-axios'
151 |
152 | Vue.use(VueAxios, Axios)
153 | Axios.defaults.baseURL = apiConfig.baseUrl
154 | ```
155 |
156 |
157 |
158 | ### 在dom里面请求api的姿势
159 | ```
160 | logout(){
161 | this.$http.post('/users/logout').then(result=>{
162 | let res = result.data;
163 | this.nickName = '';
164 | console.log(res);
165 | })
166 | },
167 | getGoods(){
168 | this.$http.post('/goods/list').then(result=>{
169 | let res = result.data;
170 | this.nickName = '';
171 | console.log(res);
172 | })
173 | }
174 | ```
175 |
--------------------------------------------------------------------------------
/note/22.登录拦截.md:
--------------------------------------------------------------------------------
1 | ## 访问拦截
2 | 当我们点击加入购物车的时候判断一下是否登录
3 | 规定哪些接口是可以访问的,哪些接口是需要登录后才能访问的
4 |
5 | ## 具体实现
6 | 在app.js里面
7 | use 一个函数 ,每次请求url都会走这块
8 | ```
9 | app.use(function(req, res, next) {
10 | // console.log(1111);
11 |
12 | next() 放过通行
13 | })
14 | ```
15 |
16 | ## 在项目中使用
17 |
18 | ```
19 | app.use(function(req, res, next) {
20 | // console.log(1111);
21 | if (req.cookies.userId) { 判断用户是否登录
22 | next()
23 | } else {
24 | if (
25 | req.originalUrl == '/users/login' ||
26 | req.path == '/goods/list' ||
27 | req.originalUrl == '/users/checkLogin'
28 | ) {
29 | next()
30 | } else {
31 | res.json({
32 | status: '1',
33 | msg: '当前用户未登录',
34 | result: ''
35 | })
36 | }
37 | }
38 | })
39 | ```
--------------------------------------------------------------------------------
/note/23.开发购物车页面.md:
--------------------------------------------------------------------------------
1 | #购物车列表页面渲染
2 | ## 把购物车组件写好
3 | 创建组件,设置路由,拷贝静态文件
4 | ## 写购物车api
5 | 查询出登录的用户的详细信息,取里面的购物列表返回给前台
6 |
7 | ## 前台代码
8 |
9 | ## dom循环出来
10 | ```
11 |
12 |
13 | {{item.productName}}
14 | {{item.salePrice}}
15 | {{item.productNum}}
16 | {{item.salePrice * item.productNum}}
17 |
18 | ```
19 | ```
20 | import NavHeader from '@/components/Header'
21 | import NavFooter from '@/components/Footer'
22 | import NavBread from '@/components/NavBread'
23 | export default {
24 | data(){
25 | return{
26 | cartList:''
27 | }
28 | },
29 | components:{
30 | NavHeader,
31 | NavFooter,
32 | NavBread
33 | },
34 | created(){
35 | this.getCartList()
36 | },
37 | methods:{
38 | getCartList(){
39 | this.$http.post('/users/cartList').then(result=>{
40 | let res = result.data;
41 | this.cartList = res.result;
42 | console.log(res);
43 | })
44 | }
45 | }
46 | }
47 | ```
48 |
49 | ## 后端接口
50 | ```
51 | router.post("/cartList", function(req, res, next) {
52 | let userId = req.cookies.userId;
53 | User.findOne({ userId: userId }, function(err, doc) {
54 | if (err) { res.json({ status: '1', msg: err.message, result: '' }) } else {
55 | res.json({
56 | status: 0,
57 | msg: '',
58 | result: doc.cartList
59 | })
60 | }
61 | })
62 | })
63 | ```
--------------------------------------------------------------------------------
/note/24.调试问题的框架.md:
--------------------------------------------------------------------------------
1 | 调试问题的框架:
2 | 发生什么问题?怎么做是最好的解决方案?
3 |
4 | 404
5 |
6 | 先看你的错误信息
7 | 如果是英文,把他翻译出来,必须把报错信息,搞懂
8 | 提取里面语法错误,或者路径信息 关键词,http请求错误
9 |
10 | 如果没有报错,数据还没有,去检查network的 xhr 请求的api
11 | 到底有没有数据
12 | 没有数据?
13 | 测试api
14 | 排查是否真正的输出
15 | 去检查数据库
16 | 前端看报错,确定是否是后端问题,
17 | 如果后端有问题,去排查,有可能是数据库问题
18 | 要经常查看 node 服务器的控制台 打印的日志
19 |
--------------------------------------------------------------------------------
/note/25.购物车列表里面的商品数量增加和减少,和是否被选中.md:
--------------------------------------------------------------------------------
1 |
2 | #购物车列表里面的商品数量增加和减少,和是否被选中
3 | ## 打算更新用户里面的商品?
4 | 要根据用户id 和商品id 确定哪个用户的商品
5 | 然后更新里面的数据
6 |
7 | ## api接口
8 | 接收参数:
9 | 商品id
10 | 商品数量
11 |
12 | ### api接口代码实现
13 | update:
14 | 参数一:条件
15 | 参数二:要设置的字段
16 | 参数三:回调函数
17 |
18 | 参数二:设置方式 cartList.$.productNum
19 | cartList 是user里面的对象
20 | $ 固定写法
21 | productNum 是要更新的字段, user.cartList 的属性
22 | ```
23 | router.post('/cartEdit', function(req, res, next) {
24 | let userId = req.cookies.userId,
25 | productId = req.body.productId,
26 | productNum = req.body.productNum;
27 |
28 |
29 | User.update({ 'userId': userId, "cartList.productId": productId }, {
30 | "cartList.$.productNum": productNum
31 | }, function(err, doc) {
32 | if (err) { res.json({ status: '1', msg: err.message, result: '' }) } else {
33 | res.json({
34 | status: 0,
35 | msg: '',
36 | result: '修改购物车商品成功'
37 | })
38 | }
39 | })
40 |
41 | })
42 | ```
43 |
44 | ### dom 实现
45 |
46 | ```
47 |
48 |
49 |
52 |
53 |
54 |
55 |
-
56 |
{{item.productNum}}
57 |
+
58 |
59 |
60 |
61 | editCart(flag,item){
62 | if(flag == 'minu'){
63 | if(item.productNum <= 1){
64 | return;
65 | }
66 | item.productNum --;
67 | }else if(flag == 'add'){
68 | item.productNum ++;
69 | }else{
70 | item.checked = item.checked == '1' ? 0 : 1;
71 | }
72 | this.$http.post('/users/cartEdit',{
73 | productId:item.productId,
74 | productNum:item.productNum
75 | }).then(result=>{
76 | console.log(result);
77 | // alert(result.data.result);
78 | })
79 |
80 | }
81 | ```
--------------------------------------------------------------------------------
/note/26.全选,全不选.md:
--------------------------------------------------------------------------------
1 | #切换全选,和全不选
2 | ## 当购物车里面的数据,差一个没全部选中的时候
3 | 这个时候,点击按钮,就全部选中
4 |
5 | 在全部选中的时候,点击按钮就全部没有选中,(取反)
6 |
7 | flag:来判断以上的条件
8 | return 布尔值
9 |
10 | 需要判断当前选中了多少
11 | 当前选中的商品 和 购物车里面的所有商品对比
12 |
13 | ## 代码实现
14 | 因为需要实时计算,写在computed里面
15 | ```
16 |
17 | computed:{
18 | // 购物车被选中的数量
19 | checkedCount(){
20 | var i = 0;
21 | this.cartList.forEach(item=>{
22 | if(item.checked == '1') i++;
23 | })
24 | return i;
25 | },
26 | // 判断是否全选
27 | checkedAllFlag(){
28 | // 当前选中的商品 和 购物车里面的所有商品对比
29 | return this.checkedCount == this.cartList.length;
30 | }
31 | },
32 |
33 |
34 | ```
35 |
36 | ```
37 | toggleCheckAll(){
38 | let flag = !this.checkedAllFlag;
39 |
40 | this.cartList.forEach(item=>{
41 | item.checked = flag ? 1 : 0;
42 | })
43 |
44 | this.$http.post('/users/editCheckAll',{checkAll:this.checkedAllFlag}).then(res=>{
45 | console.log(res);
46 | })
47 | }
48 | ```
--------------------------------------------------------------------------------
/note/27.总价格实时变化.md:
--------------------------------------------------------------------------------
1 | #总价格实时变化
2 |
3 | ```
4 |
5 | Item total: {{totalPrice}}
6 |
7 |
8 | totalPrice(){
9 | let money = 0;
10 | this.cartList.forEach(item=>{
11 | if(item.checked == '1'){
12 | money += item.salePrice * item.productNum
13 | }
14 | })
15 | return money;
16 | }
17 | ```
--------------------------------------------------------------------------------
/note/28.商品删除.md:
--------------------------------------------------------------------------------
1 | #商品删除
2 | 在生产环境中,真正的删除,就是改变了一个状态
3 | 原则性不允许删除任何东西
--------------------------------------------------------------------------------
/note/29.封装全局模态框组件.购物车判断登录与未登录情况的弹出不同模态框.md:
--------------------------------------------------------------------------------
1 | ## 29.封装全局模态框组件
2 | 把静态写好的组件放在 Modal.vue组件里面
3 | 代码如下
4 |
5 | ## 通过props父子组件传惨,通过slot定义插槽
6 | ```
7 |
8 |
9 |
10 |
11 |
12 |
信息展示
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 | ```
36 |
37 | ## 在父组件里面使用
38 |
39 | ```
40 | import Modal from '@/components/Modal'
41 |
42 |
43 | components:{
44 | NavHeader,
45 | NavFooter,
46 | NavBread,
47 | Modal //在这加上
48 | },
49 |
50 | 在打他里面加上
51 | data(){
52 | return{
53 | mdShowCart:false,
54 | mdShow:false,
55 | }
56 | }
57 |
58 | ```
59 |
60 | ```
61 |
62 |
63 | 请先登录,否则无法加入购物车
64 |
67 |
68 |
69 |
70 |
71 | 加入购物车成功
72 |
73 |
继续购物
74 |
查看购物车列表
75 |
76 |
77 | ```
78 |
79 | ## 在业务层面操作
80 | ```
81 | addCart(productId){
82 | axios.post('/goods/addCart',{productId:productId}).then(res=>{
83 | console.log(res.data);
84 | if(res.data.status == 1){
85 | this.mdShow = true; //判断一下当未登录的情况下把未登录的模态框弹出
86 | }else{
87 | }
88 | })
89 | }
90 | ```
--------------------------------------------------------------------------------
/note/30.在购物车列表页面去结账.md:
--------------------------------------------------------------------------------
1 | ##30.在购物车列表页面去结账
2 |
3 | 点击结账按钮,跳转到地址页面
4 | 之前要判断一下是否有选中的商品
5 | ```
6 | checkout(){
7 | if(this.checkedCount > 0){
8 | this.$router.push({
9 | path:'/address'
10 | })
11 | }else{
12 | alert('购物车,必须有选中的商品!才能去结账')
13 | }
14 | }
15 | ```
--------------------------------------------------------------------------------
/note/31.地址页面.md:
--------------------------------------------------------------------------------
1 | ## 地址页面
2 | 创建组件,写路由
3 | ## 遍历地址信息
4 | api接口
5 | 返回地址信息
6 | ```
7 | router.get('/addressList', function(req, res, next) {
8 | var userId = req.cookies.userId;
9 | User.findOne({ userId: userId }, function(err, doc) {
10 | if (err) {
11 | res.json({ status: 1, msg: err.message, result: '' })
12 | } else {
13 | res.json({ status: 0, msg: '', result: doc.addressList })
14 | }
15 | })
16 | })
17 | ```
18 |
19 | ## vue前台遍历
20 | ```
21 | methods:{
22 | getAddressList(){
23 | this.$http.get('/users/addressList').then(res=>{
24 | this.addressList = res.data.result;
25 | })
26 | }
27 | }
28 | ```
--------------------------------------------------------------------------------
/note/32.设置默认地址.md:
--------------------------------------------------------------------------------
1 | #设置默认地址
2 |
3 | api 接口
4 | ```
5 | router.post("/setDefault", function(req, res, next) {
6 | var userId = req.cookies.userId,
7 | addressId = req.body.addressId;
8 | if (!addressId) {
9 | res.json({
10 | status: '1003',
11 | msg: 'addressId Is null'
12 | })
13 | } else {
14 | User.findOne({ userId: userId }, function(err, doc) {
15 | var addressList = doc.addressList;
16 | addressList.forEach(item => {
17 | if (item.addressId = addressId) {
18 | item.isDefault = true;
19 | } else {
20 | item.isDefault = false;
21 | }
22 | })
23 |
24 | doc.save(function(err1, doc1) {
25 | if (err1) {
26 | res.json({
27 | status: '1',
28 | msg: err.message,
29 | result: ''
30 | })
31 | } else {
32 | res.json({
33 | status: '0',
34 | msg: '',
35 | result: doc1
36 | })
37 | }
38 | })
39 | })
40 | }
41 | })
42 | ```
43 |
44 | vue 前台实现
45 | ```
46 | setDefault(addressId){
47 | this.$http.post('/users/setDefault',{
48 | addressId:addressId
49 | }).then(res=>{
50 | if(res.data.status == '0'){
51 | this.getAddressList();
52 | }
53 | })
54 | }
55 | ```
--------------------------------------------------------------------------------
/note/33.订单确认页面.md:
--------------------------------------------------------------------------------
1 | #订单确认页面
2 |
3 | ```
4 | methods:{
5 | init(){
6 | this.$http.post('/users/cartList').then(response=>{
7 | let res = response.data;
8 | this.cartList = res.result;
9 |
10 | this.cartList.forEach(item=>{
11 | console.log(item);
12 | if(item.checked == '1'){
13 | this.subTotal += item.productNum * item.salePrice
14 | }
15 | })
16 |
17 | this.orderTotal = this.subTotal + this.shipping + this.tax - this.discount;
18 | })
19 | }
20 | }
21 | ```
--------------------------------------------------------------------------------
/note/34.项目上线.md:
--------------------------------------------------------------------------------
1 | ## 选购服务器
2 | 板瓦工 推荐1g以上内存
3 | https://www.bwh1.net/
4 |
5 | 阿里云
6 | https://common-buy.aliyun.com/?spm=5176.10003347.843204.1.Ql3ciJ&commodityCode=swas&request=undefined#/buy
7 |
8 |
9 | 推荐阿里云
10 | https://promotion.aliyun.com/ntms/act/qwbk.html?open_id=4dc9ecb7-9a7d-4800-a51a-a659a1ebb2ca-511180874&open_cid=187
11 |
12 | https://cloud.digitalocean.com/login
13 |
14 | https://www.vultr.com/
15 | https://www.vultr.com/pricing/
16 |
17 | ## 服务器系统选择
18 | Ubuntu
19 |
20 | ## 搭建环境
21 | nginx
22 | php fpm
23 | mysql
24 | mongodb
25 | nodejs
26 |
27 | pm2
28 |
29 | ## 绑定域名
30 | 子域名
31 |
32 | gitlab.com
33 |
34 |
35 | 野狗
36 |
37 |
38 | ## 做哪些事情
39 | bbs.shudong.wang
40 |
41 | wordpress
42 |
43 | hexo
44 |
45 | 今天把服务器搞定
46 |
47 | ## 域名注册
48 | 优先选购:
49 | .com .net .cn
50 |
51 | 位数要短一些
52 | 其它后缀尽量有意义
53 |
54 | vnshop.cn
55 |
56 | 国内的服务器必须备案
57 |
58 | 最好是国外的
59 | 或香港的
60 | 如果选国外的最好选择日本
61 |
62 | 优先选择香港
--------------------------------------------------------------------------------
/note/35.服务器购买.md:
--------------------------------------------------------------------------------
1 | ## https://segmentfault.com/a/1190000011772497
2 | #vps服务器购买操作
3 | ## 搭建vue + node + mongodb 项目需要购买服务器
4 | ## 服务器购买后最好选择Ubuntu系统(接下来的项目上线教程都是按照Ubuntu系统来讲)
5 | ### 注意点:
6 | >千万别绑定自己的信用卡,绑定后打算解绑需要另一张信用卡来解绑,好像国外都是这么干的
7 | ### 结账方式选择:
8 | 有支付宝的最好选择支付宝
9 | 没有支付宝的话,就选择PayPal(支持大部分银联卡)
10 |
11 | ## 选购服务器
12 | ### 支付方式支持 支付宝结账比较方便,同时也支持PayPal
13 | ## 选购搬瓦工(支持 ss 价格实惠)
14 | 板瓦工 推荐1g以上内存(因为node服务器消耗内存比较大)
15 | [bwh1](https://www.bwh1.net/)
16 | ### 注册账号的时候,需要填写一些信息,最后需要的验证码需要科学上网才能出现验证码图片,所以正确填写完验证码之后,才能注册,才能购买
17 |
18 | 
19 |
20 | ## 选购阿里云
21 | ### 注意:千万别选择window系统(如果不是必须window的话)
22 | ### 如果你选择了window系统,不能更换问Linux系统,解决办法:提交工单,去退货,然后重新购买
23 | > 如果你是学生,就去通过学生通道购买 9.9一个月
24 | 如果不是学生推荐一下链接
25 | https://common-buy.aliyun.com/?spm=5176.10003347.843204.1.Ql3ciJ&commodityCode=swas&request=undefined#/buy
26 |
27 | 如果你的域名没有备案,请买香港主机或其他国外主机
28 |
29 | ## 推荐阿里云(双十一搞活动)280一年
30 | https://promotion.aliyun.com/ntms/act/qwbk.html?open_id=4dc9ecb7-9a7d-4800-a51a-a659a1ebb2ca-511180874&open_cid=187
31 |
32 | ## 选购vultr
33 | ### 第一步注册账号
34 | ### 登录进去
35 | ### 注意点:
36 | >千万别绑定自己的信用卡,绑定后打算解绑需要另一张信用卡来解绑,好像国外都是这么干的
37 | ### 支付方式:
38 | 支持 PayPal (所有银联卡都支持)
39 |
40 | https://www.vultr.com/
41 | https://www.vultr.com/pricing/
42 | 
43 |
44 |
45 | ### 选择数字海洋 [digitalocean](https://www.digitalocean.com)
46 | >国外口碑不错
47 | > digitalocean 如果你有教育邮箱,就是edu结尾的邮箱, 可以去领100美金优惠券,这个查的很严,两个账号用一个支付方式,都使用了优惠券就回被查出来
48 | 优惠券两年后就不能用了
49 |
50 | #### 网址https://cloud.digitalocean.com/login
51 |
52 | ### 等大家买完后,接下来讲项目上线(敬请期待)
53 | ## 项目上线方式:
54 | ### 普通打包上传方式
55 | ### git webhooks pm2 自动化方式
56 | ### docker 方式
57 |
58 | #### 会不断优化此篇文章(请收藏)
59 | ## 下一篇文章(选购域名)
60 | ## 欢迎加入前端微信群,持续学习
61 | ![图片描述][1]
62 |
63 |
64 | [1]: /img/bVXyL8
--------------------------------------------------------------------------------
/note/36.域名购买.md:
--------------------------------------------------------------------------------
1 | ##域名购买
2 | ##域名厂商推荐
3 | > [阿里云](https://wanwang.aliyun.com/) (曾经万网) 推荐(备案比较方便)
4 | > [dnspod.cn](https://www.dnspod.cn/) (被腾讯收购了)
5 | > [新网](http://www.xinnet.com/) (被腾讯收购了)
6 | > [西部数码](http://west.cn/) (自营14年了,侧重搞域名交易的场所)
7 | > [百度域名注册](https://cloud.baidu.com/product/bcd.html)
8 | > [腾讯域名注册](https://dnspod.cloud.tencent.com/)
9 | ### 国外域名厂商
10 |
11 | > [狗爹](https://sg.godaddy.com/zh/tlds/gtld.aspx)
12 | ### 国外交易域名厂家
13 | > [sedo](sedo.com)
14 | > [park.io](park.io)
15 |
16 | ## 选购域名推荐
17 | 优先选择com
18 | 然后 net cn cc
19 | 如果上面没有你的选择可以找比较有意义的后缀
20 | shudong.wang 符合我的名字
21 | stark.wang
22 | vnshop.cn
23 | itnote.cn
24 |
25 | 原则性:好记,有意义
26 | 如果经济允许的话,可以选择一些比较短的新出的简短的后缀,比如vc cm cx
27 | 选择新出的后缀,两位的购买
28 | cx 两位的行情是 1000起步
29 | uv.cx 1200 目前行情,如果你可以的话
30 | chat
31 |
32 | ## 购买域名以阿里云为例子
33 |
--------------------------------------------------------------------------------
/note/36.连接阿里云工具.md:
--------------------------------------------------------------------------------
1 | ##完整比较去去这个连接
2 | https://segmentfault.com/a/1190000011775015
3 | ## 连接Linux工具
4 | putty (免费)
5 | xshell(收费)(推荐)教程使用xshell 操作
6 | ## 安装xshell
7 | [下载地址](http://www.netsarang.com/download/main.html)
8 | 官方的如果下载慢:推荐大家去360软件管家下载 或者百度助手
9 |
10 | ### 下载操作
11 | 
12 |
13 | ### 安装点击下一步,下一步,结束
14 |
15 | ### 使用方式
16 |
17 | 
18 |
19 | 
20 |
21 | > 名称:是自己随便填写的,以便区分自己的其它主机
22 | 主机:是自己购买的服务器ip
23 | >端口号:是自己购买的服务器端口号,一般默认是ssh 22 ,如果你买的国外主机,比如搬瓦工,会像你的邮箱发送几封邮件,其中一封,会标明有主机ip端口号 ,那个端口号需要在这填写,搬瓦工的端口号,不是22(切记)
24 |
25 | ### 例子:
26 | 
27 | ### 输入用户名和密码:
28 |
29 | 
30 | 如果你刚买的主机,一般管理员用root来登录
31 | 用户名是root
32 | 密码是自己设定的,如果是搬瓦工的话,邮箱会有这个信息
33 | ### 阿里云怎么找回或设置自己的密码
34 | 如果是阿里云的话需要
35 |
36 | 
37 |
38 | 
39 |
40 | 先停止这个服务器,然后
41 |
42 | 
43 |
44 |
45 |
46 | 
47 |
48 |
49 | 
50 |
51 | 等重置完密码之后,就把自己设定的密码,在这登录
52 |
53 | ### 搬瓦工怎么找回自己的密码
54 |
55 | 
56 |
57 | 进入控制面板的网址:https://kiwivm.64clouds.com/main.php
58 |
59 | ### 修改密码
60 | 改名密码之前先stop
61 | 
62 |
63 | #### 自定义设置密码
64 | 
65 | 如果这个不能用 请选择自动设置密码,下面图示
66 | #### 自动设置密码
67 |
68 | 
69 | 设置了之后,会出现一个密码,需要记住,只出现一次,一定要记住
70 |
71 | ##当我们把服务器账号密码都搞定,然后登录
72 |
73 |
74 | 
75 |
76 | 出现以下命令
77 | ```
78 | [root@iZ238uepsriZ ~]#
79 | ```
80 | root 是用户名
81 | iZ238uepsriZ 这个是主机名字
82 | ~ 是路径,波浪线代表家目录 家目录就是用户所在的目录
83 | ‘#’ 代码管理员权限操作
84 |
85 | 执行一些常用的shell
86 | ```
87 | pwd :当前所在的路径
88 | cd :切换路径
89 | ls :查看当前文件下面都有神马
90 | ll :是ls -l 的别名
91 | cp :复制
92 | mv :重命名,剪切
93 |
94 | ```
95 | ##接下来安装Nginx web环境
96 | 会安装以下环境:
97 | Nginx
98 | php
99 | mysql
100 | mongodb
101 | node
102 | pm2
103 | git
104 | docker
105 | ## 敬请期待后面文章
106 | ##(如需视频)欢迎加入前端持续学习
107 | ![图片描述][1]
108 |
109 |
110 | [1]: /img/bVXyL8
--------------------------------------------------------------------------------
/note/37.【全栈项目上线(vue+node+mongodb)】安装lnmp环境.md:
--------------------------------------------------------------------------------
1 | #37.【全栈项目上线(vue+node+mongodb)】安装lnmp环境
--------------------------------------------------------------------------------
/note/38.项目上线解决方案.md:
--------------------------------------------------------------------------------
1 | ##项目上线常用方案:
2 |
3 | ### 把本地的代码打包压缩一份上传到服务器,然后解压到相应地方
4 | > 把本地的代码压缩一下,然后上传到服务器
5 | ```
6 | npm run build
7 | ```
8 | > 生成一个dist 文件夹,把这个文件夹,压缩成zip格式的文件
9 | 然后通过xshell 上传到服务器
10 | #### 第一步:安装 lrzsz
11 |
12 | ```
13 | apt-get install lrzsz -y
14 | ```
15 |
16 | sz:将选定的文件发送到本地机器
17 | rz:运行该命令会弹出一个文件选择窗口,从本地选择文件上传到Linux服务器
18 | rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具,
19 |
20 | #### 第二步:把本地的项目文件通过rz上传到服务器
21 | 执行rz命令,然后跳出一个框,让你选择本地需要上传到服务器的文件。
22 | ```
23 | rz
24 | ```
25 | 在服务器哪执行的命令,就上传到哪去
26 |
27 | #### 第三步:移动到相应的位置解压文件
28 | 把上传的压缩包解压:
29 |
30 | ```
31 | unzip dist.zip
32 | ```
33 | 解压完之后,生成一个 dist文件夹
34 | 需要把这个文件夹里面的所有文件复制到 vn.itnote.cn文件夹里面去
35 |
36 | ```
37 | cp -r dist/* vn.itnote.cn
38 | ```
39 | > cp 是拷贝 -r 是深度拷贝,如果里面是文件,需要用 -r /* 代表把dist 文件夹里面的所有文件都拷贝 后面的vn.itnote.cn 文件夹,是要拷贝的目的地
40 |
41 | ### 从GitHub拉去到相应的地方
42 | ### 配置git webhooks 自动化上线
43 | ### 配置 pm2 自动化上线
44 | ### 使用docker 自动化上线
--------------------------------------------------------------------------------
/note/39.怎么在一台主机上面部署多个网站.md:
--------------------------------------------------------------------------------
1 | ## 怎么在一台主机上面部署多个网站
2 | ### 使用Nginx的虚拟化配置
3 | ### 操作步骤
4 | ### 第一步:执行 lnmp vhost add
5 | ```
6 | lnmp vhost add
7 | ```
8 | https://segmentfault.com/a/1190000011791001
--------------------------------------------------------------------------------
/note/40.nodejs服务上线.md:
--------------------------------------------------------------------------------
1 | 【全栈项目上线(vue+node+mongodb)】06.nodejs服务上线
--------------------------------------------------------------------------------
/note/41.homework.md:
--------------------------------------------------------------------------------
1 | 1.把概念理清
2 | nginx
3 | pm2
4 | Apache
5 | node
6 | express
7 | vue
8 | Ubuntu
9 | Linux
10 | git
11 | webhooks
12 |
13 | 2.把自己的项目上线 成功后留言到论坛
14 | http://bbs.shudong.wang/forum.php?mod=forumdisplay&fid=100
15 |
16 | 3.自己搭建的时候有问题提问到这里面来
17 |
18 | https://segmentfault.com/a/1190000011782975
19 |
20 | 4.每个人写一篇文章
21 | 发布到
22 | https://segmentfault.com/
--------------------------------------------------------------------------------
/note/42.项目上线使用webhooks.md:
--------------------------------------------------------------------------------
1 | ##项目上线
2 | ## github 和 打包上线,感觉比较繁琐
3 | > 每次更新完代码,手动push 到远程仓库,如果想让服务器的代码也同步的话,需要手动去服务器上面,拉取,编译,把编译后的代码复制需要的路径。
4 | ## 使用git webhooks 完美解决这个问题
5 | 详细笔记请移步
6 | https://segmentfault.com/a/1190000011808364
--------------------------------------------------------------------------------
/note/day.log.md:
--------------------------------------------------------------------------------
1 | 2017年10月23日 09:15:03
2 | day1:
3 | 组件拆分
4 | 请求mook数据
5 | 渲染列表
6 | day2:
7 | 图片懒加载
8 | vnshop server搭建好
9 | 配合mongodb
10 | 01.让学员把自己的商城项目提交到github的vnshop项目的issue方便查看
11 | 02.复习上周讲的商品组件
12 | 03.使用vue-lazyload插件实现图片懒加载
13 | 04.使用express脚手架生成,配置nodemon和supervisor方式启动修改后不需要重启node服务
14 | 05.使用express连接mongodb
15 | 07.使用express通过查询mongodb数据实现goods商品列表接口
16 | 08.使用vue请求server的goods的api,并且配置跨域成功访问
17 |
--------------------------------------------------------------------------------
/note/homework.md:
--------------------------------------------------------------------------------
1 | 2017年10月20日 17:09:13
2 | 1.先把当前的项目解决,跟着敲
3 | 提交到github上面
4 |
5 | 2.有时间与经历研究一下这个项目
6 | https://github.com/vueguide/vue-toutiao
7 |
8 | 2017年10月26日17:24:45
9 | 1.显示一个默认地址
10 | 2.点击一个地址被选中
11 | 3.点击下一步,确认订单页面
12 | 4.确认订单页面实现,数据也实现渲染
13 |
14 |
15 | 2017年11月1日17:33:23
16 | https://github.com/itguide/-Api
17 |
18 | 把自己选的api提交
19 | https://github.com/itguide/item/issues
20 | 格式:
21 | api:api.shudong.wang
22 | ui link:shudong.wang
23 | category: shop
24 |
25 |
26 | 格式:
27 | FE10-城市+名字
28 | api:api.shudong.wang
29 | ui link:shudong.wang
30 | category: shop
--------------------------------------------------------------------------------
/note/item.guide.md:
--------------------------------------------------------------------------------
1 | 组件化
2 | 复用
3 | 降低耦合(解耦)
--------------------------------------------------------------------------------
/note/分析需求.md:
--------------------------------------------------------------------------------
1 |
2 | 需求1:价格排序:
3 | 点击页面的按钮从大到小排序,然后再点击从小到大排序
4 |
5 | 前台:
6 | 点击页面按钮 让下面的产品安装价格排序
7 | 需要一个api
8 | 同过两次点击,切换正序和倒序 ,给后端传一个参数
9 |
10 | 开始开发:
11 | 先思考,设计的时间越长,需要修改的时间越短
12 | 请求接口的时候,携带参数,1 -1
13 | 这个怎么来的,通过点击按钮来的
14 | 每次点击按钮 都会改变一个变量值
15 | 变量值默认是 1
16 |
17 | 拿到接口:
18 | postman 测试
19 |
20 | 后端api:
21 | baseurl: localhost:3000
22 | 1:表示接口正常
23 | 0:表示接口不正常
24 |
25 | http 状态码
26 | 200 ok
27 | 400 表示错误
28 |
29 | 拿到需求:
30 | 规定两个参数,来判断输出的结果
31 |
32 | 参数:sort
33 |
34 | api:/goods/list?sort=-1
35 | 接受两个参数:
36 | 接收: 1参数
37 | /goods/list?sort=1
38 | 返回数据:
39 | status:1
40 | msg:
41 | result:
42 | 商品正序数据
43 | 接收:-1 参数
44 | /goods/list?sort=-1
45 | 返回数据:商品倒序
46 |
47 |
48 |
49 | 开始开发:
50 | 在teambition 新建任务
51 | 第一步:从master 检出 最新代码
52 | git pull origin master
53 |
54 | 第二步:git 创建新的分支
55 | git checkout -b sort
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/note/常用工具.md:
--------------------------------------------------------------------------------
1 | json 插件
2 | https://chrome.google.com/webstore/search/json?utm_source=chrome-ntp-icon
3 |
4 |
--------------------------------------------------------------------------------
/note/思想.md:
--------------------------------------------------------------------------------
1 | 现阶段:
2 | 每天是用时间换金钱
3 | 受限制
4 |
5 | 每一天 :要达到最高的效率
6 |
7 |
8 | 下一个阶段:
9 | 被动收入
10 | 让你的一份时间,可以出售多份
11 |
12 | 要创建自己的管道
13 |
14 |
--------------------------------------------------------------------------------
/note/接口文档.md:
--------------------------------------------------------------------------------
1 | v1:输出所有数据
2 | // router.get('/list', function(req, res, next) {
3 | // Goods.find({}, function(err, doc) {
4 | // if (err) {
5 | // res.json({ status: "1", msg: err.message })
6 | // } else {
7 | // res.json({ status: '0', msg: '', result: doc })
8 | // }
9 | // })
10 | // })
--------------------------------------------------------------------------------
/note/推荐工具.md:
--------------------------------------------------------------------------------
1 | https://sentry.io/welcome/
--------------------------------------------------------------------------------
/note/项目需求.md:
--------------------------------------------------------------------------------
1 | pm 产品经理
2 |
3 | 需求:
4 |
5 | 价格排序:
6 | 点击页面的按钮从大到小排序,然后再点击从小到大排序
--------------------------------------------------------------------------------
/note01/01.技术栈.md:
--------------------------------------------------------------------------------
1 | 一个中小型企业架构:
2 |
3 | 前后分离
4 |
5 | 前端:
6 | vuejs
7 | vue插件
8 | axios
9 |
10 | 后端:
11 | express
12 | 中间件
13 | jwt
14 | passport
15 |
16 | 数据库:
17 | mongodb
18 | redis:做缓存session 用户登陆信息
19 |
20 | 服务端:
21 | Linux :ubuntu + pm2 + git webhook
22 |
23 | web服务:
24 | nginx
25 | 做反向代理
26 |
27 | docker
28 |
29 |
30 | 域名:
31 | 都买一个自己的域名
32 | .com .net .cn
33 |
34 | vnshop.cn
35 |
36 | shudong.wang
37 |
38 | 课程规划:
39 | 第一个阶段:
40 | 使用express 简单api
41 | vue把api查出来显示在页面
42 |
43 |
44 | 模块:
45 | 商品列表
46 | 按照价格范围筛选
47 | 安装价格高低筛选
48 | 登陆 :
49 | 第一个阶段使用cookie
50 | 之后会增加jwt权限验证
51 | 购物车
52 | 购物车列表
53 | 加减数量实时计算价格
54 | 结账
55 | 结账页面
56 | 地址:
57 | 选择地址
58 | 提交订单:
59 | 生成订单号
60 | 订单信息
61 | 上线:
62 | 使用nginx反向代理
63 | 在一台ubuntu上 搭建node服务器 mongodb数据库服务
64 | vuejs上线
65 | pm2启动node
66 | node 是单线程,一旦发生错误,就会崩溃 挂掉
67 | pm2可以管理线程,自动重启
68 |
69 | web githook :
70 | 这个是git 钩子
71 | 当我们把代码提交到github
72 | 需要去服务器把代码拉取下拉
73 | web githook 可以自动监听这个push 事件
74 | 自动把代码拉取下来
75 |
76 | docker :
77 | 集装箱容器:
78 | 把你的环境都集成在一块
79 | 每次你同事来了,或新配置一个环境
80 | 几条命令就可以搞定
81 | 上线发现不对,可以立即回滚
82 |
83 | 时间:
84 | 五天就放假了
85 | 十一回来五天
86 |
87 | 购物车删除
88 | 地址
89 | 订单
90 |
91 | 周三,周四
92 | 上线(操作性挺强)
93 | 需要每个人买一台服务器
94 | ubuntu
95 | centos
96 | 搭建
97 | mongodb
98 | nodejs
99 | vuejs
100 |
101 | docker
102 |
103 | vuex 周二
104 |
105 | 讲一下简历 周五
106 | 项目方面
107 | 工作流程
108 |
109 | 模拟面试
110 | 面试题串讲
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/note01/02.项目结构.md:
--------------------------------------------------------------------------------
1 | client
2 | vue
3 | server
4 | express
5 |
6 | mkdir -p client server
7 |
--------------------------------------------------------------------------------
/note01/03.项目初始化.md:
--------------------------------------------------------------------------------
1 |
2 | 初始化项目:
3 | vue
4 | vue init webpack client
5 |
6 | 把静态文件拉取下拉:
7 | https://github.com/itguide/shop-static.git
8 |
9 | git clone https://github.com/itguide/shop-static.git
10 |
11 |
12 | 协作工具
13 | git
14 | teambition
15 | pubu
16 |
17 | ui:
18 |
19 | 后端还没有给ui的时候怎么办?
20 | 自己县模拟数据,提前和后端约定好接口的规格,然后自己使用mock模拟数据
21 | easy-mock.com
22 | 准备数据
23 | http://easy-mock.com/mock/59664d4d58618039284c7710/example/goods/list
24 |
25 |
--------------------------------------------------------------------------------
/note01/04.组件.md:
--------------------------------------------------------------------------------
1 | 如果组件的名字和变量的名字一致,就直接写,想改变名字就写成这种对象的方式
2 | HeadNav,
3 | 'stark':NavBread,
4 | NavBread
--------------------------------------------------------------------------------
/note01/05.懒加载图片.md:
--------------------------------------------------------------------------------
1 | 懒加载图片使用vue插件
2 |
3 | vue-lazyload
4 |
5 | 使用方式
6 | ```
7 | import VueLazyLoad from 'vue-lazyload'
8 |
9 | Vue.use(VueLazyLoad, {
10 | loading: '/static/img/ok-2.png'; //添加默认的图片
11 | })
12 | ```
--------------------------------------------------------------------------------
/note01/06.利用本地的vue项目里面express.模拟数据.md:
--------------------------------------------------------------------------------
1 | 在mock 里面创建一个数据文件
2 |
3 | var app = express()
4 | var compiler = webpack(webpackConfig)
5 | var router = express.Router();
6 | var goodsList = require('../mock/goods.json');
7 |
8 | router.get("/goods", function(req, res, next) {
9 | res.json(goodsList);
10 | })
11 |
12 | app.use(router);
--------------------------------------------------------------------------------
/note01/07.使用express-generator生成项目.md:
--------------------------------------------------------------------------------
1 | npm i express-generator -g
2 |
3 | express server
4 |
5 |
6 | https://github.com/7fe/guide/blob/master/nodejs/mongodb/note/mongodb%20guide.pdf
--------------------------------------------------------------------------------
/note01/08.前端与后端交互的介质.md:
--------------------------------------------------------------------------------
1 | json xml
2 |
3 | xml
4 |
5 |
6 | George
7 | John
8 | Reminder
9 | Don't forget the meeting!
10 |
--------------------------------------------------------------------------------
/note01/09.跨域.md:
--------------------------------------------------------------------------------
1 | Failed to load http://localhost:3000/goods/list: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
2 |
3 |
--------------------------------------------------------------------------------
/note01/10.价格排序.md:
--------------------------------------------------------------------------------
1 | 当我点击按钮的时候,要不就是按照价格从大到小,要不不小到达
2 |
3 | 前端:
4 | 点击安装触发一个事件,访问一个接口
5 | 每次点击携带,排序参数
6 | 后端:
7 | 通过前端传过来的参数,写业务逻辑,返回前端需要的排序数据
8 |
9 | 业务逻辑:
10 | 业务:就是老板交给你的任务
11 | 根据需求写的一些逻辑
12 |
13 | MongoDB sort()方法
14 | 在MongoDB中使用使用sort()方法对数据进行排序,sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
15 | 语法
16 | sort()方法基本语法如下所示:
17 | >db.COLLECTION_NAME.find()
18 |
19 |
20 | ```
21 | router.get("/list", function(req, res, next) {
22 | let sort = req.param('sort'); 接收前端请求的参数
23 | let goodModel = Goods.find({}).sort({ 'salePrice': sort });
24 | 执行按照什么排序
25 |
26 | goodModel.exec({}, function(err, doc) { 执行最后的结果
27 | res.json({ status: 0, result: doc })
28 | })
29 | })
30 | ```
--------------------------------------------------------------------------------
/note01/11.按照价格区间筛选商品.md:
--------------------------------------------------------------------------------
1 | 按照价格区间筛选商品
2 | 接口:
3 | 参数:
4 | 范围:
5 | all 所有
6 | 0 : 0 -100
7 | 1: 100 -500
8 | 2: 500 -1000
9 |
10 | 直接两个参数:
11 | 开始价格 - 结束价格
12 |
13 |
14 | 前端:
15 | 点击价格区间的按钮
16 | 商品重新渲染
17 |
18 |
19 | ```
20 | MongoDB 条件操作符
21 |
22 | 描述
23 | 条件操作符用于比较两个表达式并从mongoDB集合中获取数据。
24 | 在本章节中,我们将讨论如何在MongoDB中使用条件操作符。
25 | MongoDB中条件操作符有:
26 | (>) 大于 - $gt
27 | (<) 小于 - $lt
28 | (>=) 大于等于 - $gte
29 | (<= ) 小于等于 - $lte
30 | 我们使用的数据库名称为"runoob" 我们的集合名称为"col",以下为我们插入的数据。
31 | 为了方便测试,我们可以先使用以下命令清空集合 "col" 的数据:
32 | db.col.remove({})
33 |
34 |
35 | db.col.find({"likes" : {$gt : 100}})
36 |
37 | Select * from col where likes > 100;
38 | ```
--------------------------------------------------------------------------------
/note01/12.商品分页,瀑布流,下拉加载.md:
--------------------------------------------------------------------------------
1 | 前端:
2 | 当用户打开首页的时候显示8条,当用户滚动屏幕到显示的商品边缘,然后加载新的数据。
3 |
4 | 实现:
5 | 检测用户滚动商品边缘,请求下一页的api,然后写入到页面
6 |
7 | 代码实现:
8 | infiniteScroll
9 | vue-infinite-scroll
10 |
11 | npm install vue-infinite-scroll --save
12 |
13 | 在页面里面使用
14 | 在 main.js
15 |
16 | import infiniteScroll from 'vue-infinite-scroll'
17 | Vue.use(infiniteScroll)
18 |
19 | 使用方式:
20 | https://www.npmjs.com/package/vue-infinite-scroll
21 |
22 | ```
23 |
24 |
25 | ...
26 |
27 |
28 | v-infinite-scroll="loadMore" 当页面触发到底部的时候 执行这个函数
29 | infinite-scroll-disabled="busy" 判断当滚动满足条件后是否执行loadMore函数
30 |
31 | infinite-scroll-distance="10" 距离底部多远然后执行loadMore
32 |
33 |
34 |
35 | var count = 0;
36 |
37 | new Vue({
38 | el: '#app',
39 | data: {
40 | data: [],
41 | busy: false
42 | },
43 | methods: {
44 | loadMore: function() {
45 | this.busy = true;
46 |
47 | setTimeout(() => {
48 | for (var i = 0, j = 10; i < j; i++) {
49 | this.data.push({ name: count++ });
50 | }
51 | this.busy = false;
52 | }, 1000);
53 | }
54 | }
55 | });
56 | ```
57 |
58 |
59 | ```
60 | getGoods(flag){
61 | let sort = this.sortFlag ? 1 : -1;
62 | let param = {
63 | sort:sort,
64 | priceLevel:this.priceChecked,
65 | page:this.page,
66 | pagesize:this.pagesize
67 | }
68 | axios.get('/goods/list',{params:param}).then(result=>{
69 | let res = result.data;
70 | // this.list= res.data.result;
71 | if(flag){ //判断是否通过分页请求
72 | // 分页的数据追加到这个list里面
73 | this.list = this.list.concat(res.result);
74 |
75 | // 判断当数据加载完了,让数据截停
76 | console.log(res.result.length);
77 | if(res.result.length == 0){
78 | this.busy = true;
79 | console.log(this.busy);
80 | }else{
81 | this.busy = false;
82 | }
83 | }else{
84 | // 第一次请求
85 | this.list = res.result;
86 | this.busy = false;
87 | }
88 | console.log(res.result);
89 | })
90 | },
91 |
92 | loadMore: function() {
93 | this.busy = true;
94 | setTimeout(() => {
95 | // console.log(1111);
96 | this.page++;
97 | this.getGoods(true);
98 | }, 500);
99 | }
100 | ```
101 | 后端:
102 | api:需要两个参数
103 | page:第几页
104 | prepage: 一页显示几条
105 |
--------------------------------------------------------------------------------
/note01/13.解决node修改完重启问题.md:
--------------------------------------------------------------------------------
1 |
2 | 使用方式1
3 | npm i supervisor -g
4 | supervisor bin/www
5 |
6 | 方式二 nodemon cross-env
7 |
8 | npm i cross-env nodemon -D
9 |
10 | 在package里面配置
11 | "start": "cross-env NODE_ENV=development ./node_modules/.bin/nodemon ./bin/www"
12 |
13 |
14 | 方式三
15 | pm2
16 |
--------------------------------------------------------------------------------
/note01/14.加入购物车.md:
--------------------------------------------------------------------------------
1 | 业务逻辑
2 |
3 | 点击加入购物车的时候,把商品id传给api,然后在购物列表展示出来
4 |
5 | api:
6 | 接收商品
7 | goods_id
8 | userid
9 |
10 | 查询用哪个用户,确定好用户
11 | 通过商品id去数据库查询,把商品的信息查出来,
12 | 此时去查询这个商品是否存在于用户购物车列表里面
13 | 如果存在则商品数量加一,不存在把整个商品信息存到里面
14 | 然后存到这个用户里面
15 |
16 |
17 |
--------------------------------------------------------------------------------
/note01/15.mongoose.md:
--------------------------------------------------------------------------------
1 | https://segmentfault.com/a/1190000010688972
2 |
3 |
4 | 名词解释
5 | Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力
6 | Model: 由Schema编译而成的假想(fancy)构造器,具有抽象属性和行为。Model的每一个实例(instance)就是一个document。document可以保存到数据库和从数据库返回。
7 | Instance: 由Model创建的实例。
--------------------------------------------------------------------------------
/note01/16.用户登陆.md:
--------------------------------------------------------------------------------
1 | 前端:点击登陆按钮,把用户的用户名和密码传到后端,到用户表里面去查询。
2 | 如果有这个用户,这个小点点,那个名字就变成用户名,
3 |
4 | 总结 :
5 | 给后端接口传
6 | 用户名
7 | 密码
8 | 返回结果:
9 | 登陆成功
10 | 登陆的信息
11 | 登录失败
12 | 失败的提示信息
13 |
14 |
15 | 后端:
16 | 接收两个参数
17 | 参数1:用户名
18 | 参数2: 密码
19 |
20 | 业务逻辑:
21 | 先把用户名去数据库查询,如果有,
22 | 去验证密码
23 | 验证密码
24 | 正确:
25 | 验证验证码
26 | 错误:
27 | 返回提示
28 | 如果没有
29 | 返回用户名不存在
30 |
31 | 如果上面验证成功
32 | 需要记录一下用户的登陆状态
33 | session
34 | 存在服务端
35 | 比较安全
36 |
37 | 占用服务器空间
38 | redis memcache
39 | 数据库 高速缓存
40 | cookie
41 | 存在本地
42 | 不安全
43 |
44 |
45 | 密码验证:
46 | md5(md5 + 随机数)
47 |
48 | md5不可逆
49 | 123456
50 | 34576asaddsadaslsalasd
51 |
52 | sha1
53 | base64
54 |
55 |
--------------------------------------------------------------------------------
/note01/19.在vue中怎么优雅的配置本地代理.md:
--------------------------------------------------------------------------------
1 | ```
2 | proxyTable: {
3 | '/goods/**': {
4 | target: 'http://localhost:3000'
5 | },
6 | '/users/**': {
7 | target: 'http://localhost:3000'
8 | },
9 | },
10 | ```
11 | 这样有个弊端
12 | 每次开发的时候都需要配置
13 | 万一 vue 的路由也是 goods users 就会产生矛盾
14 |
15 | 理想方式
16 | 配置一个路由,尽量避免和vue路由冲突
17 |
18 | 配置
19 | /api/**
20 |
21 | 每次在路由里面
22 | get('/api/users/login')
23 | get('/api/users/logout')
24 | get('/api/goods/list')
25 |
26 |
27 | get('/v1/goods/list')
28 |
29 |
30 | 最理想的方式
31 | get('/users/login)
32 |
33 | target: http://localhost:3000/users/login
34 |
35 |
36 | Axios.defaults.baseURL = apiConfig.baseUrl;
37 |
38 | 在每个使用axios请求的时候,自动加上api前缀
39 |
40 | 使用方式
41 | this.$http.get('users/login);
42 |
43 | 相当于访问:http://localhost:8080/api/users/login
44 | 代理
45 | 匹配到api
46 | 转发
47 | http://localhost:3000/users/login
48 |
49 | http://localhost:8080/api/goods/list
50 |
51 | http://localhost:3000/goods/list
52 |
53 | ```
54 | '/api/**': {
55 | target: 'http://localhost:3000',
56 | pathRewrite: {
57 | '^/api': '/'
58 | }
59 | }
60 | ```
--------------------------------------------------------------------------------
/note01/20.登陆拦截.md:
--------------------------------------------------------------------------------
1 | 当我们添加购物车的时候,检测用户是否登陆
2 |
3 | 如果没登陆,提示弹窗 目前没有登陆,请去登陆
4 |
5 |
--------------------------------------------------------------------------------
/note01/21.国庆作业.md:
--------------------------------------------------------------------------------
1 | 国庆回来要面临找工作
2 | 所以说呢,最好在国庆自己准备一个项目
3 | api记得提交到论坛 作业模块
4 |
5 | 可以在大群里面问
6 |
7 |
8 |
9 | 项目写累了刷刷面试题
10 | mianshiti.shudong.wanag
--------------------------------------------------------------------------------
/note01/23.全选.全不选.md:
--------------------------------------------------------------------------------
1 | 1.判断:当前购物车里面的选中的数量 == 购物车所有的商品数量
2 |
3 | 能判断出:目前是全部选中的状态
4 |
5 | 如果是这个状态的时候:此时点击按钮全不选中
6 | 否则取反
7 |
8 |
--------------------------------------------------------------------------------
/note01/24.登录流程.md:
--------------------------------------------------------------------------------
1 | 使用vue
2 |
3 | import Cookies from 'universal-cookie'
4 | const cookies = new Cookies()
5 | import { CookieDomain } from '../config.js'
6 | let cookieConfig = {}
7 | if(CookieDomain !== ''){
8 | cookieConfig = { domain: CookieDomain } //path:'/',maxAge:365*24*60*60
9 | }
10 |
11 | export function saveCookie(name,value) {
12 | cookies.set(name, value, cookieConfig)
13 | }
14 |
15 | export function getCookie(name) {
16 | return cookies.get(name)
17 | }
18 |
19 | export function removeCookie(name) {
20 | cookies.remove(name, cookieConfig)
21 | }
22 |
23 | export function signOut() {
24 | cookies.remove('token', cookieConfig)
25 | }
26 |
27 | export function isLogin() {
28 | console.log(!!cookies.get('token'),'islogin');
29 | return !!cookies.get('token')
30 | }
31 |
32 |
33 |
34 | router.beforeEach((to, from, next) => {
35 | // to.matched.some(
36 | // function(record){
37 | // console.log(record.meta)
38 | // }
39 | // )
40 | // console.log(to.matched.some(record => record.meta.requiresAuth))
41 | if (to.matched.some(record => record.meta.goTop)) {
42 | window.scroll(0, 0)
43 | }
44 |
45 | if (to.matched.some(record => record.meta.requiresAuth)) {
46 | // console.log(record.meta.requiresAuth)
47 | if (!isLogin()) {
48 | return next({path: '/pages/login'})
49 | }
50 | }
51 | if (to.matched.some(record => record.meta.requiresNotAuth)) {
52 | if (isLogin()) {
53 | return next({path: '/'})
54 | }
55 | }
56 | next()
57 | })
58 |
59 | export default router
60 |
--------------------------------------------------------------------------------
/note01/25.删除购物车.md:
--------------------------------------------------------------------------------
1 | 前端:
2 | 点击删除按钮把商品删除 并且页面立刻把这个商品删除掉
3 | 后端:
4 | 接受参数:
5 | 用户id
6 | 商品id
7 |
8 |
9 | ```
10 | // 操作的事情
11 | $pull: {
12 | 'cartList': {
13 | 'productId': productId
14 | }
15 | }
16 | ```
17 |
--------------------------------------------------------------------------------
/note01/26.设计数据库.md:
--------------------------------------------------------------------------------
1 | activity
2 | id
3 | user_id
4 | status
5 | 报名 10
6 | 预审核 15
7 | 审核 20
8 | 正常参加 30
9 | 迟到 40
10 | 爽约 50
11 |
12 | 参加活动
--------------------------------------------------------------------------------
/note01/27.支付生成订单号.md:
--------------------------------------------------------------------------------
1 | 前端:
2 | 后端:
3 | 接受参数:
4 | 用户id
5 | 地址id
6 | 订单总金额
7 |
8 |
9 |
10 | 订单号
11 | 订单总金额
12 | 地址信息
13 | 商品列表
14 | 订单状态
15 | 创建时间
16 |
--------------------------------------------------------------------------------
/note01/28.项目上线.md:
--------------------------------------------------------------------------------
1 | #### 选购服务器
2 | 板瓦工 推荐1g以上内存
3 | https://www.bwh1.net/
4 |
5 | 阿里云
6 | https://common-buy.aliyun.com/?spm=5176.10003347.843204.1.Ql3ciJ&commodityCode=swas&request=undefined#/buy
7 |
8 |
9 | 推荐阿里云
10 | https://promotion.aliyun.com/ntms/act/qwbk.html?open_id=4dc9ecb7-9a7d-4800-a51a-a659a1ebb2ca-511180874&open_cid=187
11 |
12 | https://cloud.digitalocean.com/login
13 |
14 | https://www.vultr.com/
15 | https://www.vultr.com/pricing/
16 |
17 | #### 搭建环境
18 | nginx
19 | php fpm
20 | mysql
21 | mongodb
22 | nodejs
23 |
24 | pm2
25 |
26 | #### 绑定域名
27 | 子域名
28 |
29 | gitlab.com
30 |
31 |
32 | 野狗
33 |
34 |
35 | #### 做哪些事情
36 | bbs.shudong.wang
37 |
38 | wordpress
39 |
40 | hexo
41 |
42 | 今天把服务器搞定
43 |
44 | #### 域名注册
45 | 优先选购:
46 | .com .net .cn
47 |
48 | 位数要短一些
49 | 其它后缀尽量有意义
50 |
51 | vnshop.cn
52 |
53 | 国内的服务器必须备案
54 |
55 | 最好是国外的
56 | 或香港的
57 | 如果选国外的最好选择日本
58 |
59 | 优先选择香港
--------------------------------------------------------------------------------
/note01/mongodb 安装连接方式.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/note01/mongodb 安装连接方式.pdf
--------------------------------------------------------------------------------
/note01/vue+express+mongodb项目上线 (1).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wsdo/vnshop/99b6458c1c4512148b9e44aff51abab5d813154a/note01/vue+express+mongodb项目上线 (1).pdf
--------------------------------------------------------------------------------
/note01/学习效率.md:
--------------------------------------------------------------------------------
1 | ## 使用云笔记
2 | 有道云
3 | 印象笔记
4 | 为之笔记
5 |
6 | 丢掉用纸和笔
7 | 辛辛苦苦记这么多,丢了什么都没了
8 | 还不利于 复制
9 |
10 | 平时使用 gtd 工具
11 | 番茄工作法
12 | 集中精力25分钟 休息5分钟
13 | 番茄时钟
14 |
15 | 小强升职记
16 | gtd
17 | get things done
18 |
19 | 使用mac
20 | mac pro
21 |
22 | 一定要配两个显示器
23 |
24 | 技术是吃饭的东西,一定要在这个上面下功夫
25 |
26 | 对于开发来说,命令行很方便
27 |
28 | 技术牛逼和你工作时间,关系并不是很大
29 |
30 | 最快的成长方式
31 |
32 | 三年工作经验的人都具备哪些技能
33 | Linux
34 | php java go
35 | node
36 | koa
37 | express
38 | thinkjs
39 | js
40 |
41 | 把自己的时间分块
42 | 第一个月去攻破哪个
43 | 把学习方法总结成框架
44 |
45 |
46 | 尤其是自己薪资
47 | 软实力
48 |
49 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # vnshop 商城
2 | > 如果帮助到你,那就点个star吧。
3 |
4 | 技术栈: vue mongodb node
5 | 
6 | > 课程视频,可以联系我
7 | https://shudong.wang/about
8 | ## 项目架构
9 | 前后分离
10 |
11 | 前端:
12 | 使用vue cli 脚手架方式搭建
13 |
14 | api:
15 | 使用node express框架搭建
16 |
17 | [课程地址](https://segmentfault.com/ls/1650000018979204)
18 |
19 | ## 项目目录
20 | cd vnshop
21 | mkdir -p client note server
22 |
23 | #### vnshop
24 | client #客户端代码,里面放的是vue项目工程文件
25 |
26 | note #搭建项目的详细笔记
27 |
28 | server #node express 代码
29 |
30 | ## 项目上线 视频上传到segmentfault 讲堂
31 |
32 | ## vnshop项目视频
33 | ### 详细内容
34 |
35 | 01.课程规划
36 | 02.github操作的几个场景
37 | 03.把本地的仓库提交到远程
38 | 04.vue初识.周边资源介绍
39 | 05.vue.helloworl.插值,双向绑定
40 | 06.指令.bind if
41 | 07.生命周期案例详细讲解
42 | 08.jq在生命周期函数里面的应用
43 | 10.v-show指令
44 | 11.模版和渲染
45 | 12.插槽基本使用,具名插槽,项目中应用场景
46 | 13.组件1,组件2,全局组件
47 | 14.v-on事件
48 | 15.动态组件
49 | 16.props
50 | 17.watch监听,深度监听
51 | 18.filter自定义过滤器
52 | 19.git 操作指南上课代码拉下拉,并且更新代码
53 | 20.自定义指令
54 | 21.自定义拖拽指令
55 | 22.vue-resource.get.post.jsonp.方式请求接口
56 | 23.axios 请求api的方式post 和 get区别
57 | 24.vue-cli项目初始化
58 | 25.git合并
59 | 26.解决问题的方式
60 | 27.vue项目目录的说明
61 | 28.vue.编译流程,webpack文件讲解
62 | 29.vue文件分析
63 | 30.vue项目入口文件分析
64 | 31.路由history,hash,默认激活样式,exact讲解
65 | 32.自定义全局激活样式,嵌套路由
66 | 33.路由重定向
67 | 34.路由传参
68 | 35.复习
69 | 36.成产环境和开发环境
70 | 37.解决问题的能力
71 | 38.在vue项目中使用axios访问接口,解决跨域问题
72 | 39.案例,获取知乎日报的信息,写在组件上,解决跨域,图片403问题
73 | 40.使用vue-axios方式访问api
74 | 41.vue-axios源码分析
75 | 42.vuex介绍
76 | 43.vuex在项目简单入门使用
77 | 44.vuex 提交 mutation paload传参
78 | 45.解决api请求权限问题
79 | 46.学习的方式
80 | 47.mutations 提交type类型
81 | 48.actions使用方式
82 | 49.getters使用方式
83 | 50.mapState,mapGetters,mapAction辅助函数使用
84 | 51.项目初始化
85 | 52.vue常见错误收集
86 |
87 | ## 全栈项目上线
88 | [课程地址](https://segmentfault.com/ls/1650000018979204)
89 |
90 | 01.购买流行的vps服务器教程
91 | 02.域名注册
92 | 03.域名注册商介绍godaddy.com域名注册,park.io等信息
93 | 04.利用xshell连接Linux Ubuntu系统详细操作方式
94 | 05.【全栈项目上线(vue+node+mongodb)】安装lnmp环境 nginx mysql php 环境
95 | 06.lnmp环境安装成功并且测试
96 | 07.nodejs环境安装
97 | 08.安装mongodb
98 | 09.mongodb安装测试执行mongodb shell命令
99 | 10.解决无法解析主机名字问题
100 | 11.mongodb通用解决方案
101 | 12.缩减版的安装php mysql Nginx node mongodb 6分钟搞定
102 | 13.部署项目的方式,介绍
103 | 14.怎么在一台服务器上部署多个站点
104 | 15.项目上线方案一上传文件解压文件实现
105 | 16.项目上线方案二从github拉取
106 | 17.项目上线完毕
107 | 18.负载均衡的概念
108 | 19.使用git webhooks 优雅的自动化上线vue项目(巨详细)
109 | 20.git webhooks 自动化上线
110 | 21.搭建博客系统WordPress
111 | 22.搭建hexo博客
112 |
113 |
114 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | test/unit/coverage
8 | test/e2e/reports
9 | selenium-debug.log
10 |
11 | # Editor directories and files
12 | .idea
13 | *.suo
14 | *.ntvs*
15 | *.njsproj
16 | *.sln
17 |
--------------------------------------------------------------------------------
/server/app.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var favicon = require('serve-favicon');
4 | var logger = require('morgan');
5 | var cookieParser = require('cookie-parser');
6 | var bodyParser = require('body-parser');
7 |
8 | var index = require('./routes/index');
9 | var users = require('./routes/users');
10 | var goods = require('./routes/goods');
11 |
12 | var app = express();
13 |
14 | // view engine setup
15 | app.set('views', path.join(__dirname, 'views'));
16 | app.set('view engine', 'jade');
17 |
18 | // uncomment after placing your favicon in /public
19 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
20 | app.use(logger('dev'));
21 | app.use(bodyParser.json());
22 | app.use(bodyParser.urlencoded({ extended: false }));
23 | app.use(cookieParser());
24 | app.use(express.static(path.join(__dirname, 'public')));
25 |
26 | // 访问拦截 就是所有访问都走这个逻辑
27 | app.use(function(req, res, next) {
28 | if (req.cookies.userId) {
29 | next();
30 | } else {
31 | if (
32 | req.originalUrl == '/users/login' ||
33 | req.path == '/goods/list'
34 | ) {
35 | next()
36 | } else {
37 | res.json({
38 | status: '1',
39 | msg: '当前用户未登录',
40 | result: ''
41 | })
42 | }
43 | }
44 | })
45 |
46 | app.use('/', index);
47 | app.use('/users', users);
48 | app.use('/goods', goods);
49 |
50 | // catch 404 and forward to error handler
51 | app.use(function(req, res, next) {
52 | var err = new Error('Not Found');
53 | err.status = 404;
54 | next(err);
55 | });
56 |
57 | // error handler
58 | app.use(function(err, req, res, next) {
59 | // set locals, only providing error in development
60 | res.locals.message = err.message;
61 | res.locals.error = req.app.get('env') === 'development' ? err : {};
62 |
63 | // render the error page
64 | res.status(err.status || 500);
65 | res.render('error');
66 | });
67 |
68 | module.exports = app;
--------------------------------------------------------------------------------
/server/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('server:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/server/models/goods.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | var Schema = mongoose.Schema;
3 | var productSchema = new Schema({
4 | "productId": String,
5 | "productName": String,
6 | "productPrice": Number,
7 | "productImage": String,
8 | "productNum": String,
9 | })
10 |
11 | module.exports = mongoose.model("Goods", productSchema)
--------------------------------------------------------------------------------
/server/models/user.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | var Schema = mongoose.Schema;
3 | var userSchema = new Schema({
4 | "userId": String,
5 | "userName": String,
6 | "orderList": Array,
7 | "cartList": Array,
8 | "cartList": [{
9 | "productId": String,
10 | "productName": String,
11 | "salePrice": Number,
12 | "productImage": String,
13 | "productUrl": String,
14 | "productNum": Number,
15 | "checked": String
16 | }],
17 | "addressList": [{
18 | "addressId": String,
19 | "userName": String,
20 | "streetName": String,
21 | "postCode": Number,
22 | "tel": Number,
23 | "isDefault": Boolean
24 | }]
25 | })
26 |
27 | module.exports = mongoose.model('user', userSchema);
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "0.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "basic-auth": {
8 | "version": "2.0.1",
9 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
10 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
11 | "requires": {
12 | "safe-buffer": "5.1.2"
13 | }
14 | },
15 | "depd": {
16 | "version": "1.1.2",
17 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
18 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
19 | },
20 | "ee-first": {
21 | "version": "1.1.1",
22 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
23 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
24 | },
25 | "morgan": {
26 | "version": "1.9.1",
27 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
28 | "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
29 | "requires": {
30 | "basic-auth": "~2.0.0",
31 | "debug": "2.6.9",
32 | "depd": "~1.1.2",
33 | "on-finished": "~2.3.0",
34 | "on-headers": "~1.0.1"
35 | },
36 | "dependencies": {
37 | "debug": {
38 | "version": "2.6.9",
39 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
40 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
41 | "requires": {
42 | "ms": "2.0.0"
43 | }
44 | }
45 | }
46 | },
47 | "ms": {
48 | "version": "2.0.0",
49 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
50 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
51 | },
52 | "on-finished": {
53 | "version": "2.3.0",
54 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
55 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
56 | "requires": {
57 | "ee-first": "1.1.1"
58 | }
59 | },
60 | "on-headers": {
61 | "version": "1.0.2",
62 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
63 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
64 | },
65 | "safe-buffer": {
66 | "version": "5.1.2",
67 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
68 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "cross-env NODE_ENV=development ./node_modules/.bin/nodemon ./bin/www"
7 | },
8 | "dependencies": {
9 | "body-parser": "~1.17.1",
10 | "cookie-parser": "~1.4.3",
11 | "debug": "~2.6.3",
12 | "express": "~4.15.2",
13 | "jade": "~1.11.0",
14 | "morgan": "^1.9.1",
15 | "serve-favicon": "~2.4.2"
16 | },
17 | "devDependencies": {
18 | "cross-env": "^5.0.5",
19 | "mongoose": "^4.11.13",
20 | "nodemon": "^1.12.1"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/server/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/server/routes/goods.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var mongoose = require('mongoose');
4 | var Goods = require('../models/goods')
5 | var User = require('../models/user')
6 | mongoose.connect('mongodb://47.93.231.75:27017/shops');
7 |
8 | mongoose.connection.on('connected', function() {
9 | console.log("mongondb connected success");
10 | })
11 |
12 | mongoose.connection.on('error', function() {
13 | console.log("mongondb connected fail");
14 | })
15 |
16 | mongoose.connection.on('disconnected', function() {
17 | console.log("mongondb connected disconnected");
18 | })
19 |
20 | router.get("/list", function(req, res, next) {
21 |
22 | let sort = req.param('sort');
23 | let priceLevel = req.param('priceLevel');
24 | let priceGt = '',
25 | priceLte = '';
26 |
27 | let param = {};
28 |
29 | if (priceLevel != 'all') {
30 | // switch (priceLevel) {
31 | // case '0':
32 | // priceGt = 0;
33 | // priceLte = 100;
34 | // break;
35 | // case '1':
36 | // priceGt = 100;
37 | // priceLte = 500;
38 | // break;
39 | // case '2':
40 | // priceGt = 500;
41 | // priceLte = 1000;
42 | // break;
43 | // case '3':
44 | // priceGt = 1000;
45 | // priceLte = 5000;
46 | // break;
47 | // }
48 |
49 | // 表驱动法
50 | let priceItem = [
51 | [0, 100],
52 | [100, 500],
53 | [500, 1000],
54 | [1000, 5000]
55 | ];
56 | param = {
57 | salePrice: {
58 | // $gt: priceGt,
59 | // $lte: priceLte
60 | $gt: priceItem[priceLevel][0],
61 | $lte: priceItem[priceLevel][1]
62 | }
63 | }
64 | }
65 |
66 | console.log(param);
67 |
68 | let currentPage = (parseInt(req.param('page')) > 0) ? parseInt(req.param('page')) : 1; //第几页
69 | let pagesize = (parseInt(req.param('pagesize')) > 0) ? parseInt(req.param('pagesize')) : 8; //每页显示多少条
70 |
71 | let skip = (currentPage - 1) * pagesize;
72 |
73 | // 数据库一共有17条数据 每页显示8条 第二页 从第九条开始 limit 从第9条起数8条为止 这个8就是limit
74 |
75 | let goodModel = Goods.find(param).sort({ 'salePrice': sort }).skip(skip).limit(pagesize);
76 | goodModel.exec({}, function(err, doc) {
77 | res.json({ status: 0, result: doc })
78 | })
79 | })
80 |
81 | router.post('/addCart', function(req, res, next) {
82 | // 查询用哪个用户, 确定好用户
83 | let userId = '100000077';
84 | // 商品id
85 | var productId = req.body.productId;
86 | // console.log(productId);
87 | User.findOne({ userId: userId }, function(err, userDoc) {
88 | // console.log(userDoc);
89 | // 通过商品id去数据库查询, 把商品的信息查出来,
90 |
91 | let goodItem = '';
92 | userDoc.cartList.forEach(function(item) {
93 | if (item.productId == productId) {
94 | // 此时表示在购物车列表存在这个商品
95 | goodItem = item;
96 | item.productNum++;
97 | }
98 | })
99 |
100 | // 如果不是第一次加入购物车
101 | if (goodItem) {
102 | userDoc.save(function(err3, doc3) {
103 | if (err3) {
104 | res.json({ status: "1", msg: err3.message })
105 | } else {
106 | res.json({ status: 0, msg: '', result: '商品数量添加成功!' })
107 | }
108 | })
109 | } else {
110 | // 商品第一次加入购物车
111 | // 怎么判断是第一次加入购物车还是购物车里面已经有了
112 | Goods.findOne({ 'productId': productId }, function(err1, goodDoc) {
113 | console.log(goodDoc);
114 | console.log(productId);
115 | goodDoc.productNum = 1;
116 | goodDoc.checked = 1;
117 | // 此时去查询这个商品是否存在于用户购物车列表里面
118 |
119 | userDoc.cartList.push(goodDoc);
120 | userDoc.save(function(err2, doc2) {
121 | if (err2) {
122 | res.json({ status: 1, msg: err2.message })
123 | } else {
124 | res.json({ status: 0, msg: '', result: "加入购物车成功" })
125 | }
126 | })
127 | })
128 | }
129 |
130 |
131 | })
132 |
133 | // 如果存在则商品数量加一, 不存在把整个商品信息存到里面
134 | // 然后存到这个用户里面
135 |
136 | })
137 | module.exports = router;
--------------------------------------------------------------------------------
/server/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res, next) {
6 | res.render('index', { title: ' stark' });
7 | });
8 |
9 | router.get('/stark', function(req, res, next) {
10 | res.json({ 'name': 'stark' });
11 | });
12 |
13 | module.exports = router;
--------------------------------------------------------------------------------
/server/util/util.js:
--------------------------------------------------------------------------------
1 | Date.prototype.Format = function(fmt) { //author: meizz
2 | var o = {
3 | "M+": this.getMonth() + 1, //月份
4 | "d+": this.getDate(), //日
5 | "h+": this.getHours(), //小时
6 | "m+": this.getMinutes(), //分
7 | "s+": this.getSeconds(), //秒
8 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度
9 | "S": this.getMilliseconds() //毫秒
10 | };
11 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
12 | for (var k in o)
13 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
14 | return fmt;
15 | }
16 |
17 | module.exports = {};
--------------------------------------------------------------------------------
/server/views/error.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= message
5 | h2= error.status
6 | pre #{error.stack}
7 |
--------------------------------------------------------------------------------
/server/views/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= title
5 | p Welcome to #{title}
6 |
--------------------------------------------------------------------------------
/server/views/layout.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title= title
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 | body
7 | block content
8 |
--------------------------------------------------------------------------------