关于慕课网《使用vue2.0实现购物车和地址选配功能》的总结
视频学习网址:http://www.imooc.com/learn/796
源码打包:https://codeload.github.com/fachaoshao/Vue-ShoppingCart/zip/master(before为老师未写功能的源码,after为实现功能后的源码);
注意:以上源码请在 Apache 打开状态打开浏览;
该教程在功能上实现了:
1)将 .json文件数据发送http请求,通过遍历数组将数据渲染到页面;
2)创建过滤器实现了价格加“¥”和保留2位小数,分局部过滤器和全局过滤器;
3)实现了全选和取消全选的功能,通过v-bind:class
4)实现商品金额的计算和删除功能;
5)收货地址的卡片选择和设置默认地址;
下面说说我在该课程中get到的知识
在近期对 Vue 2.0 轮番轰炸般的学习之后,了解到 vue 这个框架是一个轻量级、高性能的js框架,在处理高并发的事件时vue较原生js或者jquery具有非常好的优势,因为他是一个MVVM模式(Model-View-ViewModel)的一个设计模式,以数据驱动为为核心思想,当数据发生变化的时候,用户界面发生相应的变化,开发者不需要手动的去修改dom.也就是说,vuejs帮我们封装了数据和dom对象操作的映射,我们只需要关心数据的逻辑处理,数据的变化就能够自然的通知页面进行页面的重新渲染。
MVVM框架
Vuejs的数据驱动是通过MVVM这种框架来实现的。MVVM框架主要包含3个部分:model、view和 viewmodel。
Model:指的是数据部分,对应到前端就是javascript对象
View:指的是视图部分,对应前端就是dom
Viewmodel:就是连接视图与数据的中间件
数据(Model)和视图(View)是不能直接通讯的,而是需要通过ViewModel来实现双方的通讯。当数据变化的时候,viewModel能够监听到这种变化,并及时的通知view做出修改。同样的,当页面有事件触发时,viewMOdel也能够监听到事件,并通知model进行响应。Viewmodel就相当于一个观察者,监控着双方的动作,并及时通知对方进行相应的操作,这样就形成了以数据的双向绑定。
数据响应原理
数据(model)改变 驱动 视图(view)自动更新
首先,vuejs在实例化的过程中,会对遍历传给实例化对象选项中的data 选项,遍历其所有属性并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
同时每一个实例对象都有一个watcher实例对象,他会在模板编译的过程中,用getter去访问data的属性,watcher此时就会把用到的data属性记为依赖,这样就建立了视图与数据之间的联系。当之后我们渲染视图的数据依赖发生改变(即数据的setter被调用)的时候,watcher会对比前后两个的数值是否发生变化,然后确定是否通知视图进行重新渲染。
这样就实现了所谓的数据对于视图的驱动。
下面详细说下慕课网《使用vue2.0实现购物车和地址选配功能》功能实现的总结
1)将 .json文件数据发送http请求,通过遍历数组将数据渲染到页面;
在methods:里面定义方法:发送http请求,获得json数据
cartView: function () {
// var _this = this;
this.$http.get('data/cartData.json').then(res=>{
//此处使用了箭头函数,使得内部的this与外部this保持一致,可以不用上面声明的
//_this了
this.productList = res.data.result.list;
// this.totalMoney = res.data.result.totalMoney;
})
},
使用了v-for,v-model,v-bind(:),v-if,v-on(@click)等基本api指令,将数据渲染到页面
2)创建过滤器实现了价格加“¥”和保留2位小数,分局部过滤器和全局过滤器;
局部过滤器,写在new Vue({})的 选项 里面
filters:{// 局部过滤器,在作用域内调用
formatMoney:function(value){
return "¥"+value.toFixed(2)+ '元'
}
}
通过管道符号改变数据内容 {{ item.productPrice | formatMoney }} ¥19.00元
全局过滤器
Vue.filter('money',function(value,type) {// 全局过滤器,在全局范围内可用
return "¥"+value.toFixed(2) + type;
});
通过管道符号改变数据内容 {{totalMoney | money('元')}} ¥256.00元 区别于局部过滤器,在vue2.0中,定义的全局过滤器是一个函数,money中传入的参数 “元” 是第二个参数 type,
参考(https://cn.vuejs.org/v2/guide/migration.html#过滤器参数符号-变更)
3)实现了全选和取消全选的功能,通过v-bind:class
单选按钮:
<a href="javascript:;" class="item-check-btn" v-bind:class="{'check':item.checked}"
v-on:click="selectedProduct(item)"
>
selectedProduct: function (item) {
if(typeof item.checked == "undefined"){
// Vue.set(item,'checked',true); // 全局注册
this.$set(item,'checked',true)
}else{
item.checked = !item.checked;
};
this.calcTotalPrice();
},
如果item里面的checked不存在,就给他注册一个变量(一般都是在data里面注册一个变量的),并且设置值为true,这样在页面就可以显示被选中状态;
全选/取消全选按钮:
绑定一个点击函数,传值为true,就全选,false就取消全选
注意到:var _this = this;是es5的语法。要是采用es6的箭头函数,内部this就和外部this保持一致了
这里的思路是:传入的flag(true/false)保存在checkAllFlag中,遍历productList item.checked没被创建,我创建一个,设置他们的值都为checkAllFlag,若创建了,直接设置为checkAllFlag。这个遍历的过程就达到了一个
全选/取消全选 的目的。
<span class="item-check-btn" :class="{'check':checkAllFlag}" @click="checkAll(true)">全选按钮
<a href="javascript:void 0" class="item-del-btn" @click="checkAll(false)">取消全选按钮
checkAll: function (flag) {
this.checkAllFlag = flag;
var _this = this;
this.productList.forEach(function(item,index){
if(typeof item.checked == "undefined"){
// Vue.set(item,'checked',true); // 全局注册
_this.$set(item,'checked',_this.checkAllFlag)
}else{
item.checked = _this.checkAllFlag
}
});
this.calcTotalPrice();
},
4)实现商品金额的计算和删除功能;
这里有单个商品的金额计算和总金额的计算
单个商品的金额计算:{{ item.productPrice * item.productQuantity | money('元')}}
总金额的计算:{{totalMoney | money('元')}}
然后就是改变单个商品数量以及选中商品或者全选商品,要是的总金额动态改变
首先定义一个函数:calcTotalPrice,设置this.totalMoney = 0;为什么呢?因为你每次金额变更前都得把总金额设置为0吧,不然在前面的基础上运算,比如我前面点击选中了,总金额变了,然后我取消了,总金额依然是之前的,所以得设置this.totalMoney = 0,每次计算前清0;
遍历数组productList
_this.totalMoney += item.productPrice*item.productQuantity; 叠加数组红所有商品金额就是总金额了
之后考虑选中与未选中以及全选和取消全选导致的总金额变化,所以他们都得调一次this.calcTotalPrice();实现总金额的计算;
changeMoney:function (product,way) {
if(way>0){
product.productQuantity++;
}else{
product.productQuantity--;
if(product.productQuantity < 1){
product.productQuantity = 1
}
};
this.calcTotalPrice();
},
selectedProduct: function (item) {
if(typeof item.checked == "undefined"){
// Vue.set(item,'checked',true); // 全局注册
this.$set(item,'checked',true)
}else{
item.checked = !item.checked;
};
this.calcTotalPrice();
},
checkAll: function (flag) {
this.checkAllFlag = flag;
var _this = this;
this.productList.forEach(function(item,index){
if(typeof item.checked == "undefined"){
// Vue.set(item,'checked',true); // 全局注册
_this.$set(item,'checked',_this.checkAllFlag)
}else{
item.checked = _this.checkAllFlag
}
});
this.calcTotalPrice();
},
calcTotalPrice:function(){
var _this = this;
this.totalMoney = 0;
this.productList.forEach(function(item,index){
if(item.checked){
_this.totalMoney += item.productPrice*item.productQuantity;
}
});
},
5)收货地址的卡片选择和设置默认地址;
首先依然是遍历出 .json里面的地址,注意到这里的 v-for="(address,index) in filterAddress",相比angular中的ng-repeat = "(index,address) in
filterAddress" , angularjs是先写下标,再写值,注意啊,正好相反。vue 1.0中也是(index,address)与angualr相同;
这里我就把js代码都放上来了,不分段截取了
可以看到也是先发送$http请求,获取数据,注意获取的数据保存在response.data中,而不是子response中,做项目是可以查看下;
为了做加载更多,我们先让它显示3条数据,所以我们设置limitNum:3, 在computed中 return this.addressList.slice(0,this.limitNum),所有我们得遍历filterAddress 的数据,当我们点击more时,@click="loadMore",触发loadMore函数,this.limitNum
= this.addressList.length,就可以加载addressList中所有的地址了
卡片地址选择:把点击的index赋值给currentIndex,当index==currentIndex时,显示被选中,这个挺重要的
<li v-for="(address,index) in filterAddress" :class="{'check':index == currentIndex}"
@click="currentIndex = index">
new Vue({
el:'.container',
data:{
addressList:[],
limitNum:3,
currentIndex:0,
shippingMethods:1
},
mounted: function () {
this.$nextTick(function () {
this.getAddressList()
})
},
methods:{
getAddressList:function(){
this.$http.get("data/address.json").then(response=>{
console.log(response)
var res = response.data;
this.addressList = res.result;
})
},
loadMore:function(){
this.limitNum = this.addressList.length
},
setDefault:function(addressId){
this.addressList.forEach(function(address,index){
if(address.addressId == addressId){
address.isDefault = true;
}else{
address.isDefault = false;
}
})
}
},
computed:{
filterAddress:function(){
return this.addressList.slice(0,this.limitNum)
}
}
})
设置默认地址:
v-if="!address.isDefault" @click="setDefault(address.addressId)">设为默认
<div class="addr-opration addr-default" v-if="address.isDefault">默认地址
v-if控制显示与隐藏,当点击设为默认触发setDefault,传的addressId值,设置当前点击的addressId为默认地址
最后就是配送方式了
<li v-bind:class="{'check':shippingMethods == 1}" @click="shippingMethods=1">标准配送
<li class="name" v-bind:class="{'check':shippingMethods == 2}" @click="shippingMethods=2">高级配送
选中状态为check,标准配送 shippingMethods == 1决定check显示选中,当点击标准配送时shippingMethods == 1,
当点击高级配送时shippingMethods == 2,通过修改shippingMethods值决定显示谁!
上述文字都是个人见解,不当之处,还请各位指正!
参考文献:
https://cn.vuejs.org/v2/guide/reactivity.html
http://www.cnblogs.com/caizhenbo/p/6418284.html
http://www.cnblogs.com/caizhenbo/p/6710174.html
关于慕课网《使用vue2.0实现购物车和地址选配功能》的总结的更多相关文章
- VUE2.0实现购物车和地址选配功能学习第一节(来源--慕课网河畔一角)
第一节 vue知识 vue-resource:和后台交互的一个插件,实现get.post和jsonp等功能.(替代jQuery) vue特点: 1.易用:通过创建vue实例,{{}}绑定数据十分方便 ...
- VUE2.0实现购物车和地址选配功能学习第七节
第七节 卡片选中,设置默认 1.卡片选中html:<li v-for="(item,index) in filterAddress" v-bind:class="{ ...
- VUE2.0实现购物车和地址选配功能学习第六节
第六节 地址列表过滤和展开所有的地址 html:<li v-for="(item,index) in filterAddress">js: new Vue({ el:' ...
- VUE2.0实现购物车和地址选配功能学习第五节
第五节 单件商品金额计算和单选全选功能 1.vue精髓在于操作data模型来改变dom,渲染页面,而不是直接去改变dom 2.加减改变总金额功能: html:<div class="c ...
- VUE2.0实现购物车和地址选配功能学习第四节
第四节 v-on实现金额动态计算 用¥金额 进行格式处理,可以使用原生js进行转换,但是在vuei,使用filter过滤器更加方便 注: 1.es6语法=>和import等 好处在于res参数后 ...
- VUE2.0实现购物车和地址选配功能学习第三节
第三节 使用v-for渲染商品列表 1.使用vue-resource插件引入json数据 (注:在谷歌中调试打断点-- ,console还可以输出vm,res等属性列表,或者productList等一 ...
- VUE2.0实现购物车和地址选配功能学习第二节
第二节 创建VUE实例 购物车项目计划: 1.创建一个vue实例 2.通过v-for指令渲染产品数据 3.使用filter对金额和图片进行格式化 4.使用v-on实现产品金额动态计算 5.综合演示 ① ...
- vue2.0实现购物车功能
购物车功能是一件比较繁琐的事情,逻辑功能太多,今天就用vue2.0实现一个简单的购物车功能,数据都本地自己写的假数据 功能列表: 1.全选和单选结算 2.减少和增加数量 3.商品的删除 界面搭建以及布 ...
- vue购物车和地址选配(三)
参考资料:vue.js官网 项目演示: 项目源代码: 核心代码及踩坑 删除: new Vue({ el:'#app', data:{ productlist:[], totalMoney:0, che ...
随机推荐
- Spring的基本应用(1):依赖以及控制反转
在说到这里的时候,首先要说下程序的耦合和解耦,以便对上节做一个解释. 一.程序的耦合和解耦 1.程序的耦合性(Copling) (1)程序的耦合性,也叫做耦合度,是对模块之间关联程度的度量,耦合性的强 ...
- 简单易用的字符串模糊匹配库Fuzzywuzzy
简单易用的字符串模糊匹配库Fuzzywuzzy 阅读目录 FuzzyWuzzy 简介 安装 用法 已知移植 FuzzyWuzzy 简介 FuzzyWuzzy 是一个简单易用的模糊字符串匹配工具包.它依 ...
- PAT Basic 1003 我要通过! (20 分)
“答案正确”是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”. 得到“答案正确”的条件是: ...
- Some notes of An Insider's Guide to TOEFL iBT
尽早把托福这个坑填上方是正道,在正式上托福课之前阅读了这本Guide,颇受启发——只要是考试,总是有固定的方法的= = An Insider's Guide to TOEFL iBT It is NO ...
- @InitBinder的作用
由@InitBinder表示的方法,可以对WebDataBinder对象进行初始化.WebDataBinder是DataBinder的子类,用于完成由表单到JavaBean属性的绑定. @InitBi ...
- Spring Boot安全设计的配置
Web应用的安全管理,包括两个方面:一是用户身份认证,即用户登录的设计:另一方面是用户的授权,即一个用户在一个应用系统中能够执行哪些操作的权限管理.我这里使用spring-cloud-security ...
- sqlalchemy 中的get_or_404
- :last-child的坑-CSS3选择器
CSS3选择器之:last-child - Eric 真实经历 最近开发项目的时候发现了一个这么多年忽略的问题,和大家分享一下.项目使用的是Antd组件库,有一个搜索框是这样的: 为了保证下拉框的内容 ...
- Spring资源
资源 官网:http://spring.io 文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/.htt ...
- [深度学习] pytorch学习笔记(3)(visdom可视化、正则化、动量、学习率衰减、BN)
一.visdom可视化工具 安装:pip install visdom 启动:命令行直接运行visdom 打开WEB:在浏览器使用http://localhost:8097打开visdom界面 二.使 ...