├── .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 |
13 |
14 |
15 |
20 |
21 |
22 |
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 |
103 |
104 | ```
105 | 考虑到是响应式布局,移动端时点击 Filter by 价格菜单切换,类名"filterby-show"控制价格区间菜单的显示
106 |
107 | ```html
108 | Filter by
109 |
110 |
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
201 |
202 | 
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 | 
46 |
47 | 
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 | 
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 | 
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 | 
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 | 
241 |
242 | 
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 | 
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 | 
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 | 
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 | 
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 |
15 |
--------------------------------------------------------------------------------
/resource/loading/loading-bars.svg:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/resource/loading/loading-bubbles.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/resource/loading/loading-cubes.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/resource/loading/loading-cylon-red.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/resource/loading/loading-cylon.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/resource/loading/loading-spin.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/resource/loading/loading-spinning-bubbles.svg:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/resource/loading/loading-spokes.svg:
--------------------------------------------------------------------------------
1 |
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 |
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 |
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 |
77 |
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 |
109 | The region you selected is not within our delivery area. Please select another shipping address within our delivery areas.
110 |
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 |
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 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
51 |
57 |
58 |
59 |
77 |
78 |
79 |
80 |
81 |
82 | -
83 |
84 |

85 |
86 |
87 |
XX
88 |
999
89 |
92 |
93 |
94 | -
95 |
96 |

97 |
98 |
99 |
XX
100 |
1000
101 |
104 |
105 |
106 | -
107 |
108 |

109 |
110 |
111 |
XX
112 |
500
113 |
116 |
117 |
118 | -
119 |
120 |

121 |
122 |
123 |
XX
124 |
2499
125 |
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 |
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 |
74 |
75 |
78 |
88 |
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 |
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 |
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 |
2 |
3 |
4 |
5 |
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 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
38 |
--------------------------------------------------------------------------------
/src/components/NavBread.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/src/components/NavFooter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
31 |
32 |
33 |
38 |
39 |
42 |
--------------------------------------------------------------------------------
/src/components/NavHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
63 |
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 |
3 |
4 |
5 |
6 |
7 |
8 | Order Confirm
9 |
10 |
11 |
35 |
36 |
37 |
38 |
39 |
check out
40 |
41 |
42 |
43 |
44 | - Confirm address
45 | - View your order
46 | - Make payment
47 | - Order confirmation
48 |
49 |
50 |
51 |
52 |
53 |
Order content
54 |
55 |
56 |
57 |
58 |
59 | - Order contents
60 | - Price
61 | - Quantity
62 | - Subtotal
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
![]()
71 |
72 |
73 |
{{item.productName}}
74 |
75 |
76 |
77 |
78 |
{{item.salePrice | currency('$')}}
79 |
80 |
81 |
82 |
83 |
84 |
85 | ×{{item.productNum}}
86 |
87 |
88 |
In Stock
89 |
90 |
91 |
92 |
93 |
{{(item.salePrice*item.productNum) | currency('$')}}
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | -
105 | Item subtotal:
106 | {{subTotal | currency('$')}}
107 |
108 | -
109 | Shipping:
110 | {{shipping | currency('$')}}
111 |
112 | -
113 | Discount:
114 | {{discount | currency('$')}}
115 |
116 | -
117 | Tax:
118 | {{tax | currency('$')}}
119 |
120 | -
121 | Order total:
122 | {{orderTotal | currency('$')}}
123 |
124 |
125 |
126 |
127 |
128 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
219 |
222 |
--------------------------------------------------------------------------------
/src/views/OrderSuccess.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
check out
10 |
11 |
12 |
13 |
14 | - Confirm address
15 | - View your order
16 | - Make payment
17 | - Order confirmation
18 |
19 |
20 |
21 |
22 |
23 |
24 |
Congratulations!
Your order is under processing!
25 |
26 | Order ID:{{orderId}}
27 | Order total:{{orderTotal|currency('$')}}
28 |
29 |
30 |
31 |
32 | Cart List
33 |
34 |
35 |
36 | Goods List
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
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 |
15 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-bars.svg:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-bubbles.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-cubes.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-cylon-red.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-cylon.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-spin.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-spinning-bubbles.svg:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/static/loading-svg/loading-spokes.svg:
--------------------------------------------------------------------------------
1 |
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 |
--------------------------------------------------------------------------------