├── .babelrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .postcssrc.js ├── 01-GoodsList.md ├── 02-express.md ├── 03-GoodsListInterface.md ├── 04-pagingAndSort.md ├── 05-priceAndCart.md ├── 06-login.md ├── 07-shoppingCart.md ├── 08-address.md ├── 09-orderConfirm.md ├── 10-vuex.md ├── 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 ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── index.html ├── mock └── goods.json ├── package.json ├── resource ├── db ├── dumall-goods ├── dumall-users ├── goodsList_spec.png ├── 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 │ ├── icon.png │ ├── imooc.jpg │ ├── logo.jpg │ ├── logo1.png │ ├── mi6.jpg │ ├── note.jpg │ ├── ok-2.png │ ├── photo.jpg │ ├── pingheng.jpg │ └── zipai.jpg ├── loading │ ├── loading-balls.svg │ ├── loading-bars.svg │ ├── loading-bubbles.svg │ ├── loading-cubes.svg │ ├── loading-cylon-red.svg │ ├── loading-cylon.svg │ ├── loading-spin.svg │ ├── loading-spinning-bubbles.svg │ └── loading-spokes.svg ├── readme │ ├── 10 │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.jpg │ ├── 11 │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ └── 8.jpg │ ├── 12 │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── 13 │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ └── 5.jpg │ ├── 14 │ │ └── 1.jpg │ ├── 15 │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ └── 3.jpg │ ├── 07 │ │ ├── image01.png │ │ ├── image02.png │ │ └── image03.png │ ├── 09 │ │ ├── 1.png │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ └── 1.jpg ├── svg.svg ├── util.js └── views │ ├── address.html │ ├── cart.html │ ├── css │ ├── base.css │ ├── checkout.css │ ├── login.css │ └── product.css │ ├── goodsList.html │ ├── orderConfirm.html │ └── orderSuccess.html ├── server ├── app.js ├── bin │ └── www ├── models │ ├── goods.js │ └── users.js ├── public │ └── stylesheets │ │ └── style.css ├── routes │ ├── goods.js │ ├── index.js │ └── users.js ├── util │ └── util.js └── views │ └── index.html ├── src ├── App.vue ├── assets │ ├── css │ │ ├── base.css │ │ ├── checkout.css │ │ ├── login.css │ │ └── product.css │ └── logo.png ├── components │ ├── Modal.vue │ ├── NavBread.vue │ ├── NavFooter.vue │ └── NavHeader.vue ├── main.js ├── router │ └── index.js ├── util │ └── currency.js └── views │ ├── Address.vue │ ├── Cart.vue │ ├── GoodsList.vue │ ├── OrderConfirm.vue │ └── OrderSuccess.vue ├── static ├── .gitkeep ├── 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 ├── icon.png ├── imooc.jpg ├── loading-svg │ ├── loading-balls.svg │ ├── loading-bars.svg │ ├── loading-bubbles.svg │ ├── loading-cubes.svg │ ├── loading-cylon-red.svg │ ├── loading-cylon.svg │ ├── loading-spin.svg │ ├── loading-spinning-bubbles.svg │ └── loading-spokes.svg ├── logo.png ├── mi6.jpg ├── note.jpg ├── ok-2.png ├── photo.jpg ├── pingheng.jpg └── zipai.jpg └── test ├── ES6-1.html ├── ES6-2.html ├── ES6.md ├── Promise.html ├── Promise.js ├── axios.html ├── vue-resource.html └── vuex ├── vuex1-state.html ├── vuex2-mutations.html ├── vuex3-actions.html └── vuex4-getters.html /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.js linguist-language=Vue 5 | *.css linguist-language=Vue 6 | *.html linguist-language=Vue 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /01-GoodsList.md: -------------------------------------------------------------------------------- 1 | ### GoodsList.vue-商品列表页模块实现 2 | 3 | > ##### 面包屑子组件NavBread.vue 4 | 5 | slot插槽使用 6 | 7 | 因为每个页面的名字不一样,所以面包屑不是固定的,在名字的位置留一个插槽,由父组件提供内容。 8 | 9 | 10 | ```html 11 | 子组件NavBread.vue: 12 | 23 | 24 | 父组件goodsList.vue 25 | import NavBread from '@/components/NavBread.vue' 26 | 27 | Goods 28 | 29 | 30 | ``` 31 | > ##### mock模拟json数据 32 | 33 | ```javascript 34 | //dev-server.js 35 | 为什么可以用localhost:8080访问? 36 | vue内置的一套express框架,基于nodejs的服务。 37 | 38 | var app = express()后面 39 | var router=express.Router(); // 拿到服务端的路由 40 | var goodsData = require('../mock/goods.json'); 41 | router.get("/goods",function(req,res,next){ //定义了一个goods路由,req拿到请求的参数,res是response输出的一些东西,next 42 | res.json(goodsData); 43 | }) 44 | app.use(router); // 用路由 45 | 46 | ``` 47 | 48 | ```javascript 49 | // goodsList.vue 50 | data(){ 51 | return { 52 | goodsList:[] 53 | } 54 | }, 55 | mounted:function(){ 56 | this.getGoodsList(); 57 | }, 58 | methods:{ 59 | getGoodsList(){ 60 | axios.get("/goods").then((res)=>{ 61 | var _res = res.data; 62 | this.goodsList = _res.result; 63 | }) 64 | } 65 | } 66 | 67 | ``` 68 | > ##### 价格区间菜单实现 69 | 70 | ```javascript 71 | data(){ 72 | return { 73 | priceFilter:[ // 价格区间数组 74 | { 75 | startPrice:'0.00', 76 | endPrice:'100.00' 77 | }, 78 | { 79 | startPrice:'100.00', 80 | endPrice:'500.00' 81 | }, 82 | { 83 | startPrice:'500.00', 84 | endPrice:'1000.00' 85 | }, 86 | { 87 | startPrice:'1000.00', 88 | endPrice:'5000.00' 89 | } 90 | ], 91 | priceChecked:'all' // 选中的价格区间 92 | } 93 | }, 94 |
95 |
96 |
Price:
97 |
All
98 |
99 | {{price.startPrice}} - {{price.endPrice}} 100 |
101 |
102 |
103 | 104 | ``` 105 | 考虑到是响应式布局,移动端时点击 Filter by 价格菜单切换,类名"filterby-show"控制价格区间菜单的显示 106 | 107 | ```html 108 | Filter by 109 | 110 |
111 |
112 |
Price:
113 |
All
114 |
115 | {{price.startPrice}} - {{price.endPrice}} 116 |
117 |
118 |
119 | 120 | 121 |
122 | ``` 123 | 124 | ```javascript 125 | data(){ 126 | return { 127 | priceFilter:[ // 价格区间数组 128 | { 129 | startPrice:'0.00', 130 | endPrice:'100.00' 131 | }, 132 | { 133 | startPrice:'100.00', 134 | endPrice:'500.00' 135 | }, 136 | { 137 | startPrice:'500.00', 138 | endPrice:'1000.00' 139 | }, 140 | { 141 | startPrice:'1000.00', 142 | endPrice:'5000.00' 143 | } 144 | ], 145 | priceChecked:'all', // 选中的价格区间 146 | filterBy:false, // 控制价格菜单的显示 147 | overLayFlag:false // 遮罩的显示 148 | } 149 | }, 150 | methods:{ 151 | setPriceFilter(index){ // 点击价格 152 | this.priceChecked = index; 153 | this.closePop(); 154 | }, 155 | showFilterPop(){ // 点击filterBy出现价格菜单和遮罩 156 | this.filterBy = true; 157 | this.overLayFlag = true; 158 | }, 159 | closePop(){ // 关闭价格菜单和遮罩 160 | this.filterBy = false; 161 | this.overLayFlag = false; 162 | } 163 | } 164 | ``` 165 | > ##### 图片懒加载 https://www.npmjs.com/package/vue-lazyload 166 | 167 | 168 | ``` 169 | npm install vue-lazyload --save 170 | 171 | // main.js 172 | import VueLazyLoad from 'vue-lazyload' 173 | Vue.use(VueLazyLoad,{ 174 | loading:"/static/loading-svg/loading-bars.svg" 175 | }) 176 | 177 | ``` 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /02-express.md: -------------------------------------------------------------------------------- 1 | ### express-project 2 | 3 | > ##### 搭建基于Express框架运行环境 4 | 5 | 6 | * 安装express generator生成器 7 | * 通过生成器自动创建项目 8 | * 配置分析 9 | 10 | ###### 安装 11 | 12 | ```javascript 13 | cnpm i -g express-generator 14 | express --version // 查看版本 15 | express server // 创建项目 16 | 17 | ``` 18 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/07/image01.png?raw=true) 19 | 20 | 正常是前后端分离,建立两个项目。此项目为了测试前后端未分离,将package.json的dependencies合并到根目录的package.json。 21 | 22 | ```javascript 23 | cnpm install // 安装依赖 24 | cd server 25 | node bin/www // 运行 26 | 27 | ``` 28 | 浏览器输入localhost:3000 29 | 30 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/07/image02.png?raw=true) 31 | 32 | ##### 更换html模板引擎 33 | 34 | express项目views文件夹内文件格式是.jade格式,若要改成HTML文件。 35 | 36 | 37 | ``` 38 | cnpm install ejs --save //安装ejs 39 | 40 | ``` 41 | 42 | ``` 43 | app.js 44 | 45 | var ejs = require('ejs'); 46 | app.engine('.html',ejs.__express); // 设置html后缀模板引擎 47 | app.set('view engine', 'jade'); 改成 app.set('view engine', 'html'); 48 | 49 | 50 | 在views文件夹内建立index.html文件,重新启动express 51 | 52 | node bin/www 53 | 54 | ``` 55 | localhost:3000 56 | 57 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/07/image03.png?raw=true) 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /03-GoodsListInterface.md: -------------------------------------------------------------------------------- 1 | ## 基于Node.js开发商品列表接口 2 | 3 | > #### 一、node的启动调试方式 4 | [http://www.cnblogs.com/ccyinghua/p/7889320.html](http://www.cnblogs.com/ccyinghua/p/7889320.html) 5 | 6 |
7 | 8 | > #### 二、基于Express实现商品列表查询接口 9 | 10 | mongodb安装与环境搭建,建立dumall数据库,创建goods集合,导入数据文件 (resource文件夹/dumall-goods),也可以自己手动插入。 11 | 12 | mongodb安装与环境搭建: [http://www.cnblogs.com/ccyinghua/p/7887713.html](http://www.cnblogs.com/ccyinghua/p/7887713.html) 13 | 14 | 建立数据库和插入数据,可以进入mongo操作数据库,以命令行形式插入操作,即成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作; 15 | 也可以下载mongovue3.4.4(64位)客户端进行操作,客户端可以手动输入插入数据,也可以导入文件插入数据。 16 | 17 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/1.png?raw=true) 18 | 19 | 数据库建立完成,然后就是项目与mongodb连接: 20 | 21 | ```javascript 22 | * 安装mongoose链接数据库mongodb 23 | * 创建model,mongoose创建了model就是一个实体,可以跟mongodb进行关联。 24 | * 创建路由。 25 | * 基于mongoose,实现商品列表的查询功能。 26 | ``` 27 | ###### 1、安装mongoose(操作mongodb数据库的对象模型工具) 28 | 29 | API文档: [http://mongoosejs.com/docs/guide.html](http://mongoosejs.com/docs/guide.html) 30 | 31 | ```javascript 32 | cnpm install mongoose --save 33 | 34 | ``` 35 | 36 | ###### 2、创建model 37 | 38 | [models/goods.js](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/server/models/goods.js)--定义输出一个商品的模型model. 39 | 40 | 41 | ```javascript 42 | var mongoose = require('mongoose'); 43 | var Schema = mongoose.Schema; 44 | // 定义一个Schema 45 | var produtSchema = new Schema({ 46 | 'productId':String, // 或者 'productId':{type:String} 47 | 'productName':String, 48 | 'salePrice':Number, 49 | 'productImage':String 50 | }) 51 | 52 | // 输出(导出) 53 | module.exports = mongoose.model('good',produtSchema); // 定义一个good商品模型,可以根据这个商品模型调用其API方法。 54 | // 这个模型定义的是数据库dumall的goods集合数据,所以这个model取名good是对应这个集合,连接数据库之后,这个模型会根据名字的复数形式"goods"来查找数据集合。 55 | // module.exports = mongoose.model('good',produtSchema,'goods'); 也可以后面注明链接的是数据库的goods集合 56 | ``` 57 | ###### 3、创建路由,实现查询 58 | 59 | server/routers文件夹内定义其路由,在routers/goods.js;同时server/app.js要增添上这个goods的路由 60 | 61 | ```javascript 62 | >> app.js 63 | 64 | var goods = require('./routes/goods'); 65 | app.use('/goods', goods); 66 | 67 | ``` 68 | 69 | ```javascript 70 | >> routers/goods.js 71 | 72 | var express = require('express'); 73 | var router = express.Router(); // 拿到express框架的路由 74 | var mongoose = require('mongoose'); 75 | var Goods = require('../models/goods'); 76 | 77 | // 链接MongoDB数据库,数据库的名称叫dumall 78 | mongoose.connect('mongodb://127.0.0.1:27017/dumall'); // 若是带账号密码的:'mongodb://root:123456@127.0.0.1:27017/dumall' 79 | 80 | // 连接成功操作 81 | mongoose.connection.on("connected",function(){ 82 | console.log("MongoDB connected success.") 83 | }) 84 | 85 | // 连接失败操作 86 | mongoose.connection.on("error",function(){ 87 | console.log("MongoDB connected fail.") 88 | }) 89 | 90 | // 连接断开操作 91 | mongoose.connection.on("disconnected",function(){ 92 | console.log("MongoDB connected disconnected.") 93 | }) 94 | 95 | // 二级路由 96 | /* GET goods page. */ 97 | router.get('/', function(req, res, next) { 98 | res.send('hello,goods list'); // 测试路由,连接成功页面出现'hello,goods list' 99 | }); 100 | 101 | module.exports = router; 102 | 103 | 104 | // 启动express 105 | // node server/bin/www 或 pm2方式 或 webstorm 等 106 | // localhost:3000/goods/ // '/goods'是app.js中的一级路由,'/'是本页的二级路由;链接成功页面出现'hello,goods list' 107 | 108 | ``` 109 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/2.png?raw=true) 110 | 111 | 路由连接成功之后,用model的good商品模型查询到数据库的goods集合。 112 | 113 | ```javascript 114 | // 二级路由 115 | /* GET goods page. */ 116 | router.get('/', function(req, res, next) { 117 | // res.send('hello,goods list'); // 测试路由,连接成功页面出现'hello,goods list' 118 | 119 | // 连接成功之后,用model的good商品模型查询到数据库的goods集合。 120 | Goods.find({},function(err, doc){ // Goods来自models/goods.js;导出的是mongoose的商品模型,可使用mongoose的API方法 121 | if(err) { 122 | res.json({ 123 | status:'1', 124 | msg:err.message 125 | }) 126 | }else{ 127 | res.json({ 128 | status:'0', 129 | msg:'', 130 | result:{ 131 | count:doc.length, 132 | list:doc 133 | } 134 | }) 135 | } 136 | }) 137 | 138 | }); 139 | 140 | // 重新启动express 141 | // 页面出现mongodb数据库里的goods集合数据信息json 142 | 143 | ``` 144 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/3.png?raw=true) 145 | 146 |
147 | 148 | > #### 三、vue项目mock模拟json数据换成接口显示 149 | 150 | 连接了数据库,有了数据接口,就不需要mock模拟json数据了。 151 | 152 | build/dev-server.js 153 | 154 | ```javascript 155 | * 这段代码不需要了 156 | // mock模拟json数据 157 | var router = express.Router() // 拿到服务端的路由 158 | var goodsData = require('../mock/goods.json') 159 | router.get("/goods",function(req,res,next){ // 定义了一个goods路由,req拿到请求的参数,res是response输出的一些东西,next 160 | res.json(goodsData) 161 | }) 162 | app.use(router) // 用路由 163 | 164 | ``` 165 | server的express框架,localhost:3000运行,已经跨域了,我们获取json数据的axios插件不支持跨域,所以需要做一个`代理`。 166 | 167 | config/index.js 168 | 169 | ```javascript 170 | dev: { 171 | proxyTable: { // 是一个代理插件,方便做转发,不需要跨域了。仅限于开发使用,开发完之后一定要跟服务器端连接在一起,否则需要nginx转发配置 172 | '/goods':{ // 当我们访问'/goods'的时候,会转发到express的localhost:3000下面,访问3000下面的'/goods'; 173 | target:'http://localhost:3000' 174 | } 175 | } 176 | } 177 | ``` 178 | 179 | 之前的mock数据goods.json数据是在result下面,express接口的数据是在result.list下面,所以获取数据的axios需要改一下。 180 | 181 | ```javascript 182 | // 原来的 183 | axios.get("/goods").then((res)=>{ 184 | var _res = res.data; 185 | this.goodsList = _res.result; 186 | }) 187 | 188 | // 现在的:转到localhost:3000之后 189 | axios.get("/goods").then((res)=>{ 190 | var res = res.data; 191 | if(res.status == "0"){ 192 | this.goodsList = res.result.list; 193 | }else{ 194 | this.goodsList = []; 195 | } 196 | }) 197 | ``` 198 | 运行项目:npm run dev 199 | 200 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/4.png?raw=true) 201 | 202 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/5.jpg?raw=true) 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /04-pagingAndSort.md: -------------------------------------------------------------------------------- 1 | ## 商品列表页分页和排序功能 2 | 3 | 4 | > #### 一、后台实现分页排序功能 5 | server/routes/goods.js 6 | 7 | ```javascript 8 | // 二级路由 9 | /* GET goods page. */ 10 | router.get('/', function(req, res, next) { 11 | // res.send('hello,goods list'); // 测试路由,连接成功页面出现'hello,goods list' 12 | 13 | // express获取请求参数 14 | let page = parseInt(req.param("page")); 15 | let pageSize = parseInt(req.param("pageSize")); 16 | let sort = req.param("sort"); 17 | let skip = (page-1)*pageSize; // 跳过的数据条数,(分页的公式). 18 | let params = {}; 19 | let goodsModel = Goods.find(params).skip(skip).limit(pageSize); // 先查询所有,skip(skip)跳过skip条数据,limit(pageSize)一页多少条数据. 20 | goodsModel.sort({'salePrice':sort}); // 对价格排序 21 | 22 | goodsModel.exec(function(err, doc){ 23 | if(err) { 24 | res.json({ 25 | status:'1', 26 | msg:err.message 27 | }) 28 | }else{ 29 | res.json({ 30 | status:'0', 31 | msg:'', 32 | result:{ 33 | count:doc.length, 34 | list:doc 35 | } 36 | }) 37 | } 38 | }) 39 | 40 | }); 41 | 42 | ``` 43 | 启动express,在server文件夹 node bin/www , 浏览器 http://localhost:3000/goods?page=1&pageSize=5&sort=1 (page=1第一页;pageSize=5一页显示5条;sort=1升序),数据库一共17条,第四页是最后一页,只显示2条。 44 | 45 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/6.jpg?raw=true) 46 | 47 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/7.jpg?raw=true) 48 | 49 |
50 | 51 | > #### 二、前端实现分页排序 52 | 53 | ###### 2.1 分页排序 54 | 55 | src/views/GoodsList.vue 56 | 57 | ```javascript 58 | 59 | export default { 60 | data(){ 61 | return { 62 | sortFlag:true, // 排序:默认升序 63 | page:1, // 当前第一页 64 | pageSize:8 // 一页有8条数据 65 | } 66 | }, 67 | mounted:function(){ 68 | this.getGoodsList(); 69 | }, 70 | methods:{ 71 | getGoodsList(){ 72 | var param = { 73 | page:this.page, 74 | pageSize:this.pageSize, 75 | sort:this.sortFlag ? 1 : -1 // sortFlag为true升序 76 | } 77 | axios.get("/goods",{ 78 | params:param // 传参 79 | }).then((res)=>{ 80 | var res = res.data; 81 | if(res.status == "0"){ 82 | this.goodsList = res.result.list; 83 | }else{ 84 | this.goodsList = []; 85 | } 86 | }) 87 | }, 88 | sortGoods(){ // 点击页面右上角"price"排序商品 89 | this.sortFlag = !this.sortFlag; 90 | this.page = 1; // 点击价格排序后从第一页开始 91 | this.getGoodsList(); // 重新加载数据 92 | }, 93 | } 94 | } 95 | 96 | ``` 97 | 列表页只显示8条,默认升序 98 | 99 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/8.jpg?raw=true) 100 | 101 | ###### 2.2滚动加载插件 vue-infinite-scroll    [https://www.npmjs.com/package/vue-infinite-scroll](https://www.npmjs.com/package/vue-infinite-scroll) 102 | 103 | 104 | ```javascript 105 | cnpm install vue-infinite-scroll --save // 安装 106 | 107 | Usage: 108 |
109 | ... 110 |
111 | 112 | v-infinite-scroll="loadMore" // 滚动的时候加载的方法 113 | infinite-scroll-disabled="busy" // 是否禁用此方法,busy为true就失效不滚动 114 | infinite-scroll-distance="10" // 滚动的距离,滚定条距离底部多远就触发加载 115 | 116 | ``` 117 | 118 | main.js导入插件 119 | 120 | ```javascript 121 | import infiniteScroll from 'vue-infinite-scroll' 122 | Vue.use(infiniteScroll) 123 | ``` 124 | GoodsList.vue 125 | 126 | ```javascript 127 | 128 | 129 |
130 | 加载中... 131 |
132 | 182 | 183 | 184 | 185 | ``` 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /05-priceAndCart.md: -------------------------------------------------------------------------------- 1 | ## 商品列表价格过滤和加入购物车功能 2 | 3 | ### 一、价格过滤功能 4 | 5 | GoodsList.vue 6 | 7 | ```javascript 8 | >>点击价格区间时发送请求 9 | 10 | methods:{ 11 | getGoodsList(flag){ 12 | var param = { 13 | // 请求时传点击的价格区间数据给后台 14 | priceLevel:this.priceChecked // 点击的价格区间 15 | } 16 | ...... 17 | }, 18 | setPriceFilter(index){ // 点击价格 19 | this.priceChecked = index; 20 | this.closePop(); 21 | this.getGoodsList(); // 发送请求 22 | }, 23 | } 24 | 25 | ``` 26 | server/routes/goods.js
27 | 获取传过来的参数,对价格参数进行处理,查询价格区间内的数据库数据 28 | 29 | ```javascript 30 | 31 | // 二级路由 32 | /* GET goods page. */ 33 | router.get('/', function(req, res, next) { 34 | // express获取请求参数 35 | let priceLevel = req.param("priceLevel"); // 传过来的价格区间 36 | var priceGt = '',priceLte = ''; 37 | let params = {}; 38 | if(priceLevel != 'all'){ // 价格区间过滤功能 39 | switch (priceLevel){ 40 | case '0':priceGt=0;priceLte =100;break; 41 | case '1':priceGt=100;priceLte =500;break; 42 | case '2':priceGt=500;priceLte =1000;break; 43 | case '3':priceGt=1000;priceLte =5000;break; 44 | } 45 | params = { 46 | salePrice:{ 47 | $gt:priceGt, 48 | $lte:priceLte 49 | } 50 | } 51 | } 52 | ...... 53 | }); 54 | 55 | #重新启动express, node server/bin/www 56 | #浏览器输入 http://localhost:3000/goods?page=1&pageSize=8&sort=1&priceLevel=2 测试价格区间500-1000的数据能否显示 57 | 58 | ``` 59 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/9.jpg?raw=true) 60 | 61 | 62 | > #### 往下滚动分页加载图标效果 63 | 64 | ```javascript 65 | 66 | 67 | 68 | export default { 69 | data(){ 70 | return { 71 | loading:false // 往下滚动"加载图标"的出现效果:默认不出现 72 | } 73 | }, 74 | methods:{ 75 | getGoodsList(flag){ 76 | this.loading = true; // 请求前出现 77 | axios.get("/goods",{ 78 | params:param // 传参 79 | }).then((res)=>{ 80 | var res = res.data; 81 | this.loading = false; // 请求到数据图标消失 82 | if(res.status == "0"){ 83 | ...... 84 | } 85 | }) 86 | } 87 | } 88 | } 89 | ``` 90 | ### 二、加入购物车功能 91 | 92 | dumall数据库建立users集合导入resource文件夹的dumall-users
93 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/10.jpg?raw=true) 94 | 95 | 96 | 与商品列表接口一样,先建立用户数据的模型
97 | server/models/users.js 98 | 99 | ```javascript 100 | 101 | // 对应数据库用户数据在resource文件夹的dumall-users 102 | var mongoose = require('mongoose'); 103 | var Schema = mongoose.Schema; 104 | 105 | // 定义一个Schema 106 | var userSchema = new Schema({ 107 | 'userId':String, // 或者 'userId':{type:String} 108 | 'userName':String, 109 | 'userPwd':String, 110 | 'orderList':Array, 111 | 'cartList':[ // 购物车列表 112 | { 113 | "productId":String, 114 | "productName":String, 115 | "salePrice":Number, 116 | "productImage":String, 117 | "checked":String, // 是否选中 118 | "productNum":String // 商品数量 119 | } 120 | ], 121 | "addressList":Array 122 | }) 123 | 124 | // 输出(导出) 125 | module.exports = mongoose.model('user',userSchema); // 定义一个user模型,可以根据这个模型调用其API方法。 126 | // 这个模型定义的是数据库dumall的users集合数据,所以这个model取名user是对应这个集合,连接数据库之后,这个模型会根据名字的复数形式"users"来查找数据集合。 127 | // module.exports = mongoose.model('user',userSchema,'users'); 也可以后面注明链接的是数据库的goods集合 128 | 129 | ``` 130 | 131 | 数据库链接(之前商品列表页已连接),查询操作用户数据,建立接口,实现加入购物车功能 132 | server/routes/goods.js 133 | 134 | ```javascript 135 | 136 | // 加入到购物车 137 | // 是二级路由,一级路由在app.js 138 | router.post("/addCart",function(req, res, next){ 139 | var userId = '100000077', 140 | productId = req.body.productId; // post请求拿到res参数:req.body 141 | var User = require('../models/users.js'); // 引入user模型 142 | 143 | // 查询第一条:拿到用户信息 144 | User.findOne({ 145 | userId:userId // 查询条件 146 | },function(err,userDoc){ 147 | if(err){ 148 | res.json({ 149 | status:"1", 150 | msg:err.message 151 | }) 152 | }else{ 153 | console.log("userDoc"+userDoc); // 用户数据 154 | if(userDoc){ 155 | let goodsItem = ''; 156 | userDoc.cartList.forEach(function(item){ // 遍历用户购物车,判断加入购物车的商品是否已经存在 157 | if(item.productId == productId){ 158 | goodsItem = item; 159 | item.productNum++; // 购物车这件商品数量+1 160 | } 161 | }) 162 | if(goodsItem){ // 若购物车商品已存在 163 | userDoc.save(function (err2,doc2) { 164 | if(err2){ 165 | res.json({ 166 | status:"1", 167 | msg:err2.message 168 | }) 169 | }else{ 170 | res.json({ 171 | status:'0', 172 | msg:'', 173 | result:'suc' 174 | }) 175 | } 176 | }) 177 | }else{ // 若购物车商品不存在,就添加进去 178 | Goods.findOne({productId:productId},function(err1,doc){ // 从商品列表页Goods查询点击加入购物车的那件商品信息 179 | if(err1){ 180 | res.json({ 181 | status:"1", 182 | msg:err1.message 183 | }) 184 | }else{ 185 | if(doc){ 186 | doc.productNum = 1; 187 | doc.checked = 1; 188 | userDoc.cartList.push(doc); // 添加信息到用户购物车列表中 189 | userDoc.save(function(err2,doc2){ // 保存数据库 190 | if(err2){ 191 | res.json({ 192 | status:"1", 193 | msg:err2.message 194 | }) 195 | }else{ 196 | res.json({ 197 | status:"0", 198 | msg:'', 199 | result:'suc' 200 | }) 201 | } 202 | }) 203 | } 204 | } 205 | }) 206 | } 207 | } 208 | } 209 | }) 210 | }) 211 | 212 | ``` 213 | 214 | 页面实现加入购物车请求实现 215 | GoodsList.vue 216 | 217 | ```javascript 218 | 219 | 220 | 加入购物车 221 | 222 | methods:{ 223 | addCart(productId){ // 点击加入购物车 224 | axios.post("/goods/addCart",{ // 接口设置在server/routes/goods.js 225 | productId:productId 226 | }).then((res)=>{ 227 | var res = res.data; 228 | if(res.status==0){ 229 | alert("加入成功") 230 | }else{ 231 | alert("msg:"+res.msg) 232 | } 233 | }) 234 | } 235 | } 236 | 237 | ``` 238 | 运行项目,点击购物车,请求成功,数据库购物车列表变化 239 | 240 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/11.jpg?raw=true) 241 | 242 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/09/12.jpg?raw=true) 243 | 244 | 245 | 246 | 247 | -------------------------------------------------------------------------------- /10-vuex.md: -------------------------------------------------------------------------------- 1 | ## 基于Vuex改造登录和购物车数量功能 2 | 3 | 4 | Vuex官网: [https://vuex.vuejs.org/zh-cn/](https://vuex.vuejs.org/zh-cn/)
5 | Vuex基础总结: [http://www.cnblogs.com/ccyinghua/p/7865804.html](http://www.cnblogs.com/ccyinghua/p/7865804.html) 6 |

7 | Vuex用来集中管理数据,哪些组件被页面重复使用,哪些组件被多个页面嵌套,而且组件之间有数据交互,就比较适合用vuex。 8 |

9 | 在这个项目中,头部和底部组件是用的最多的,底部没有数据交互,所以头部中我们可以对登录和购物车数量使用vuex交互。 10 | 11 | ### 一、使用vuex 12 | 13 | 安装 14 | 15 | ```javascript 16 | cnpm install vuex --save 17 | 18 | ``` 19 | src/main.js 20 | 21 | ```javascript 22 | 23 | import Vuex from 'vuex' 24 | Vue.use(Vuex); 25 | 26 | // 建立store对象 27 | const store = new Vuex.Store({ 28 | state: { 29 | nickName:'', // 用户名 30 | cartCount:0 // 购物车数量 31 | }, 32 | mutations: { // 更改状态 33 | //更新用户信息 34 | updateUserInfo(state, nickName) { 35 | state.nickName = nickName; 36 | }, 37 | updateCartCount(state,cartCount){ 38 | state.cartCount += cartCount; 39 | }, 40 | initCartCount(state,cartCount){ 41 | state.cartCount = cartCount; 42 | } 43 | } 44 | }); 45 | 46 | /* eslint-disable no-new */ 47 | new Vue({ 48 | store, // 使用store 49 | }) 50 | 51 | ``` 52 | 53 | ### 二、用户名使用vuex交互 54 | 55 | src/components/NavHeader.vue 56 |
57 | 若用户名使用数据管理,data里面nickName用户名就不用定义,而是使用`this.$store.state.nickName`在computed计算属性获取vuex的state.nickName用户名数据。 58 | 另外,methods方法的里面的`this.nickName`赋值需要改成`this.$store.commit("updateUserInfo",赋值的用户名);`形式以达到提交store对象的mutations触发赋值事件。 59 | 60 | ```javascript 61 | export default { 62 | data(){ 63 | return { 64 | // nickName:'' // 用了vuex这个data数据就不用了 65 | } 66 | }, 67 | computed:{ 68 | nickName(){ 69 | return this.$store.state.nickName; 70 | } 71 | }, 72 | methods:{ 73 | checkLogin(){ // 检查是否登录 74 | ...... 75 | // this.nickName = res.result; 76 | this.$store.commit("updateUserInfo",res.result); 77 | ...... 78 | }) 79 | }, 80 | login(){ // 点击登录 81 | ...... 82 | // this.nickName = res.result.userName; 83 | this.$store.commit("updateUserInfo",res.result.userName); 84 | ...... 85 | }, 86 | logOut(){ // 点击logout登出 87 | ...... 88 | // this.nickName = ''; 89 | this.$store.commit("updateUserInfo",res.result.userName); 90 | ...... 91 | } 92 | } 93 | } 94 | 95 | ``` 96 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/15/1.jpg?raw=true) 97 | 98 | ### 三、购物车数量使用vuex交互 99 | 100 | server/routes/users.js查询购物车商品数量接口 101 | 102 | ```javascript 103 | // 查询购物车商品数量 104 | router.get("/getCartCount", function (req,res,next) { 105 | if(req.cookies && req.cookies.userId){ 106 | console.log("userId:"+req.cookies.userId); 107 | var userId = req.cookies.userId; 108 | User.findOne({"userId":userId}, function (err,doc) { 109 | if(err){ 110 | res.json({ 111 | status:"0", 112 | msg:err.message 113 | }); 114 | }else{ 115 | let cartList = doc.cartList; 116 | let cartCount = 0; 117 | cartList.map(function(item){ 118 | cartCount += parseFloat(item.productNum); 119 | }); 120 | res.json({ 121 | status:"0", 122 | msg:"", 123 | result:cartCount 124 | }); 125 | } 126 | }); 127 | }else{ 128 | res.json({ 129 | status:"0", 130 | msg:"当前用户不存在" 131 | }); 132 | } 133 | }); 134 | ``` 135 | src/components/NavHeader.vue 136 | 137 | ```html 138 | 139 | 140 | ``` 141 | 142 | ```javascript 143 | export default { 144 | computed:{ 145 | cartCount(){ 146 | return this.$store.state.cartCount; 147 | } 148 | }, 149 | methods:{ 150 | checkLogin(){ // 检查是否登录 151 | ...... 152 | if(res.status == '0'){ // 如果已登录购物车商品数量更新 153 | ...... 154 | this.getCartCount(); // 查询购物车商品数量 155 | } 156 | ...... 157 | }, 158 | login(){ // 点击登录 159 | ...... 160 | if(res.status == "0"){ // 登录成功后购物车商品数量更新 161 | ...... 162 | this.getCartCount(); // 查询购物车商品数量 163 | } 164 | ...... 165 | }, 166 | getCartCount(){ // 查询购物车商品数量 167 | axios.get("/users/getCartCount").then(res=>{ 168 | var res = res.data; 169 | this.$store.commit("initCartCount",res.result); 170 | }); 171 | } 172 | } 173 | } 174 | 175 | ``` 176 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/15/2.jpg?raw=true) 177 | 178 | 也可使用`mapState辅助函数`简写。 179 | 180 | ```javascript 181 | 182 | import { mapState } from 'vuex' 183 | computed:{ 184 | ...mapState(['nickName','cartCount']) // 这里的...是ES6语法 185 | /*nickName(){ 186 | return this.$store.state.nickName; 187 | }, 188 | cartCount(){ 189 | return this.$store.state.cartCount; 190 | }*/ 191 | } 192 | 193 | ``` 194 | 195 | > ###### 商品列表页点击加入购物车;购物车列表页点击删除商品;添加商品减少商品;--购物车商品数量的变化 196 | 197 | src/views/GoodsList.vue 198 | 199 | ```javascript 200 | export default { 201 | methods:{ 202 | addCart(productId){ // 点击加入购物车 203 | ...... 204 | // 购物车数量加1 205 | this.$store.commit('updateCartCount',1); 206 | ...... 207 | }) 208 | }, 209 | } 210 | } 211 | 212 | ``` 213 | src/views/Cart.vue 214 | 215 | ```javascript 216 | export default { 217 | methods:{ 218 | delCart(){ // 确认删除此商品 219 | axios.post('/users/cartDel',... 220 | // 右上角购物车数量更新 221 | var delCount = this.delItem.productNum; 222 | this.$store.commit("updateCartCount",-delCount); 223 | } 224 | }) 225 | }, 226 | editCart(flag,item){ // 商品加减和勾选 227 | ...... 228 | axios.post('/users/cartEdit',... 229 | // 右上角购物车数量更新 230 | let num = 0; 231 | if(flag == 'add'){ //点加号 232 | num = 1 233 | }else if(flag == 'minu'){ //点减号 234 | num = -1; 235 | } 236 | this.$store.commit("updateCartCount",num); 237 | }) 238 | } 239 | } 240 | } 241 | 242 | ``` 243 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/15/3.jpg?raw=true) 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-node-mongodb-project 2 | 3 | > A Vue.js project 4 | 5 | ### 运行项目 6 | 7 | 1、先安装mongodb和环境搭建: [http://www.cnblogs.com/ccyinghua/p/7887713.html](http://www.cnblogs.com/ccyinghua/p/7887713.html) 8 | 9 | 2、安装mongovue,建立dumall数据库,增加goods和users集合,插入数据(数据在resource/dumall-goods和resource/dumall-users)
10 | ![image](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/resource/readme/1.jpg?raw=true) 11 | 12 | 3、npm install
13 | 4、node server/bin/www // 启动express后端服务
14 | 5、npm run dev 15 | 16 | 17 | ### 构建项目 18 | 19 | ```javascript 20 | vue init webpack vue-node-mongodb-project 21 | 22 | cnpm install 23 | npm run dev 24 | 25 | cnpm install vue-resource --save 26 | cnpm install axios --save 27 | 28 | cnpm install vue-lazyload --save // 图片加载 29 | 30 | * 构建express的一些安装 // 参考 02-express.md 31 | * 安装mongoose // 参考03-GoodsListInterface.md 32 | 33 | * cnpm install vue-infinite-scroll --save // 安装滚动加载插件 04-pagingAndSort.md 34 | 35 | * cnpm install vuex --save // 安装vuex 10-vuex.md 36 | 37 | ``` 38 | > 文件夹列表 39 | 40 | ``` 41 | | - build 42 | | - config 43 | | - mock -- json静态数据 44 | | - resource -- 静态资源文件 45 | | - server -- express框架后端文件 46 | | - models 47 | | - goods.js -- 商品数据模型 48 | | - users.js -- 用户数据模型 49 | | - routes 50 | | - goods.js -- 商品相关接口 51 | | - users.js -- 用户相关接口 52 | | - src 53 | | - assets -- 样式文件 54 | | - components 55 | | - Modal.vue -- 模态框组件 56 | | - NavHeader.vue -- 头部组件 57 | | - NavBread.vue -- 面包屑组件 58 | | - NavFooter.vue -- 底部组件 59 | | - router -- 路由配置文件 60 | | - util -- 公用方法文件 61 | | - views 62 | | - GoodsList.vue -- 商品列表页组件 63 | | - Cart.vue -- 购物车列表组件 64 | | - Address.vue -- 地址列表页组件 65 | | - OrderConfirm.vue -- 订单确认页面 66 | | - OrderSuccess.vue -- 订单成功页面 67 | | - App.vue 68 | | - main.js 69 | | - static -- 项目所用图片,图标 70 | | - test -- vue-resource,axios,vuex,ES6,ES6-promise基础用法 71 | 72 | ``` 73 | 74 | > Markdown说明文件 75 | 76 | [01-GoodsList.md - 商品列表模块实现GoodsList.vue](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/01-GoodsList.md) 77 |
78 | [02-express.md - 搭建基于express框架运行环境](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/02-express.md) 79 |
80 | [03-GoodsListInterface.md - 基于Node.js开发商品列表接口](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/03-GoodsListInterface.md) 81 |
82 | [04-pagingAndSort.md - 商品列表页分页和排序功能](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/04-pagingAndSort.md) 83 |
84 | [05-priceAndCart.md - 商品列表价格过滤和加入购物车功能](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/05-priceAndCart.md) 85 |
86 | [06-login.md - 登录模块(登录功能/登出功能/登录拦截功能/校验登录/全局模态框组件实现)](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/06-login.md) 87 |
88 | [07-shoppingCart.md - 购物车模块实现(渲染购物车列表页面/购物车列表删除功能/购物车商品修改功能)](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/07-shoppingCart.md) 89 |
90 | [08-address.md - 地址模块实现(地址列表渲染/地址切换和展开/设置默认地址/地址删除功能实现)](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/08-address.md) 91 |
92 | [09-orderConfirm.md - 订单模块实现(订单列表渲染/创建订单功能/订单成功页面)](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/09-orderConfirm.md) 93 |
94 | [10-vuex.md - 基于Vuex改造登录和购物车数量功能](https://github.com/ccyinghua/vue-node-mongodb-project/blob/master/10-vuex.md) 95 | 96 | 未完待续...... 97 | 98 | 99 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 = require('./webpack.dev.conf') 14 | 15 | // default port where dev server listens for incoming traffic 16 | var port = process.env.PORT || config.dev.port 17 | // automatically open browser, if not set will be false 18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 19 | // Define HTTP proxies to your custom API backend 20 | // https://github.com/chimurai/http-proxy-middleware 21 | var proxyTable = config.dev.proxyTable 22 | 23 | var app = express() 24 | 25 | /* 有接口了就不用模拟数据了 26 | // mock模拟json数据 27 | var router = express.Router() // 拿到服务端的路由 28 | var goodsData = require('../mock/goods.json') 29 | router.get("/goods",function(req,res,next){ // 定义了一个goods路由,req拿到请求的参数,res是response输出的一些东西,next 30 | res.json(goodsData) 31 | }) 32 | app.use(router) // 用路由 33 | */ 34 | 35 | 36 | var compiler = webpack(webpackConfig) 37 | 38 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 39 | publicPath: webpackConfig.output.publicPath, 40 | quiet: true 41 | }) 42 | 43 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 44 | log: false, 45 | heartbeat: 2000 46 | }) 47 | // force page reload when html-webpack-plugin template changes 48 | compiler.plugin('compilation', function (compilation) { 49 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 50 | hotMiddleware.publish({ action: 'reload' }) 51 | cb() 52 | }) 53 | }) 54 | 55 | // proxy api requests 56 | Object.keys(proxyTable).forEach(function (context) { 57 | var options = proxyTable[context] 58 | if (typeof options === 'string') { 59 | options = { target: options } 60 | } 61 | app.use(proxyMiddleware(options.filter || context, options)) 62 | }) 63 | 64 | // handle fallback for HTML5 history API 65 | app.use(require('connect-history-api-fallback')()) 66 | 67 | // serve webpack bundle output 68 | app.use(devMiddleware) 69 | 70 | // enable hot-reload and state-preserving 71 | // compilation error display 72 | app.use(hotMiddleware) 73 | 74 | // serve pure static assets 75 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 76 | app.use(staticPath, express.static('./static')) 77 | 78 | var uri = 'http://localhost:' + port 79 | 80 | var _resolve 81 | var readyPromise = new Promise(resolve => { 82 | _resolve = resolve 83 | }) 84 | 85 | console.log('> Starting dev server...') 86 | devMiddleware.waitUntilValid(() => { 87 | console.log('> Listening at ' + uri + '\n') 88 | // when env is testing, don't need open it 89 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 90 | opn(uri) 91 | } 92 | _resolve() 93 | }) 94 | 95 | var server = app.listen(port) 96 | 97 | module.exports = { 98 | ready: readyPromise, 99 | close: () => { 100 | server.close() 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 19 | : config.dev.assetsPublicPath 20 | }, 21 | resolve: { 22 | extensions: ['.js', '.vue', '.json'], 23 | alias: { 24 | 'vue$': 'vue/dist/vue.esm.js', 25 | '@': resolve('src'), 26 | } 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.vue$/, 32 | loader: 'vue-loader', 33 | options: vueLoaderConfig 34 | }, 35 | { 36 | test: /\.js$/, 37 | loader: 'babel-loader', 38 | include: [resolve('src'), resolve('test')] 39 | }, 40 | { 41 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 42 | loader: 'url-loader', 43 | options: { 44 | limit: 10000, 45 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 46 | } 47 | }, 48 | { 49 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 50 | loader: 'url-loader', 51 | options: { 52 | limit: 10000, 53 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 54 | } 55 | }, 56 | { 57 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 58 | loader: 'url-loader', 59 | options: { 60 | limit: 10000, 61 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 62 | } 63 | } 64 | ] 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 = config.build.env 13 | 14 | var webpackConfig = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ 17 | sourceMap: config.build.productionSourceMap, 18 | extract: true 19 | }) 20 | }, 21 | devtool: config.build.productionSourceMap ? '#source-map' : false, 22 | output: { 23 | path: config.build.assetsRoot, 24 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 25 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 26 | }, 27 | plugins: [ 28 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 29 | new webpack.DefinePlugin({ 30 | 'process.env': env 31 | }), 32 | new webpack.optimize.UglifyJsPlugin({ 33 | compress: { 34 | warnings: false 35 | }, 36 | sourceMap: true 37 | }), 38 | // extract css into its own file 39 | new ExtractTextPlugin({ 40 | filename: utils.assetsPath('css/[name].[contenthash].css') 41 | }), 42 | // Compress extracted CSS. We are using this plugin so that possible 43 | // duplicated CSS from different components can be deduped. 44 | new OptimizeCSSPlugin({ 45 | cssProcessorOptions: { 46 | safe: true 47 | } 48 | }), 49 | // generate dist index.html with correct asset hash for caching. 50 | // you can customize output by editing /index.html 51 | // see https://github.com/ampedandwired/html-webpack-plugin 52 | new HtmlWebpackPlugin({ 53 | filename: config.build.index, 54 | template: 'index.html', 55 | inject: true, 56 | minify: { 57 | removeComments: true, 58 | collapseWhitespace: true, 59 | removeAttributeQuotes: true 60 | // more options: 61 | // https://github.com/kangax/html-minifier#options-quick-reference 62 | }, 63 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 64 | chunksSortMode: 'dependency' 65 | }), 66 | // keep module.id stable when vender modules does not change 67 | new webpack.HashedModuleIdsPlugin(), 68 | // split vendor js into its own file 69 | new webpack.optimize.CommonsChunkPlugin({ 70 | name: 'vendor', 71 | minChunks: function (module, count) { 72 | // any required modules inside node_modules are extracted to vendor 73 | return ( 74 | module.resource && 75 | /\.js$/.test(module.resource) && 76 | module.resource.indexOf( 77 | path.join(__dirname, '../node_modules') 78 | ) === 0 79 | ) 80 | } 81 | }), 82 | // extract webpack runtime and module manifest to its own file in order to 83 | // prevent vendor hash from being updated whenever app bundle is updated 84 | new webpack.optimize.CommonsChunkPlugin({ 85 | name: 'manifest', 86 | chunks: ['vendor'] 87 | }), 88 | // copy custom static assets 89 | new CopyWebpackPlugin([ 90 | { 91 | from: path.resolve(__dirname, '../static'), 92 | to: config.build.assetsSubDirectory, 93 | ignore: ['.*'] 94 | } 95 | ]) 96 | ] 97 | }) 98 | 99 | if (config.build.productionGzip) { 100 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 101 | 102 | webpackConfig.plugins.push( 103 | new CompressionWebpackPlugin({ 104 | asset: '[path].gz[query]', 105 | algorithm: 'gzip', 106 | test: new RegExp( 107 | '\\.(' + 108 | config.build.productionGzipExtensions.join('|') + 109 | ')$' 110 | ), 111 | threshold: 10240, 112 | minRatio: 0.8 113 | }) 114 | ) 115 | } 116 | 117 | if (config.build.bundleAnalyzerReport) { 118 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 119 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 120 | } 121 | 122 | module.exports = webpackConfig 123 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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: { // 是一个代理插件,方便做转发,不需要跨域了。仅限于开发使用,开发完之后一定要跟服务器端连接在一起,否则需要nginx转发配置 31 | '/goods':{ // 当我们访问'/goods'的时候,会转发到express的localhost:3000下面,访问3000下面的'/goods'; 32 | target:'http://localhost:3000' 33 | }, 34 | '/goods/*':{ 35 | target:'http://localhost:3000' 36 | }, 37 | '/users/*':{ // users/路由的下一级路由 38 | target:'http://localhost:3000' 39 | } 40 | }, 41 | // CSS Sourcemaps off by default because relative paths are "buggy" 42 | // with this option, according to the CSS-Loader README 43 | // (https://github.com/webpack/css-loader#sourcemaps) 44 | // In our experience, they generally work as expected, 45 | // just be aware of this issue when enabling this option. 46 | cssSourceMap: false 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-node-mongodb-project 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /mock/goods.json: -------------------------------------------------------------------------------- 1 | { 2 | "status":"0", 3 | "msg":"", 4 | "result":[ 5 | { 6 | "productId":"10001", 7 | "productName":"小米6", 8 | "salePrice":"2499", 9 | "productImage":"mi6.jpg" 10 | }, 11 | { 12 | "productId":"10002", 13 | "productName":"小米笔记本", 14 | "salePrice":"3999", 15 | "productImage":"note.jpg" 16 | }, 17 | { 18 | "productId":"10003", 19 | "productName":"小米6", 20 | "salePrice":"2499", 21 | "productImage":"mi6.jpg" 22 | }, 23 | { 24 | "productId":"10004", 25 | "productName":"小米6", 26 | "salePrice":"2499", 27 | "productImage":"1.jpg" 28 | }, 29 | { 30 | "productId":"10005", 31 | "productName":"小米6", 32 | "salePrice":"2499", 33 | "productImage":"2.jpg" 34 | }, 35 | { 36 | "productId":"10006", 37 | "productName":"小米6", 38 | "salePrice":"2499", 39 | "productImage":"3.jpg" 40 | }, 41 | { 42 | "productId":"10007", 43 | "productName":"小米6", 44 | "salePrice":"2499", 45 | "productImage":"4.jpg" 46 | }, 47 | { 48 | "productId":"10008", 49 | "productName":"小米6", 50 | "salePrice":"2499", 51 | "productImage":"5.jpg" 52 | } 53 | ] 54 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-node-mongodb-project", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "wuchengcheng", 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 | }, 12 | "dependencies": { 13 | "axios": "^0.16.2", 14 | "ejs": "^2.5.7", 15 | "mongoose": "^4.13.4", 16 | "vue": "^2.4.2", 17 | "vue-infinite-scroll": "^2.0.2", 18 | "vue-lazyload": "^1.1.3", 19 | "vue-resource": "^1.3.4", 20 | "vue-router": "^2.7.0", 21 | "vuex": "^3.0.1" 22 | }, 23 | "devDependencies": { 24 | "autoprefixer": "^7.1.2", 25 | "babel-core": "^6.22.1", 26 | "babel-loader": "^7.1.1", 27 | "babel-plugin-transform-runtime": "^6.22.0", 28 | "babel-preset-env": "^1.3.2", 29 | "babel-preset-stage-2": "^6.22.0", 30 | "babel-register": "^6.22.0", 31 | "chalk": "^2.0.1", 32 | "connect-history-api-fallback": "^1.3.0", 33 | "copy-webpack-plugin": "^4.0.1", 34 | "css-loader": "^0.28.0", 35 | "cssnano": "^3.10.0", 36 | "eventsource-polyfill": "^0.9.6", 37 | "express": "~4.15.5", 38 | "extract-text-webpack-plugin": "^2.0.0", 39 | "file-loader": "^0.11.1", 40 | "friendly-errors-webpack-plugin": "^1.1.3", 41 | "html-webpack-plugin": "^2.28.0", 42 | "http-proxy-middleware": "^0.17.3", 43 | "webpack-bundle-analyzer": "^3.3.2", 44 | "semver": "^5.3.0", 45 | "shelljs": "^0.7.6", 46 | "opn": "^5.1.0", 47 | "optimize-css-assets-webpack-plugin": "^2.0.0", 48 | "ora": "^1.2.0", 49 | "rimraf": "^2.6.0", 50 | "url-loader": "^0.5.8", 51 | "vue-loader": "^13.0.4", 52 | "vue-style-loader": "^3.0.1", 53 | "vue-template-compiler": "^2.4.2", 54 | "webpack": "^2.6.1", 55 | "webpack-dev-middleware": "^1.10.0", 56 | "webpack-hot-middleware": "^2.18.0", 57 | "webpack-merge": "^4.1.0", 58 | "body-parser": "~1.18.2", 59 | "cookie-parser": "~1.4.3", 60 | "debug": "~2.6.9", 61 | "jade": "~1.11.0", 62 | "morgan": "~1.9.0", 63 | "serve-favicon": "~2.4.5" 64 | }, 65 | "engines": { 66 | "node": ">= 4.0.0", 67 | "npm": ">= 3.0.0" 68 | }, 69 | "browserslist": [ 70 | "> 1%", 71 | "last 2 versions", 72 | "not ie <= 8" 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /resource/db: -------------------------------------------------------------------------------- 1 | Goods: 2 | { 3 | "productId":String, 4 | "productName":String, 5 | "salePrice":Number, 6 | "checked":String, 7 | "productNum":Number, 8 | "productImage":String 9 | } 10 | 11 | Users: 12 | { 13 | "userId":String, 14 | "userName":String, 15 | "userPwd":String, 16 | "orderList":Array, 17 | "cartList":[ 18 | { 19 | "productId":String, 20 | "productName":String, 21 | "salePrice":String, 22 | "productImage":String, 23 | "checked":String, 24 | "productNum":String 25 | } 26 | ], 27 | "addressList":[ 28 | { 29 | "addressId": String, 30 | "userName": String, 31 | "streetName": String, 32 | "postCode": Number, 33 | "tel": Number, 34 | "isDefault": Boolean 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /resource/dumall-goods: -------------------------------------------------------------------------------- 1 | {"_id":{"$oid":"58c284b13a1bb9aa7033801b"},"productId":"201710003","productName":"平衡车","salePrice":1999,"productImage":"pingheng.jpg","productUrl":""} 2 | {"_id":{"$oid":"58c284d7117a2e6599abef5e"},"productId":"201710004","productName":"头戴式耳机-3","salePrice":80,"productImage":"2.jpg","productUrl":""} 3 | {"_id":{"$oid":"58c284e6117a2e6599abef5f"},"productId":"201710005","productName":"小米笔记本","salePrice":3549,"productImage":"note.jpg","productUrl":""} 4 | {"_id":{"$oid":"58c284f4117a2e6599abef60"},"productId":"201710006","productName":"小米6","salePrice":2499,"productImage":"mi6.jpg","productUrl":""} 5 | {"_id":{"$oid":"58e704ef98dab115d336b3f1"},"productId":"201710002","productName":"智能插线板","salePrice":59,"productImage":"6.jpg","productUrl":""} 6 | {"_id":{"$oid":"58e7050398dab115d336b3f2"},"productId":"201710007","productName":"自拍杆","salePrice":39,"productImage":"zipai.jpg","productUrl":""} 7 | {"_id":{"$oid":"58e7050c98dab115d336b3f3"},"productId":"201710008","productName":"小米净水器","salePrice":1999,"productImage":"8.jpg","productUrl":""} 8 | {"_id":{"$oid":"58e7051698dab115d336b3f4"},"productId":"201710009","productName":"IH 电饭煲","salePrice":999,"productImage":"9.jpg","productUrl":""} 9 | {"_id":{"$oid":"58e7052198dab115d336b3f5"},"productId":"201710010","productName":"小米电视4A","salePrice":2099,"productImage":"10.jpg","productUrl":""} 10 | {"_id":{"$oid":"58e7052a98dab115d336b3f6"},"productId":"201710011","productName":"Ear1000","salePrice":1000,"productImage":"11.jpg","productUrl":""} 11 | {"_id":{"$oid":"58e7053298dab115d336b3f7"},"productId":"201710012","productName":"Ear1100","salePrice":1100,"productImage":"12.jpg","productUrl":""} 12 | {"_id":{"$oid":"58e7053c98dab115d336b3f8"},"productId":"201710013","productName":"Ear2000","salePrice":2000,"productImage":"13.jpg","productUrl":""} 13 | {"_id":{"$oid":"58e7054798dab115d336b3f9"},"productId":"201710014","productName":"Ear1600","salePrice":1600,"productImage":"14.jpg","productUrl":""} 14 | {"_id":{"$oid":"58e7055198dab115d336b3fa"},"productId":"201710015","productName":"Ear1200","salePrice":1200,"productImage":"15.jpg","productUrl":""} 15 | {"_id":{"$oid":"58e7057798dab115d336b3fb"},"productId":"201710016","productName":"Ear700","salePrice":700,"productImage":"16.jpg","productUrl":""} 16 | {"_id":{"$oid":"58e7058498dab115d336b3fc"},"productId":"201710017","productName":"小钢炮蓝牙音箱","salePrice":129,"productImage":"1.jpg","productUrl":""} 17 | {"_id":{"$oid":"58e7058d98dab115d336b3fd"},"productId":"201710018","productName":"智能摄像机","salePrice":389,"productImage":"photo.jpg","productUrl":""} 18 | -------------------------------------------------------------------------------- /resource/dumall-users: -------------------------------------------------------------------------------- 1 | {"_id":{"$oid":"58c41d5d3eddd93e9ab5b078"},"userId":"100000077","userName":"admin","userPwd":"123456","orderList":[{"orderId":"6224201705302250301","orderTotal":3359,"addressInfo":{"addressId":"100001","userName":"JackBean","streetName":"北京市朝阳区朝阳公园","postCode":100001,"tel":12345678901.0,"isDefault":true},"goodsList":[{"productImage":"mi6.jpg","salePrice":"2499","productName":"小米6","productId":"201710006","_id":{"$oid":"58c284f4117a2e6599abef60"},"productNum":"1","checked":"1"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"7","checked":"1"}],"orderStatus":"1","createDate":"2017-05-30 22:50:30"},{"orderId":"9201706071525282","orderTotal":"5558","orderStatus":1,"_id":{"$oid":"5937aa68adad24614cb310af"},"createDate":"2017-06-07 15:25:28","goodsList":[{"productImage":"mi6.jpg","salePrice":"2499","productName":"小米6","productId":"201710006","_id":{"$oid":"58c284f4117a2e6599abef60"},"productNum":"2"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"7"}]},{"orderId":"7201706081545294","orderTotal":"5558","orderStatus":1,"_id":{"$oid":"59390099c0444831c461d576"},"createDate":"2017-06-08 15:45:29","goodsList":[{"productImage":"mi6.jpg","salePrice":"2499","productName":"小米6","productId":"201710006","_id":{"$oid":"58c284f4117a2e6599abef60"},"productNum":"2"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"7"}]},{"orderId":"7201706131105338","orderTotal":"560","orderStatus":1,"_id":{"$oid":"593f567d366e42108986268a"},"createDate":"2017-06-13 11:05:33","goodsList":[{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"7"}]},{"orderId":"5201706131122131","orderTotal":"30160","orderStatus":1,"_id":{"$oid":"593f5a65366e42108986268b"},"createDate":"2017-06-13 11:22:13","goodsList":[{"productImage":"9.jpg","salePrice":"999","productName":"IH 电饭煲","productId":"201710009","_id":{"$oid":"58e7051698dab115d336b3f4"},"productNum":"3"},{"productImage":"14.jpg","salePrice":"1600","productName":"Ear1600","productId":"201710014","_id":{"$oid":"58e7054798dab115d336b3f9"},"productNum":"1"},{"productImage":"note.jpg","salePrice":"3549","productName":"小米笔记本","productId":"201710005","_id":{"$oid":"58c284e6117a2e6599abef5f"},"productNum":"7"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"9"}]},{"orderId":"8201706131828404","orderTotal":"32367","orderStatus":1,"_id":{"$oid":"593fbe58e1a5b7147605cb33"},"createDate":"2017-06-13 18:28:40","goodsList":[{"productImage":"9.jpg","salePrice":"999","productName":"IH 电饭煲","productId":"201710009","_id":{"$oid":"58e7051698dab115d336b3f4"},"productNum":"5"},{"productImage":"14.jpg","salePrice":"1600","productName":"Ear1600","productId":"201710014","_id":{"$oid":"58e7054798dab115d336b3f9"},"productNum":"1"},{"productImage":"note.jpg","salePrice":"3549","productName":"小米笔记本","productId":"201710005","_id":{"$oid":"58c284e6117a2e6599abef5f"},"productNum":"7"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"10"},{"productImage":"1.jpg","salePrice":"129","productName":"小钢炮蓝牙音箱","productId":"201710017","_id":{"$oid":"58e7058498dab115d336b3fc"},"productNum":"1"}]},{"orderId":"7201706142225144","orderTotal":"2738","orderStatus":1,"_id":{"$oid":"5941474ae1a5b7147605cb34"},"createDate":"2017-06-14 22:25:14","goodsList":[{"productImage":"14.jpg","salePrice":"1600","productName":"Ear1600","productId":"201710014","_id":{"$oid":"58e7054798dab115d336b3f9"},"productNum":"1"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"11"},{"productImage":"1.jpg","salePrice":"129","productName":"小钢炮蓝牙音箱","productId":"201710017","_id":{"$oid":"58e7058498dab115d336b3fc"},"productNum":"2"}]},{"orderId":"1201706142242198","orderTotal":"2738","orderStatus":1,"_id":{"$oid":"59414b4be1a5b7147605cb35"},"createDate":"2017-06-14 22:42:19","goodsList":[{"productImage":"14.jpg","salePrice":"1600","productName":"Ear1600","productId":"201710014","_id":{"$oid":"58e7054798dab115d336b3f9"},"productNum":"1"},{"productImage":"2.jpg","salePrice":"80","productName":"头戴式耳机-3","productId":"201710004","_id":{"$oid":"58c284d7117a2e6599abef5e"},"productNum":"11"},{"productImage":"1.jpg","salePrice":"129","productName":"小钢炮蓝牙音箱","productId":"201710017","_id":{"$oid":"58e7058498dab115d336b3fc"},"productNum":"2"}]},{"orderId":"8201706150102580","orderTotal":"2499","orderStatus":1,"_id":{"$oid":"59416c42e1a5b7147605cb36"},"createDate":"2017-06-15 01:02:58","goodsList":[{"productImage":"mi6.jpg","salePrice":"2499","productName":"小米6","productId":"201710006","_id":{"$oid":"58c284f4117a2e6599abef60"},"productNum":"1"}]},{"orderId":"5201706150146458","orderTotal":"2886","orderStatus":1,"_id":{"$oid":"59417685e1a5b7147605cb37"},"createDate":"2017-06-15 01:46:45","goodsList":[{"productImage":"1.jpg","salePrice":"129","productName":"小钢炮蓝牙音箱","productId":"201710017","_id":{"$oid":"58e7058498dab115d336b3fc"},"productNum":"3"},{"productImage":"mi6.jpg","salePrice":"2499","productName":"小米6","productId":"201710006","_id":{"$oid":"58c284f4117a2e6599abef60"},"productNum":"1"}]},{"orderId":"9201706151140355","orderTotal":"4548","orderStatus":1,"_id":{"$oid":"594201b348d881235342dbc0"},"createDate":"2017-06-15 11:40:35","goodsList":[{"productImage":"9.jpg","salePrice":"999","productName":"IH 电饭煲","productId":"201710009","_id":{"$oid":"58e7051698dab115d336b3f4"},"productNum":"1"},{"productImage":"note.jpg","salePrice":"3549","productName":"小米笔记本","productId":"201710005","_id":{"$oid":"58c284e6117a2e6599abef5f"},"productNum":"1"}]},{"orderId":"1201706151143137","orderTotal":"4548","orderStatus":1,"_id":{"$oid":"5942025148d881235342dbc1"},"createDate":"2017-06-15 11:43:13","goodsList":[{"productImage":"9.jpg","salePrice":"999","productName":"IH 电饭煲","productId":"201710009","_id":{"$oid":"58e7051698dab115d336b3f4"},"productNum":"1"},{"productImage":"note.jpg","salePrice":"3549","productName":"小米笔记本","productId":"201710005","_id":{"$oid":"58c284e6117a2e6599abef5f"},"productNum":"1"}]}],"cartList":[{"productImage":"1.jpg","salePrice":"129","productName":"小钢炮蓝牙音箱","productId":"201710017","_id":{"$oid":"58e7058498dab115d336b3fc"},"productNum":"6","checked":"0"},{"productImage":"mi6.jpg","salePrice":"2499","productName":"小米6","productId":"201710006","_id":{"$oid":"58c284f4117a2e6599abef60"},"productNum":"6","checked":"0"},{"productImage":"9.jpg","salePrice":"999","productName":"IH 电饭煲","productId":"201710009","_id":{"$oid":"58e7051698dab115d336b3f4"},"productNum":"1","checked":"1"},{"productImage":"note.jpg","salePrice":"3549","productName":"小米笔记本","productId":"201710005","_id":{"$oid":"58c284e6117a2e6599abef5f"},"productNum":"1","checked":"1"},{"productImage":"6.jpg","salePrice":"59","productName":"智能插线板","productId":"201710002","_id":{"$oid":"58e704ef98dab115d336b3f1"},"productNum":"1"}],"addressList":[{"addressId":"100001","userName":"JackBean","streetName":"北京市朝阳区朝阳公园","postCode":"100001","tel":"12345678901","isDefault":true},{"addressId":"100004","userName":"Mary","streetName":"北京市朝阳区SOHO","postCode":"100005","tel":"010555555","isDefault":false},{"addressId":"100005","userName":"Donie","streetName":"北京市海淀区西二旗","postCode":"100009","tel":"18710987654","isDefault":false},{"addressId":"100006","userName":"Cherry","streetName":"北京市海淀区回龙观","postCode":"100009","tel":"010655555","isDefault":false},{"addressId":"100007","userName":"Joke","streetName":"北京市朝阳区望京","postCode":"100010","tel":"13619898722","isDefault":false},{"addressId":"100008","userName":"Frank","streetName":"北京市海淀区中关村软件园","postCode":"100011","tel":"10125652345","isDefault":false}],"__v":30} 2 | -------------------------------------------------------------------------------- /resource/goodsList_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/goodsList_spec.png -------------------------------------------------------------------------------- /resource/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/1.jpg -------------------------------------------------------------------------------- /resource/img/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/10.jpg -------------------------------------------------------------------------------- /resource/img/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/11.jpg -------------------------------------------------------------------------------- /resource/img/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/12.jpg -------------------------------------------------------------------------------- /resource/img/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/13.jpg -------------------------------------------------------------------------------- /resource/img/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/14.jpg -------------------------------------------------------------------------------- /resource/img/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/15.jpg -------------------------------------------------------------------------------- /resource/img/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/16.jpg -------------------------------------------------------------------------------- /resource/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/2.jpg -------------------------------------------------------------------------------- /resource/img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/3.jpg -------------------------------------------------------------------------------- /resource/img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/4.jpg -------------------------------------------------------------------------------- /resource/img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/5.jpg -------------------------------------------------------------------------------- /resource/img/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/6.jpg -------------------------------------------------------------------------------- /resource/img/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/7.jpg -------------------------------------------------------------------------------- /resource/img/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/8.jpg -------------------------------------------------------------------------------- /resource/img/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/9.jpg -------------------------------------------------------------------------------- /resource/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/icon.png -------------------------------------------------------------------------------- /resource/img/imooc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/imooc.jpg -------------------------------------------------------------------------------- /resource/img/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/logo.jpg -------------------------------------------------------------------------------- /resource/img/logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/logo1.png -------------------------------------------------------------------------------- /resource/img/mi6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/mi6.jpg -------------------------------------------------------------------------------- /resource/img/note.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/note.jpg -------------------------------------------------------------------------------- /resource/img/ok-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/ok-2.png -------------------------------------------------------------------------------- /resource/img/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/photo.jpg -------------------------------------------------------------------------------- /resource/img/pingheng.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/pingheng.jpg -------------------------------------------------------------------------------- /resource/img/zipai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/img/zipai.jpg -------------------------------------------------------------------------------- /resource/loading/loading-balls.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resource/loading/loading-bars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resource/loading/loading-bubbles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resource/loading/loading-cubes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resource/loading/loading-cylon-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /resource/loading/loading-cylon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /resource/loading/loading-spin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /resource/loading/loading-spinning-bubbles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /resource/loading/loading-spokes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /resource/readme/07/image01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/07/image01.png -------------------------------------------------------------------------------- /resource/readme/07/image02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/07/image02.png -------------------------------------------------------------------------------- /resource/readme/07/image03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/07/image03.png -------------------------------------------------------------------------------- /resource/readme/09/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/1.png -------------------------------------------------------------------------------- /resource/readme/09/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/10.jpg -------------------------------------------------------------------------------- /resource/readme/09/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/11.jpg -------------------------------------------------------------------------------- /resource/readme/09/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/12.jpg -------------------------------------------------------------------------------- /resource/readme/09/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/2.png -------------------------------------------------------------------------------- /resource/readme/09/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/3.png -------------------------------------------------------------------------------- /resource/readme/09/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/4.png -------------------------------------------------------------------------------- /resource/readme/09/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/5.jpg -------------------------------------------------------------------------------- /resource/readme/09/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/6.jpg -------------------------------------------------------------------------------- /resource/readme/09/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/7.jpg -------------------------------------------------------------------------------- /resource/readme/09/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/8.jpg -------------------------------------------------------------------------------- /resource/readme/09/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/09/9.jpg -------------------------------------------------------------------------------- /resource/readme/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/1.jpg -------------------------------------------------------------------------------- /resource/readme/10/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/1.jpg -------------------------------------------------------------------------------- /resource/readme/10/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/10.jpg -------------------------------------------------------------------------------- /resource/readme/10/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/11.jpg -------------------------------------------------------------------------------- /resource/readme/10/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/2.jpg -------------------------------------------------------------------------------- /resource/readme/10/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/3.jpg -------------------------------------------------------------------------------- /resource/readme/10/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/4.jpg -------------------------------------------------------------------------------- /resource/readme/10/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/5.jpg -------------------------------------------------------------------------------- /resource/readme/10/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/6.jpg -------------------------------------------------------------------------------- /resource/readme/10/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/7.png -------------------------------------------------------------------------------- /resource/readme/10/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/8.png -------------------------------------------------------------------------------- /resource/readme/10/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/10/9.jpg -------------------------------------------------------------------------------- /resource/readme/11/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/1.jpg -------------------------------------------------------------------------------- /resource/readme/11/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/2.jpg -------------------------------------------------------------------------------- /resource/readme/11/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/3.jpg -------------------------------------------------------------------------------- /resource/readme/11/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/4.jpg -------------------------------------------------------------------------------- /resource/readme/11/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/5.jpg -------------------------------------------------------------------------------- /resource/readme/11/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/6.jpg -------------------------------------------------------------------------------- /resource/readme/11/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/7.jpg -------------------------------------------------------------------------------- /resource/readme/11/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/11/8.jpg -------------------------------------------------------------------------------- /resource/readme/12/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/1.jpg -------------------------------------------------------------------------------- /resource/readme/12/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/10.jpg -------------------------------------------------------------------------------- /resource/readme/12/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/11.jpg -------------------------------------------------------------------------------- /resource/readme/12/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/12.jpg -------------------------------------------------------------------------------- /resource/readme/12/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/2.jpg -------------------------------------------------------------------------------- /resource/readme/12/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/3.jpg -------------------------------------------------------------------------------- /resource/readme/12/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/4.jpg -------------------------------------------------------------------------------- /resource/readme/12/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/5.jpg -------------------------------------------------------------------------------- /resource/readme/12/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/6.jpg -------------------------------------------------------------------------------- /resource/readme/12/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/7.jpg -------------------------------------------------------------------------------- /resource/readme/12/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/8.jpg -------------------------------------------------------------------------------- /resource/readme/12/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/12/9.jpg -------------------------------------------------------------------------------- /resource/readme/13/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/13/1.jpg -------------------------------------------------------------------------------- /resource/readme/13/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/13/2.jpg -------------------------------------------------------------------------------- /resource/readme/13/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/13/3.jpg -------------------------------------------------------------------------------- /resource/readme/13/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/13/4.jpg -------------------------------------------------------------------------------- /resource/readme/13/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/13/5.jpg -------------------------------------------------------------------------------- /resource/readme/14/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/14/1.jpg -------------------------------------------------------------------------------- /resource/readme/15/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/15/1.jpg -------------------------------------------------------------------------------- /resource/readme/15/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/15/2.jpg -------------------------------------------------------------------------------- /resource/readme/15/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/resource/readme/15/3.jpg -------------------------------------------------------------------------------- /resource/svg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | arrow-short 6 | 7 | 8 | 9 | status-ok 10 | 11 | 12 | 13 | 14 | cart 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /resource/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jacksoft on 17/4/26. 3 | */ 4 | Date.prototype.Format = function (fmt) { 5 | var o = { 6 | "M+": this.getMonth() + 1, //月份 7 | "d+": this.getDate(), //日 8 | "h+": this.getHours(), //小时 9 | "m+": this.getMinutes(), //分 10 | "s+": this.getSeconds(), //秒 11 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 12 | "S": this.getMilliseconds() //毫秒 13 | }; 14 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 15 | for (var k in o) 16 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 17 | return fmt; 18 | } 19 | 20 | module.exports = {}; 21 | -------------------------------------------------------------------------------- /resource/views/address.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | add 15 | 16 | 17 | 18 | ok 19 | 20 | 21 | 22 | edit 23 | 24 | 25 | 26 | delete 27 | 28 | 29 | 30 | 31 | 32 | 33 | clock 34 | 35 | 36 | 37 | question 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 |
47 |

check out

48 |
49 | 50 |
51 |
    52 |
  • Confirm address
  • 53 |
  • View your order
  • 54 |
  • Make payment
  • 55 |
  • Order confirmation
  • 56 |
57 |
58 | 59 | 60 |
61 |

Shipping address

62 |
63 |
64 |
65 |
    66 |
  • 67 |
    68 |
    XXX
    69 |
    朝阳公园
    70 |
    10000000000
    71 |
    72 |
    73 | 74 | 75 | 76 |
    77 |
    78 | Set default 79 |
    80 |
    Default address
    81 |
  • 82 |
  • 83 |
    84 | 85 | 86 | 87 |

    Add new address

    88 |
    89 |
  • 90 |
91 |
92 | 93 | 102 |
103 | 104 | 105 |
106 |

Shipping method

107 |
108 | 111 |
112 |
113 |
    114 |
  • 115 |
    Standard shipping
    116 |
    Free
    117 |
    118 |

    Once shipped,Order should arrive in the destination in 1-7 business days

    119 |
    120 |
  • 121 |
122 |
123 |
124 |
125 | Next 126 |
127 |
128 |
129 |
130 | 131 | 132 | -------------------------------------------------------------------------------- /resource/views/css/login.css: -------------------------------------------------------------------------------- 1 | .regi_form_input{ 2 | position: relative; 3 | height: 42px; 4 | line-height: 42px; 5 | background: none; 6 | margin-bottom: 15px; 7 | font-size: 14px; 8 | overflow: hidden; 9 | border:1px solid #ccc; 10 | padding-bottom: 0; 11 | } 12 | .regi_form_input .icon { 13 | display: inline-block; 14 | float: left; 15 | width: 25px; 16 | height: 29px; 17 | margin: 6px 0 0 14px; 18 | background-position: 4px 5px; 19 | background-image: url("/static/icon.png"); 20 | background-repeat: no-repeat; 21 | } 22 | .regi_form_input .IconPwd { 23 | background-position: -198px 3px; 24 | } 25 | .regi_form_input .regi_login_input{ 26 | position: absolute; 27 | left:45px; 28 | top:0; 29 | padding: 9px 0 10px; 30 | width: 270px; 31 | font-size: 14px; 32 | zoom: 1; 33 | border: none; 34 | color: #333; 35 | /*height: 23px;*/ 36 | line-height: 23px; 37 | background: 0 0!important; 38 | } 39 | .md-title{ 40 | position: absolute; 41 | top: 14px; 42 | line-height: 24px; 43 | padding: 8px 0; 44 | color: #333; 45 | font-size: 18px; 46 | font-weight: 400; 47 | font-style: normal; 48 | } 49 | .login-wrap{ 50 | margin-top:30px; 51 | } 52 | .md-content .btn-login{ 53 | display: block; 54 | height: 38px; 55 | line-height: 38px; 56 | border: 2px solid #009de6; 57 | background: #009de6; 58 | color: #fff; 59 | font-size: 18px; 60 | text-align: center; 61 | } 62 | .btn-login:hover { 63 | background: #61b1ef; 64 | border: 2px solid #61b1ef; 65 | } 66 | .error-wrap .error{ 67 | font-size: 12px; 68 | color: #d31723; 69 | visibility: hidden; 70 | display: block; 71 | padding: 0 0 7px 17px; 72 | line-height: 16px; 73 | height: 16px; 74 | text-align: left; 75 | background: url("/static/icon.png") 0 -100px no-repeat; 76 | } 77 | .md-content .error-wrap .error-show{ 78 | visibility: visible; 79 | height: auto; 80 | } 81 | -------------------------------------------------------------------------------- /resource/views/goodsList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 | 12 | cart 13 | 14 | 15 | 16 | 17 | 18 | 40 |
41 | 49 |
50 |
51 |
52 | Sort by: 53 | Default 54 | Price 55 | Filter by 56 |
57 |
58 | 59 |
60 |
61 |
Price:
62 |
All
63 |
64 | 0 - 100 65 |
66 |
67 | 100 - 500 68 |
69 |
70 | 500 - 1000 71 |
72 |
73 | 1000 - 2000 74 |
75 |
76 |
77 | 78 | 79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 |
    86 |
    87 |
    XX
    88 |
    999
    89 |
    90 | 加入购物车 91 |
    92 |
    93 |
  • 94 |
  • 95 |
    96 | 97 |
    98 |
    99 |
    XX
    100 |
    1000
    101 |
    102 | 加入购物车 103 |
    104 |
    105 |
  • 106 |
  • 107 |
    108 | 109 |
    110 |
    111 |
    XX
    112 |
    500
    113 |
    114 | 加入购物车 115 |
    116 |
    117 |
  • 118 |
  • 119 |
    120 | 121 |
    122 |
    123 |
    XX
    124 |
    2499
    125 |
    126 | 加入购物车 127 |
    128 |
    129 |
  • 130 |
131 |
132 |
133 |
134 |
135 |
136 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /resource/views/orderConfirm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | add2 15 | 16 | 17 | 18 | ok 19 | 20 | 21 | 22 | edit 23 | 24 | 25 | 26 | delete 27 | 28 | 29 | 30 | clock 31 | 32 | 33 | 34 | 35 |
36 |
37 |
38 |

check out

39 |
40 | 41 |
42 |
    43 |
  • Confirm address
  • 44 |
  • View your order
  • 45 |
  • Make payment
  • 46 |
  • Order confirmation
  • 47 |
48 |
49 | 50 | 51 |
52 |

Order content

53 |
54 |
55 |
56 |
57 |
    58 |
  • Order contents
  • 59 |
  • Price
  • 60 |
  • Quantity
  • 61 |
  • Subtotal
  • 62 |
63 |
64 |
    65 |
  • 66 |
    67 |
    68 | 69 |
    70 |
    71 |
    小米6
    72 | 73 |
    74 |
    75 |
    76 |
    2499
    77 |
    78 |
    79 |
    80 |
    81 |
    82 | ×1 83 |
    84 |
    85 |
    In Stock
    86 |
    87 |
    88 |
    89 |
    $2499
    90 |
    91 |
  • 92 |
93 |
94 |
95 | 96 | 97 |
98 |
99 |
    100 |
  • 101 | Item subtotal: 102 | $2499 103 |
  • 104 |
  • 105 | Shipping: 106 | $100 107 |
  • 108 |
  • 109 | Discount: 110 | $0 111 |
  • 112 |
  • 113 | Tax: 114 | $400 115 |
  • 116 |
  • 117 | Order total: 118 | $1999 119 |
  • 120 |
121 |
122 |
123 | 124 |
125 |
126 | 127 |
128 |
129 | 130 |
131 |
132 |
133 |
134 |
135 | 136 | 137 | -------------------------------------------------------------------------------- /resource/views/orderSuccess.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |

check out

14 |
15 | 16 |
17 |
    18 |
  • Confirm address
  • 19 |
  • View your order
  • 20 |
  • Make payment
  • 21 |
  • Order confirmation
  • 22 |
23 |
24 | 25 |
26 |
27 |
28 |

Congratulations!
Your order is under processing!

29 |

30 | Order ID:100000001 31 | Order total:1000 32 |

33 |
34 |
35 | Cart List 36 |
37 |
38 | Goods List 39 |
40 |
41 |
42 |
43 |
44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /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 ejs = require('ejs'); 9 | 10 | var index = require('./routes/index'); 11 | var users = require('./routes/users'); 12 | var goods = require('./routes/goods'); 13 | 14 | var app = express(); 15 | 16 | // view engine setup 17 | app.set('views', path.join(__dirname, 'views')); 18 | app.engine('.html',ejs.__express); // 设置html后缀 19 | app.set('view engine', 'html'); 20 | 21 | // uncomment after placing your favicon in /public 22 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 23 | app.use(logger('dev')); 24 | app.use(bodyParser.json()); 25 | app.use(bodyParser.urlencoded({ extended: false })); 26 | app.use(cookieParser()); 27 | app.use(express.static(path.join(__dirname, 'public'))); 28 | 29 | 30 | // 捕获登录状态 31 | app.use(function(req,res,next){ // 进入路由之前优先进入function 32 | if(req.cookies.userId){ // 有cookies,说明已经登录 33 | next(); 34 | }else{ 35 | console.log(`path:${req.path},originalUrl:${req.originalUrl}`); 36 | // 结果例 => path:/goods/list,originalUrl:/goods/list?page=1&pageSize=8&sort=1&priceLevel=all 37 | if(req.originalUrl =='/users/login' || req.originalUrl == '/users/logout' || req.originalUrl.indexOf('/goods/list')>-1){ // 未登录时可以点击登录login登出logout和查看商品列表 38 | // if(req.originalUrl =='/users/login' || req.originalUrl == '/users/logout' || req.path == '/goods/list'){ // 第二种方法 39 | next(); 40 | }else{ 41 | res.json({ 42 | status:'1001', 43 | msg:'当前未登录', 44 | result:'' 45 | }) 46 | } 47 | } 48 | }) 49 | 50 | 51 | // 一级路由 52 | app.use('/', index); 53 | app.use('/users', users); 54 | app.use('/goods', goods); 55 | 56 | // catch 404 and forward to error handler 捕获404的 57 | app.use(function(req, res, next) { 58 | var err = new Error('Not Found'); 59 | err.status = 404; 60 | next(err); 61 | }); 62 | 63 | // error handler 捕获500状态的 64 | app.use(function(err, req, res, next) { 65 | // set locals, only providing error in development 66 | res.locals.message = err.message; 67 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 68 | 69 | // render the error page 70 | res.status(err.status || 500); 71 | res.render('error'); 72 | }); 73 | 74 | module.exports = app; 75 | -------------------------------------------------------------------------------- /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 | // 对应数据库商品列表数据在resource文件夹的dumall-goods 2 | var mongoose = require('mongoose'); 3 | var Schema = mongoose.Schema; 4 | 5 | // 定义一个Schema 6 | var produtSchema = new Schema({ 7 | 'productId':String, // 或者 'productId':{type:String} 8 | 'productName':String, 9 | 'salePrice':Number, 10 | 'productImage':String, 11 | 12 | // 在列表页点击“加入购物车时”,会获取对应goods商品数据,然后给该商品添加checked和productNum属性,再将该商品添加到购物车列表中,Schema中不定义属性的话是添加不了的。 13 | "checked":String, 14 | "productNum":Number 15 | }) 16 | 17 | // 输出(导出) 18 | module.exports = mongoose.model('good',produtSchema); // 定义一个good商品模型,可以根据这个商品模型调用其API方法。 19 | // 这个模型定义的是数据库dumall的goods集合数据,所以这个model取名good是对应这个集合,连接数据库之后,这个模型会根据名字的复数形式"goods"来查找数据集合。 20 | // module.exports = mongoose.model('good',produtSchema,'goods'); 也可以后面注明链接的是数据库的goods集合 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /server/models/users.js: -------------------------------------------------------------------------------- 1 | // 对应数据库用户数据在resource文件夹的dumall-users 2 | var mongoose = require('mongoose'); 3 | var Schema = mongoose.Schema; 4 | 5 | // 定义一个Schema 6 | var userSchema = new Schema({ 7 | 'userId':String, // 或者 'userId':{type:String} 8 | 'userName':String, 9 | 'userPwd':String, 10 | 'orderList':Array, 11 | 'cartList':[ // 购物车列表 12 | { 13 | "productId":String, 14 | "productName":String, 15 | "salePrice":Number, 16 | "productImage":String, 17 | "checked":String, // 是否选中 18 | "productNum":String // 商品数量 19 | } 20 | ], 21 | "addressList":[ 22 | { 23 | "addressId": String, 24 | "userName": String, 25 | "streetName": String, 26 | "postCode": Number, 27 | "tel": Number, 28 | "isDefault": Boolean 29 | } 30 | ] 31 | }) 32 | 33 | // 输出(导出) 34 | module.exports = mongoose.model('user',userSchema); // 定义一个user模型,可以根据这个模型调用其API方法。 35 | // 这个模型定义的是数据库dumall的users集合数据,所以这个model取名user是对应这个集合,连接数据库之后,这个模型会根据名字的复数形式"users"来查找数据集合。 36 | // module.exports = mongoose.model('user',userSchema,'users'); 也可以后面注明链接的是数据库的goods集合 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /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(); // 拿到express框架的路由 3 | var mongoose = require('mongoose'); 4 | var Goods = require('../models/goods'); 5 | 6 | // 链接MongoDB数据库,数据库的名称叫dumall 7 | mongoose.connect('mongodb://127.0.0.1:27017/dumall'); // 若是带账号密码的:'mongodb://root:123456@127.0.0.1:27017/dumall' 8 | 9 | // 连接成功操作 10 | mongoose.connection.on("connected",function(){ 11 | console.log("MongoDB connected success.") 12 | }) 13 | 14 | // 连接失败操作 15 | mongoose.connection.on("error",function(){ 16 | console.log("MongoDB connected fail.") 17 | }) 18 | 19 | // 连接断开操作 20 | mongoose.connection.on("disconnected",function(){ 21 | console.log("MongoDB connected disconnected.") 22 | }) 23 | 24 | 25 | // 二级路由 26 | // 查询商品列表数据 27 | /* GET goods page. */ 28 | router.get('/list', function(req, res, next) { 29 | // res.send('hello,goods list'); // 测试路由,连接成功页面出现'hello,goods list' 30 | 31 | // express获取请求参数 32 | let page = parseInt(req.param("page")); // get请求数据拿到数据:res.param() 33 | let pageSize = parseInt(req.param("pageSize")); 34 | let priceLevel = req.param("priceLevel"); // 传过来的价格区间 35 | let sort = req.param("sort"); 36 | let skip = (page-1)*pageSize; // 跳过的数据条数,(分页的公式). 37 | var priceGt = '',priceLte = ''; 38 | let params = {}; 39 | if(priceLevel != 'all'){ // 价格区间过滤功能 40 | switch (priceLevel){ 41 | case '0':priceGt=0;priceLte =100;break; 42 | case '1':priceGt=100;priceLte =500;break; 43 | case '2':priceGt=500;priceLte =1000;break; 44 | case '3':priceGt=1000;priceLte =5000;break; 45 | } 46 | params = { 47 | salePrice:{ 48 | $gt:priceGt, 49 | $lte:priceLte 50 | } 51 | } 52 | } 53 | let goodsModel = Goods.find(params).skip(skip).limit(pageSize); // 先查询所有,skip(skip)跳过skip条数据,limit(pageSize)一页多少条数据.即分页功能实现 54 | goodsModel.sort({'salePrice':sort}); // 对价格排序功能 55 | 56 | goodsModel.exec(function(err, doc){ 57 | if(err) { 58 | res.json({ 59 | status:'1', 60 | msg:err.message 61 | }) 62 | }else{ 63 | res.json({ 64 | status:'0', 65 | msg:'', 66 | result:{ 67 | count:doc.length, 68 | list:doc 69 | } 70 | }) 71 | } 72 | }) 73 | 74 | }); 75 | // 启动express 76 | // node server/bin/www 或 pm2方式 或 webstorm 等 77 | // localhost:3000/goods/ // '/goods'是app.js中的一级路由,'/'是本页的二级路由 78 | 79 | 80 | // 加入到购物车 81 | // 是二级路由,一级路由在app.js 82 | router.post("/addCart",function(req, res, next){ 83 | var userId = '100000077', 84 | productId = req.body.productId; // post请求拿到res参数:req.body 85 | var User = require('../models/users.js'); // 引入user模型 86 | 87 | // 查询第一条:拿到用户信息 88 | User.findOne({ 89 | userId:userId // 查询条件 90 | },function(err,userDoc){ 91 | if(err){ 92 | res.json({ 93 | status:"1", 94 | msg:err.message 95 | }) 96 | }else{ 97 | console.log("userDoc"+userDoc); // 用户数据 98 | if(userDoc){ 99 | let goodsItem = ''; 100 | userDoc.cartList.forEach(function(item){ // 遍历用户购物车,判断加入购物车的商品是否已经存在 101 | if(item.productId == productId){ 102 | goodsItem = item; 103 | item.productNum++; // 购物车这件商品数量+1 104 | } 105 | }) 106 | if(goodsItem){ // 若购物车商品已存在 107 | userDoc.save(function (err2,doc2) { 108 | if(err2){ 109 | res.json({ 110 | status:"1", 111 | msg:err2.message 112 | }) 113 | }else{ 114 | res.json({ 115 | status:'0', 116 | msg:'', 117 | result:'suc' 118 | }) 119 | } 120 | }) 121 | }else{ // 若购物车商品不存在,就添加进去 122 | Goods.findOne({productId:productId},function(err1,doc){ // 从商品列表页Goods查询点击加入购物车的那件商品信息 123 | if(err1){ 124 | res.json({ 125 | status:"1", 126 | msg:err1.message 127 | }) 128 | }else{ 129 | if(doc){ 130 | doc.productNum = 1; // 在Goods模型中添加属性,要去models/goods.js的Schema添加这两个属性。 131 | doc.checked = 1; 132 | userDoc.cartList.push(doc); // 添加信息到用户购物车列表中 133 | userDoc.save(function(err2,doc2){ // 保存数据库 134 | if(err2){ 135 | res.json({ 136 | status:"1", 137 | msg:err2.message 138 | }) 139 | }else{ 140 | res.json({ 141 | status:"0", 142 | msg:'', 143 | result:'suc' 144 | }) 145 | } 146 | }) 147 | } 148 | } 149 | }) 150 | } 151 | } 152 | } 153 | }) 154 | }) 155 | 156 | 157 | 158 | module.exports = router; 159 | 160 | -------------------------------------------------------------------------------- /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: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /server/util/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jacksoft on 17/4/26. 3 | * 直接对Date对象原型添加方法 4 | */ 5 | Date.prototype.Format = function (fmt) { 6 | var o = { 7 | "M+": this.getMonth() + 1, //月份 8 | "d+": this.getDate(), //日 9 | "h+": this.getHours(), //小时 10 | "m+": this.getMinutes(), //分 11 | "s+": this.getSeconds(), //秒 12 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 13 | "S": this.getMilliseconds() //毫秒 14 | }; 15 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 16 | for (var k in o) 17 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 18 | return fmt; 19 | } 20 | 21 | module.exports = {}; 22 | -------------------------------------------------------------------------------- /server/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

hello 我是express的html页面

11 | 12 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/Modal.vue: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 38 | -------------------------------------------------------------------------------- /src/components/NavBread.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /src/components/NavFooter.vue: -------------------------------------------------------------------------------- 1 | 2 | 32 | 33 | 38 | 39 | 42 | -------------------------------------------------------------------------------- /src/components/NavHeader.vue: -------------------------------------------------------------------------------- 1 | 2 | 64 | 65 | 146 | 147 | 150 | -------------------------------------------------------------------------------- /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 | 7 | import VueLazyLoad from 'vue-lazyload' // 懒加载 8 | import infiniteScroll from 'vue-infinite-scroll' // 滚动加载 9 | Vue.use(infiniteScroll) 10 | 11 | import Vuex from 'vuex' 12 | Vue.use(Vuex); 13 | 14 | import './assets/css/base.css' 15 | import './assets/css/checkout.css' 16 | import './assets/css/product.css' 17 | 18 | Vue.config.productionTip = false 19 | 20 | Vue.use(VueLazyLoad,{ 21 | loading:"/static/loading-svg/loading-bars.svg" 22 | }) 23 | 24 | // import {currency} from './util/currency' 25 | // Vue.filter("currency",currency); // 定义全局过滤器 26 | 27 | 28 | // 建立store对象 29 | const store = new Vuex.Store({ 30 | state: { 31 | nickName:'', // 用户名 32 | cartCount:0 // 购物车数量 33 | }, 34 | mutations: { // 更改状态 35 | //更新用户信息 36 | updateUserInfo(state, nickName) { 37 | state.nickName = nickName; 38 | }, 39 | updateCartCount(state,cartCount){ 40 | state.cartCount += cartCount; 41 | }, 42 | initCartCount(state,cartCount){ 43 | state.cartCount = cartCount; 44 | } 45 | } 46 | }); 47 | 48 | 49 | /* eslint-disable no-new */ 50 | new Vue({ 51 | el: '#app', 52 | store, // 使用store 53 | router, 54 | template: '', 55 | components: { App } 56 | }) 57 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | import GoodsList from '@/views/GoodsList' // 商品列表 5 | import Cart from '@/views/Cart' // 购物车列表 6 | import Address from '@/views/Address' // 地址列表 7 | import OrderConfirm from '@/views/OrderConfirm' // 订单确认页面 8 | import OrderSuccess from '@/views/OrderSuccess' // 订单成功页面 9 | 10 | Vue.use(Router) 11 | 12 | export default new Router({ 13 | routes: [ 14 | { 15 | path: '/', 16 | name: 'GoodsList', 17 | component: GoodsList 18 | }, 19 | { 20 | path: '/cart', // 购物车列表路由 21 | name: 'Cart', 22 | component: Cart 23 | }, 24 | { 25 | path: '/address', // 地址列表路由 26 | name: 'Address', 27 | component: Address 28 | }, 29 | { 30 | path: '/orderConfirm', // 订单确认页面路由 31 | name: 'OrderConfirm', 32 | component: OrderConfirm 33 | }, 34 | { 35 | path: '/orderSuccess', // 订单成功頁面 36 | name: 'OrderSuccess', 37 | component: OrderSuccess 38 | } 39 | ] 40 | }) 41 | -------------------------------------------------------------------------------- /src/util/currency.js: -------------------------------------------------------------------------------- 1 | // https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/currency.js 2 | 3 | const digitsRE = /(\d{3})(?=\d)/g 4 | /** 5 | * [currency 金额格式化函数] 6 | * @param {[type]} value [传进来的值] 7 | * @param {[type]} currency [货币符号] 8 | * @param {[type]} decimals [小数位数] 9 | * @return {[type]} [description] 10 | */ 11 | export function currency (value, currency, decimals) { 12 | value = parseFloat(value) 13 | if (!isFinite(value) || (!value && value !== 0)) return '' 14 | currency = currency != null ? currency : '$' 15 | decimals = decimals != null ? decimals : 2 16 | var stringified = Math.abs(value).toFixed(decimals) 17 | var _int = decimals 18 | ? stringified.slice(0, -1 - decimals) 19 | : stringified 20 | var i = _int.length % 3 21 | var head = i > 0 22 | ? (_int.slice(0, i) + (_int.length > 3 ? ',' : '')) 23 | : '' 24 | var _float = decimals 25 | ? stringified.slice(-1 - decimals) 26 | : '' 27 | var sign = value < 0 ? '-' : '' 28 | return sign + currency + head + 29 | _int.slice(i).replace(digitsRE, '$1,') + 30 | _float 31 | } 32 | -------------------------------------------------------------------------------- /src/views/OrderConfirm.vue: -------------------------------------------------------------------------------- 1 | 2 | 145 | 146 | 219 | 222 | -------------------------------------------------------------------------------- /src/views/OrderSuccess.vue: -------------------------------------------------------------------------------- 1 | 2 | 46 | 47 | 94 | 97 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/.gitkeep -------------------------------------------------------------------------------- /static/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/1.jpg -------------------------------------------------------------------------------- /static/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/10.jpg -------------------------------------------------------------------------------- /static/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/11.jpg -------------------------------------------------------------------------------- /static/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/12.jpg -------------------------------------------------------------------------------- /static/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/13.jpg -------------------------------------------------------------------------------- /static/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/14.jpg -------------------------------------------------------------------------------- /static/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/15.jpg -------------------------------------------------------------------------------- /static/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/16.jpg -------------------------------------------------------------------------------- /static/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/2.jpg -------------------------------------------------------------------------------- /static/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/3.jpg -------------------------------------------------------------------------------- /static/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/4.jpg -------------------------------------------------------------------------------- /static/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/5.jpg -------------------------------------------------------------------------------- /static/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/6.jpg -------------------------------------------------------------------------------- /static/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/7.jpg -------------------------------------------------------------------------------- /static/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/8.jpg -------------------------------------------------------------------------------- /static/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/9.jpg -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/icon.png -------------------------------------------------------------------------------- /static/imooc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/imooc.jpg -------------------------------------------------------------------------------- /static/loading-svg/loading-balls.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/loading-svg/loading-bars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /static/loading-svg/loading-bubbles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/loading-svg/loading-cubes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/loading-svg/loading-cylon-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /static/loading-svg/loading-cylon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /static/loading-svg/loading-spin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /static/loading-svg/loading-spinning-bubbles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /static/loading-svg/loading-spokes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/logo.png -------------------------------------------------------------------------------- /static/mi6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/mi6.jpg -------------------------------------------------------------------------------- /static/note.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/note.jpg -------------------------------------------------------------------------------- /static/ok-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/ok-2.png -------------------------------------------------------------------------------- /static/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/photo.jpg -------------------------------------------------------------------------------- /static/pingheng.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/pingheng.jpg -------------------------------------------------------------------------------- /static/zipai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccyinghua/vue-node-mongodb-project/2ffc1fc57144f81e0848106a75ab7757816eac31/static/zipai.jpg -------------------------------------------------------------------------------- /test/ES6-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ES6-Demo演示 6 | 9 | 10 | 11 |

ES6-Demo演示

12 |
13 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /test/ES6-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ES6-2Demo演示 6 | 7 | 8 |

9 | ES6-2Demo演示 10 |

11 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /test/ES6.md: -------------------------------------------------------------------------------- 1 | ### 数组的解构 2 | 3 | ```javascript 4 | // 数组的解构 5 | var [a,b] = [3,8,10]; // 数组的分解 6 | console.log(`a:${a},b:${b}`) // a:3,b:8 7 | 8 | var [x,y,z] = "Vue"; // 字符串的分解 9 | console.log(`x:${x},y:${y},z:${z}`); // x:V,y:u,z:e 10 | 11 | var {n,m} = {m:10,n:20}; // 对象的解构,对key进行拆分 12 | console.log(`m:${m},n:${n}`); // m:10,n:20 13 | 14 | function sum([x,y]){ 15 | return x+y; 16 | } 17 | var total = sum([2,8]); 18 | console.log(`total:${total}`); // total:10 19 | ``` 20 | 21 | ### 函数的扩展 22 | 23 | - ##### 函数默认值 24 | 25 | ```javascript 26 | function sum(num1,num2=3){ 27 | return num1+num2; 28 | } 29 | console.log(sum(7)); // 10 30 | ``` 31 | - ##### 函数的Rest参数(...m) 32 | 33 | ```javascript 34 | // ES5 35 | function sum(x,y,z){ 36 | let total = 0; 37 | if(x)total+=x; 38 | if(y)total+=y; 39 | if(z)total+=z; 40 | 41 | console.log(`total:${total}`) 42 | } 43 | sum(5,"",9); // 14 44 | ``` 45 | 46 | ```javascript 47 | // ES6 48 | // 函数的Rest参数 49 | function sum2(...m){ 50 | let total = 0; 51 | for(var i of m){ // ES6-for循坏 52 | total += i; 53 | } 54 | console.log(`total:${total}`) 55 | } 56 | sum2(4,8,9,10); // 31 57 | ``` 58 | - ##### 函数的扩展(...) 59 | 60 | ```javascript 61 | var [x,y] = [4,8] 62 | 63 | console.log(...[4,8]); // 4 8 64 | 65 | let arr1 = [1,3];let arr2 = [4,8]; 66 | console.log("concat:"+arr1.concat(arr2)); 67 | 68 | [...arr1,...arr2] 69 | console.log([...arr1,...arr2]) // [1, 3, 4, 8] 70 | 71 | var [x,...y] = [4,8,10,30] 72 | console.log(x) // 4 73 | console.log(y) // [8, 10, 30] 74 | 75 | let [a,b,c] = "ES6"; 76 | console.log(a) // E 77 | console.log(b) // S 78 | console.log(c) // 6 79 | 80 | let xy = [...'ES6']; 81 | console.log(xy) // ["E", "S", "6"] 82 | ``` 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /test/Promise.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/Promise.js: -------------------------------------------------------------------------------- 1 | // 创造了一个Promise实例 2 | let checkLogin = function(){ 3 | return new Promise(function(resolve,reject){ 4 | let flag = document.cookie.indexOf("userId") > -1 ? true : false ; 5 | if(flag = true){ // 原本是if(flag),if(flag = true)代表给flag赋予了默认值true 6 | resolve({ 7 | status:0, 8 | result:true 9 | }) 10 | }else{ 11 | reject("error"); 12 | } 13 | }) 14 | } 15 | // 另一个Promise实例 16 | let getUserInfo = () =>{ 17 | return new Promise((resolve,reject)=>{ 18 | let userInfo = { 19 | userId:"101" 20 | } 21 | resolve(userInfo); 22 | }) 23 | } 24 | 25 | // 嵌套改成链式调用 26 | checkLogin().then((res)=>{ 27 | if(res.status==0){ 28 | console.log("login success"); // 输出这个,因为flag设为了true 29 | return getUserInfo() 30 | } 31 | }).catch((error)=>{ 32 | console.log(`errrs:${error}`) 33 | }).then((res2)=>{ // 链式调用,不用再嵌套 34 | console.log(`userId:${res2.userId}`) 35 | }) 36 | 37 | // 多个promise实例可用Promise.all() 38 | Promise.all([checkLogin(),getUserInfo()]).then(([res1,res2])=>{ 39 | console.log(`result1:${res1.result},result2:${res2.userId}`) 40 | }) 41 | 42 | // 结果: 43 | // login success Promise.js:39 44 | // result1:true,result2:101 Promise.js:39 45 | // userId:101 Promise.js:34 -------------------------------------------------------------------------------- /test/axios.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | axios插件案列 6 | 7 | 8 | 9 | 10 | 11 |
12 |

axios插件的使用

13 | Get 14 | Post 15 | Http 16 | all 17 |
{{msg}}
18 |
19 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /test/vue-resource.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-resource插件案列 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Vue-resource插件的使用

13 | Get 14 | Post 15 | Jsonp 16 | Http 17 |
{{msg}}
18 |
19 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /test/vuex/vuex1-state.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vuex-state 6 | 7 | 8 | 9 | 10 | 11 |
12 |

msg: {{msg}}

13 | 14 |
15 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /test/vuex/vuex2-mutations.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vuex-Mutations 6 | 7 | 8 | 9 | 10 | 11 |
12 |

msg: {{msg}}

13 | 点击 14 | 15 |
16 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /test/vuex/vuex3-actions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vuex-Actions 6 | 7 | 8 | 9 | 10 | 11 |
12 |

msg: {{msg}}

13 | 点击 14 | 15 |
16 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /test/vuex/vuex4-getters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vuex-Getters 6 | 7 | 8 | 9 | 10 | 11 |
12 |

msg: {{msg}}

13 | 点击 14 | 15 |
16 | 87 | 88 | 89 | --------------------------------------------------------------------------------