视频学习网址: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实现购物车和地址选配功能》的总结的更多相关文章

  1. VUE2.0实现购物车和地址选配功能学习第一节(来源--慕课网河畔一角)

    第一节  vue知识 vue-resource:和后台交互的一个插件,实现get.post和jsonp等功能.(替代jQuery) vue特点: 1.易用:通过创建vue实例,{{}}绑定数据十分方便 ...

  2. VUE2.0实现购物车和地址选配功能学习第七节

    第七节 卡片选中,设置默认 1.卡片选中html:<li v-for="(item,index) in filterAddress" v-bind:class="{ ...

  3. VUE2.0实现购物车和地址选配功能学习第六节

    第六节 地址列表过滤和展开所有的地址 html:<li v-for="(item,index) in filterAddress">js: new Vue({ el:' ...

  4. VUE2.0实现购物车和地址选配功能学习第五节

    第五节 单件商品金额计算和单选全选功能 1.vue精髓在于操作data模型来改变dom,渲染页面,而不是直接去改变dom 2.加减改变总金额功能: html:<div class="c ...

  5. VUE2.0实现购物车和地址选配功能学习第四节

    第四节 v-on实现金额动态计算 用¥金额 进行格式处理,可以使用原生js进行转换,但是在vuei,使用filter过滤器更加方便 注: 1.es6语法=>和import等 好处在于res参数后 ...

  6. VUE2.0实现购物车和地址选配功能学习第三节

    第三节 使用v-for渲染商品列表 1.使用vue-resource插件引入json数据 (注:在谷歌中调试打断点-- ,console还可以输出vm,res等属性列表,或者productList等一 ...

  7. VUE2.0实现购物车和地址选配功能学习第二节

    第二节 创建VUE实例 购物车项目计划: 1.创建一个vue实例 2.通过v-for指令渲染产品数据 3.使用filter对金额和图片进行格式化 4.使用v-on实现产品金额动态计算 5.综合演示 ① ...

  8. vue2.0实现购物车功能

    购物车功能是一件比较繁琐的事情,逻辑功能太多,今天就用vue2.0实现一个简单的购物车功能,数据都本地自己写的假数据 功能列表: 1.全选和单选结算 2.减少和增加数量 3.商品的删除 界面搭建以及布 ...

  9. vue购物车和地址选配(三)

    参考资料:vue.js官网 项目演示: 项目源代码: 核心代码及踩坑 删除: new Vue({ el:'#app', data:{ productlist:[], totalMoney:0, che ...

随机推荐

  1. Spring的基本应用(1):依赖以及控制反转

    在说到这里的时候,首先要说下程序的耦合和解耦,以便对上节做一个解释. 一.程序的耦合和解耦 1.程序的耦合性(Copling) (1)程序的耦合性,也叫做耦合度,是对模块之间关联程度的度量,耦合性的强 ...

  2. 简单易用的字符串模糊匹配库Fuzzywuzzy

    简单易用的字符串模糊匹配库Fuzzywuzzy 阅读目录 FuzzyWuzzy 简介 安装 用法 已知移植 FuzzyWuzzy 简介 FuzzyWuzzy 是一个简单易用的模糊字符串匹配工具包.它依 ...

  3. PAT Basic 1003 我要通过! (20 分)

    “答案正确”是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”. 得到“答案正确”的条件是: ...

  4. Some notes of An Insider's Guide to TOEFL iBT

    尽早把托福这个坑填上方是正道,在正式上托福课之前阅读了这本Guide,颇受启发——只要是考试,总是有固定的方法的= = An Insider's Guide to TOEFL iBT It is NO ...

  5. @InitBinder的作用

    由@InitBinder表示的方法,可以对WebDataBinder对象进行初始化.WebDataBinder是DataBinder的子类,用于完成由表单到JavaBean属性的绑定. @InitBi ...

  6. Spring Boot安全设计的配置

    Web应用的安全管理,包括两个方面:一是用户身份认证,即用户登录的设计:另一方面是用户的授权,即一个用户在一个应用系统中能够执行哪些操作的权限管理.我这里使用spring-cloud-security ...

  7. sqlalchemy 中的get_or_404

  8. :last-child的坑-CSS3选择器

    CSS3选择器之:last-child - Eric 真实经历 最近开发项目的时候发现了一个这么多年忽略的问题,和大家分享一下.项目使用的是Antd组件库,有一个搜索框是这样的: 为了保证下拉框的内容 ...

  9. Spring资源

    资源 官网:http://spring.io 文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/.htt ...

  10. [深度学习] pytorch学习笔记(3)(visdom可视化、正则化、动量、学习率衰减、BN)

    一.visdom可视化工具 安装:pip install visdom 启动:命令行直接运行visdom 打开WEB:在浏览器使用http://localhost:8097打开visdom界面 二.使 ...