路漫漫其修远兮
吾将上下而求索

vue学习:Vue2.0 / Node.js / MongoDB 打造商城系统-8-19章

第8章 MongoDB介绍
8-1 window平台下MongoDB的安装和环境搭建 (27:08)
8-2 Linux平台下安装配置MongoDB (17:44)
8-3 给MongoDB创建用户 (10:57)
貌似用不到,json数据还是要一条一条自己插入


8-4 MongoDB基本语法 (17:02)

库-集合-raw

show dbs 查看数据库
use demo 创建数据库
db.createCollection('user')  创建集合
db.user.insert({id:123,name:'hello'}) 往user集合插入一行
show collections  查看表
db.dropDatabase()  删库
db.user.drop()  删除集合
db.user.find()  查询所有
db.user.find().pretty()  格式化
db.user.findOne()  查询一条
db.user.update()
增加
db.user.insert({userId:101,userName:'andy',userAge:20,class:{name:'imooc',num:10}})
db.user.insert({userId:102,userName:'bob',userAge:22,class:{name:'tshangh',num:20}})
db.user.update({userName:'bob'},{$set:{userAge:30}})
更新子文档
db.user.update({userName:'bob'},{$set:{'class.name':'fudan'}})
查询
db.user.find({userName:'andy'})
db.user.find({'class.name':'fudan'})
年龄大于19
db.user.find({userAge:{$gt:19}}).pretty()
删除
db.user.remove({userId:101})



8-5 表数据设计和插入 (09:25)
数据导入三种方式:1 一条一条插入,2 界面导入,3 命令行命令批量导入
采用第三种方式导入
mongoimport -h 192.168.170.20 -d db_demo -c users --file dumall-users 
mongoimport -h 192.168.170.20 -d db_demo -c goods --file dumall-goods 




第9章 基于Node.js开发商品列表接口
9-1 Node的启动和调试方式 (13:26)

app.js里面定义了两个路由,访问根目录和访问/users目录
app.use('/', indexRouter);
app.use('/users', usersRouter);

分别对应router目录下的两个文件,里面设置具体的子路由
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');



启动后端nodejs的方式,监听在端口:3000

后端项目启动的方式有三种:
1、node server/bin/www
2、通过webstorm进行启动
3、pm2进行启动,主要用在生产,通过pm2进行管理nodejs后端服务



9-2 基于Express实现商品列表查询接口 (27:22)

安装mongo连接扩展
npm install mongoose --save

设置连接mongo地址:server/routes/goods.js  mongoose.connect('mongodb://192.168.170.20:27017/db_demo');

当在router/goods里面定义"/"路径的时候,需要访问:/goods/才可以,是goods路由下面的子路由

在前端项目里面config/index.js里面配置代理,当访问http://localhost:8080/goods的时候会将请求转发到http://localhost:3000/goods,代理到后端服务上面

到这节结束,商品列表就可以正常显示了,下面是请求链接
http://localhost:3000/goods


后端可以了,然后编写前端代码,这里和6.2节配合一块看
安装axios模块:npm install axios

然后下面的代码就可以获取到列表,可以通过前端调试看看能否获取到数据
import axios from 'axios'
export default {
	data(){
		return {
			goodsList: [],
		}
	},
	components:{
		NavHeader,
		NavFooter: NavFooter,
		NavBread,
	},
	mounted() {
		this.getGoodsList();
	},
	methods: {
		getGoodsList(){
			axios.get('/goods').then((response)=>{
				var res = response.data;
				this.goodsList = res.result.list;
			})
		}
	}


修改html里面的遍历
<li v-for="item in goodsList">
	<div class="pic">
		<a href="#"><img v-bind:src="'/static/'+item.productImage" alt=""></a>
	</div>
	<div class="main">
		<div class="name">{{item.productName}}</div>
		<div class="price">{{item.salePrice}}</div>
		<div class="btn-area">
			<a href="javascript:;" class="btn btn--m">加入购物车</a>
		</div>
	</div>
</li>

通过下面的url可正常访问到列表
http://localhost:8080/#/goods

阶段性成功



实现懒加载,看6.3节的内容来实现

点击选中功能如下,为典型的功能,要记住
<dt>Price:</dt>
<dd><a href="javascript:;" v-bind:class="{'cur': priceChecked=='all'}" @click="priceChecked='all'">All</a></dd>
<dd v-for="(price,index) in priceFilter">
	<a href="javascript:void(0)" v-bind:class="{'cur': priceChecked==index}" @click="priceChecked=index">{{price.startPrice}} - {{price.endPrice}}</a>
</dd>


priceFilter: [
	{
		startPrice: '0.00',
		endPrice: '100',
	},
	{
		startPrice: '100.00',
		endPrice: '500.00',
	},
	{
		startPrice: '500,00',
		endPrice: '1000.00',
	},
	{
		startPrice: '1000.00',
		endPrice: '5000.00',
	}
],


当页面模拟手机端,页面非常窄的时候,需要点击上面的’filter by‘来过滤,这里实现这个功能
逻辑:当点击’filter by‘的时候,显示遮罩,弹出菜单。点击遮罩的时候,关闭遮罩,关闭菜单。点击菜单的时候,设定菜单,关闭菜单,关闭遮罩

图片懒加载使用插件:vue-lazyload
https://www.npmjs.com/package/vue-lazyload

安装插件,然后在main.js里面引入插件,这里的loading指的是图片没有加载出来的时候显示的图片
import VueLazyLoad from 'vue-lazyload'

Vue.use(VueLazyLoad, {
    loading: '/static/loading-svg/loading-bars.svg',
});

将js里面有图片的地址修改为
<a href="#"><img v-lazy="'/static/'+item.productImage" alt=""></a>

可以在调试里面将网速设置为3g网络,网速慢些,查看具体的效果



9-3 商品列表分页和排序功能实现(上) (11:14)
这一节是实现后台分页功能,后端代码如下,根据get方法的参数来进行筛选查找排序返回处理
router.get('/', function(req, res, next){
    let page = parseInt(req.param('page'));
    let pageSize = parseInt(req.param('pageSize'));
    let sort = req.param('sort');
    let skip = (page-1)*pageSize;
    let params = {};
    let goodsModel = Goods.find(params).skip(skip).limit(pageSize);
    goodsModel.sort({'salePrice':sort});
    goodsModel.exec(function (err,doc) {
        if(err){
            res.json({
                status:'1',
                msg:err.message
            });
        }else{
            res.json({
                status:'0',
                msg:'',
                result:{
                    count:doc.length,
                    list:doc
                }
            });
        }
    })
});

通过下面的接口测试
http://localhost:3000/goods?page=4&pageSize=5&sort=1




9-4 商品列表分页和排序功能实现(下) (22:22)

前端优化,当返回状态码不为1的时候,将数组清空
axios.get('/goods').then((response)=>{
	var res = response.data;
	if(res.status=='0'){
		this.goodsList = res.result.list;                       
	}else{
		this.goodList = [];
	}

商品分页前端代码如下
getGoodsList(){
	var param = {
		page: this.page,
		pageSize: this.pageSize,
		sort: this.sortFlag? 1:-1,

	};
	axios.get('/goods',{
		params: param,
	}).then((response)=>{
		var res = response.data;
		if(res.status=='0'){
			this.goodsList = res.result.list;
		}else{
			this.goodList = [];
		}

	});
},

遇到一个bug,这一节的图片使用bind指令,排序后会正常显示,使用lazy的时候会出问题
<a href="#"><img v-bind:src="'/static/'+item.productImage" alt=""></a>
<a href="#"><img v-lazy="'static/'+item.productImage" alt=""></a>


实现分页功能,当滑动鼠标的时候自动加载下一页
npm install --save vue-infinite-scroll

在main.js里面使用
import infiniteScroll from  'vue-infinite-scroll'
Vue.use(infiniteScroll);

使用插件:参数说明:
<div class="view-more-normal"
	 v-infinite-scroll="loadMore"  调用方法
	 infinite-scroll-disabled="busy"  当busy为true,禁用方法
	 infinite-scroll-distance="20">   鼠标滚轮滚动多长进行加载
	<img src="./../assets/loading-spinning-bubbles.svg" v-show="loading">
</div>

js代码如下
getGoodsList(flag){
	var param = {
		page: this.page,
		pageSize: this.pageSize,
		sort: this.sortFlag? 1:-1,

	};
	axios.get('/goods',{
		params: param,
	}).then((response)=>{
		var res = response.data;
		if(res.status=='0'){
			if(flag){
				this.goodsList = this.goodsList.concat(res.result.list);
				if(res.result.count==0){
					this.busy = true;
				}else{
					this.busy = false;
				}
			}else{
				this.goodsList = res.result.list;
				this.busy = false;
			}

		}else{
			this.goodList = [];
		}

	});
},

当页面刚加载的时候,设置this.busy = false;开启懒加载,当鼠标滚动20xx的时候,触发loadMore方法,进行异步请求加载,进入方法后先禁用懒加载方法,防止过多加载
getGoodsList需要判断用户是第一次看页面,还是向下滚动时候的加载。当向下滚动加载的时候,数组需要累加,这样才能显示更多的商品
请求完成后,需要判断请求到的数量是否为0,如果是0,表示已经把所有的加载完成,关闭懒加载,否则再将懒加载打开,可以请求下次
这里必须要判断if(res.result.count==0),不然用户一往最下面拉,就会发出请求,显示加载中的图标,很多是不必要的。



9-5 价格过滤功能实现 (14:49)

前端绑定事件将价格等级传入到参数中到后端,链接如下
http://localhost:8080/goods?page=1&pageSize=8&sort=1&priceLevel=2

后端根据不同等级转换,然后查询
let priceGt = '', priceLte = '';
let params = {};
if(priceLevel!='all') {
	switch (priceLevel) {
		case '0':
			priceGt = 0;
			priceLte = 100;
			break;
		case '1':
			priceGt = 100;
			priceLte = 500;
			break;
		case '2':
			priceGt = 500;
			priceLte = 1000;
			break;
		case '3':
			priceGt = 1000;
			priceLte = 5000;
			break;
	}
	params = {
		salePrice: {
			$gt: priceGt,
			$lte: priceLte
		}
	}
}


加载中的这个图标应该是在加载请求方法进入的时候显示,当数据加载完成后将图标隐藏,js里面进行赋值true或者false
下面是html需要修改的地方
<img src="./../assets/loading-spinning-bubbles.svg" v-show="loading">




9-6 加入购物车功能实现 (32:34)


后端添加user model
然后在router里面添加路由:这里先模拟一个用户来测试
router.post("/addCart", function (req,res,next) {
    var userId = '100000077',productId = req.body.productId;

前端:
addCart(productId){
	axios.post('/goods/addCart',{
		productId: productId
	}).then((res)=>{
		var res = res.data;
		if(res.status==0){
			alert('加入购物车');
		}else{
			alert('msg:'+res.msg);
		}
	})
}

测试:会将商品的id当做参数传递到后端
Request URL: http://localhost:8080/goods/addCart
Request Method: POST





第10章 登录模块实现
10-1 登录功能实现 (27:05)

前端设置变量如下:
return {
	userName: 'admin',  默认显示的账号
	userPwd: '123456',  默认显示的密码
	errorTip: false,  当没有输入密码或者密码错误的时候置为true,将密码错误提示显示
	loginModalFlag: false,  置为true,表示要登录,显示登录框,显示遮罩,右上角也会相应变化
	nickName: '',  当用户登录成功,显示在右上角的名字,从后端读取
}
前端js代码如下
login(){
	if(!this.userName || !this.userPwd){
		this.errorTip = true;
		return;
	}
	axios.post('/users/login',{
		userName: this.userName,
		userPwd: this.userPwd,
	}).then((response)=>{
		let res = response.data;
		if(res.status==0){
			this.errorTip = false;
			this.loginModalFlag = false;
			this.nickName = res.result.userName;
		}else{
			this.errorTip = true;
		}
	})
}

单击遮罩退出遮罩
<div class="md-overlay" v-if="loginModalFlag" @click="loginModalFlag=false"></div>

后端代码就是从mongo中读取数据返回




10-2 登出功能实现 (09:33)

登出功能
前端调post接口,返回后将nickName置空,nickName置空后,右上角会相应发生变化,不用干预,自动的
后端将cookie删除




10-3 登录拦截 (22:03)

登录拦截是后端实现的功能,在请求到达后端后,先进行检查
用户cookie中有userId,表示已经登录
当用户未登录的时候,除了几个白名单外,所有的请求都返回未登录提示
app.use(function(req, res, next){
    if(req.cookies.userId){
        next();
    }else{
        if(req.originalUrl=='/users/login' || req.originalUrl=='/user/logout' || req.originalUrl.indexOf('/goods/list')>-1){
            next();
        }else{
            res.json({
                status: '10001',
                msg: '当前未登录',
                result: '',
            })
        }
    }
});


用户登录保持功能
前端需要做的是,当页面刷新重新加载的时候,将调用checkLogin方法,向后端验证该用户是否登录,cookie会随请求发送到后端
后端拿到请求后,检查cookie是否有userId,有的话返回用户名,没有的话就是未登录。
router.get('/checkLogin', function(req, res, next){
    if(req.cookies.userId){
        res.json({
            status: '0',
            msg: '',
            result: req.cookies.userName || '',
        });
    }else{
        res.json({
            status: '1',
            msg: '未登录',
            result: '',
        })
    }
});



10-4 全局模态框组件实现 (21:35)

父组件可以传递属性给子组件
子组件不能改变这个状态,这个状态只能是父组件传递过来的




第11章 购物车模块实现
11-1 购物车列表功能实现 (18:39)
11-2 商品删除功能实现 (20:42)
11-3 商品修改功能实现 (20:27)
11-4 购物车全选和商品实时计算功能实现 (25:26)
第12章 地址模块实现
12-1 地址列表渲染实现 (上) (06:59)
12-2 地址列表渲染功能实现(下) (08:08)
12-3 地址列表切换和展开功能实现 (08:50)
12-4 地址设置默认功能实现 (12:42)
12-5 地址删除功能实现 (18:08)
第13章 订单确认模块实现
13-1 订单确认列表渲染功能实现 (20:05)
13-2 创建订单功能实现 (24:55)
第14章 订单成功模块实现
14-1 订单成功页面功能实现 (18:58)
第15章 基于Vuex改造登录和购物车数量功能
15-1 Vuex基本介绍 (23:55)
15-2 Vuex的语法讲解 (24:15)
15-3 通过Vuex实现登录和购物车数量(上) (23:00)
15-4 通过Vuex实现登录和购物车数量(下) (13:22)
第16章 Webpack使用
16-1 webpack基础介绍 (17:10)
16-2 插件静态部分实现 (16:30)
16-3 插件功能实现 (18:34)
16-4 webpack打包功能实现(上) (19:03)
16-5 webpack打包功能实现(下) (18:07)
16-6 npm插件发布 (07:07)
16-7 webpack多页面构建(上) (25:37)
16-8 webpack多页面构建(下) (17:06)
16-9 webpack多页面构建-第三方库 (11:36)
16-10 webpack多页面构建-抽取公共模块 (21:57)
第17章 线上部署
17-1 线上部署(上) (18:31)
17-2 线上部署(中) (15:53)
17-3 线上部署(下) (16:23)
第18章 课程总结
18-1 课程总结 (21:06)
第19章 针对第六章和第八章大家提出的问题,补充视频
19-1 第六章 修复vue-cli工具不生成dev-server.js文件问题 (10:07)
19-2 第八章 mongodb环境变量配置和mongo版本冲突问题 (31:00)

未经允许不得转载:江哥架构师笔记 » vue学习:Vue2.0 / Node.js / MongoDB 打造商城系统-8-19章

分享到:更多 ()

评论 抢沙发

评论前必须登录!