最近我实习的公司在作网上商城的一个项目,我负责购物车这一块。这个项目是一个Web项目,没有进行先后端分离,可是又得作手机端,感受好像哪里不对。。。 web框架使用的是SpringMVC,模板框架是FreeMarker,想到之后要作移动端,果断仍是用json来进行数据交互,并无用freemarker。网页静态文件所有写好了,放在了springmvc的Views中。按理来讲仍是进行先后端分离好点的,可是作网页的没接触过Vue,那好吧。。。 因而我就想到在页面直接引入Vue,但是又是在内网环境开发,只好在本身我的笔记本上下载vue.js再拷贝到内网电脑上进行页面上的引入。html
首先让咱们看一下静态页面的效果图:vue
一,建立一个Vue对象,设置好数据。git
var cart; //全局Vue对象
//经过封装一个方法来建立Vue对象
function createVue(list) { //传入经过后台获取的list
cart = new Vue({
el:'#cart',
data(){
return {
list:list //商品列表
}
}
});
}
复制代码
二,假设从后台请求到数据,而后赋值到Vue对象中github
window.onload = function () {
//请求后台代码 。。。。
//请求成功后将得到的list赋值给cart的list
let list = [
{
goodsTitle: "卫龙辣条", //商品名
specifications: "大包", //商品规格
unitPrice: "5", //商品单价
subimage1Filename :"20180317eeftyd.jpg", //商品图片名
purchaseQuantity: 6 //商品数量
},
{
goodsTitle: "雕牌洗衣粉",
specifications: "大包",
unitPrice: "13",
subimage1Filename: "20180317ggptfg.jpg",
purchaseQuantity: 1
},
{
goodsTitle: "旺仔牛奶",
specifications: "20盒装",
unitPrice: "45",
subimage1Filename: "20180317feftyp.jpg",
purchaseQuantity: 1
}];
createVue(list); //执行建立Vue对象方法
}
);
复制代码
三,修改html部分代码,将数据展现出来web
<tr v-for="(item,index) in list">
<td>
<input type="checkbox" :id="'check'+index" name="checkboxs" />
<label :for="'check'+index"></label>
</td>
<td>
<img :src="'路径前缀/'+item.subimage1Filename" />
</td>
<td style="text-align:left;">
<p>{{item.goodsTitle}}</p>
<p>规格:{{item.specifications}}</p>
</td>
<td>¥{{item.unitPrice}}</td>
<td class="adddel">
<em v-on:click="minius(index)">-</em>
<input type="number" v-model.number="item.purchaseQuantity" />
<em v-on:click="add(index)">+</em>
</td>
<td>¥{{item.unitPrice * item.purchaseQuantity}}</td>
<td><button v-on:click="checkDel(index)">删除</button></td>
</tr>
复制代码
这样就能将单个商品部分所有循环打印出来,而且将对应的信息打印在对应位置。效果图以下:spring
cart = new Vue({
el: '#cart',
data() {
return {
list: list,
checkeds: new Array(list.length) //初始化成list的长度
}
});
复制代码
而后在html中将商品对应的checkbox与checkeds绑定起来,修改后的代码以下:json
<input type="checkbox" :id="'check'+index" name="checkboxs" v-model="checkeds[index]" />
复制代码
利用computed属性计算价格总和:后端
sum () {
let sum = 0;
for (let i in this.list) {
if (this.checkeds[i]) //若是checkeds[i]的结果为truth,则进行累加
sum += this.list[i].unitPrice * this.list[i].purchaseQuantity;
}
return sum;
}
复制代码
HTML部分,咱们在对应位置用{{sum}}带入就能进行显示了。这样就能实现计算勾选过的商品小计之和了。接下来实现全选功能,在methods属性中添加一个方法checkAll,具体代码以下:数组
checkAll (event) { //这里的event就是全选checkbox对象
if (event.checked) { //若是全选的checkbox选中,将checkeds全部的值设置为true,对应商品checkbox的选中状态自动更新
for (let i = 0; i < this.checkeds.length; i++) {
Vue.set(this.checkeds, i, true);
}
else { //不然就进行与上面相反的操做
for (let i = 0; i < this.checkeds.length; i++) {
Vue.set(this.checkeds, i, false);
}
}
}
复制代码
通过上面的一波操做,已经能够实现全选和点选时候的价格之和计算。咱们还要统计商品选中的数量,这个很简单,一样使用computed属性,对checkeds中结果为truth的进行统计就行了,代码以下:bash
checkNum: function () {
let num = 0;
for (let i in this.checkeds) {
if (this.checkeds[i]) {
num++;
}
}
return num;
}
复制代码
而后在html中的对应位置用{{checkNum}}代入便可。如今咱们已经实现了近一半需求,让咱们继续完成他们吧! 五,实现购物车物品单个删除功能,这个就很简单啦,咱们在methods中增长一个del方法,使用js数组的splice方法就能够实现。
del (index) {
this.list.splice(index, 1); //只须要从数组中移除对应项,视图会自动更新,不得不说,Vue太棒啦!
this.checkeds.splice(index,1); //同时删除对应的选中状态标识
}
复制代码
而后就是给删除按钮绑定点击事件(index是循环列表时候的下标):
<button v-on:click="del(index)">删除</button>
复制代码
这样咱们就轻松实现了删除单个商品的需求,固然防止用户误删,在用户点击删除按钮时咱们能够弹出一个确认框提示用户,这里咱们就不去实现了。 六,实现购物车单个商品的数量增长,减小,并实时更新商品的小计。首先在methods中添加增长方法add和减小方法minius:
add (index) {
this.list[index].purchaseQuantity++; //这里按理来讲应该查询后台对应商品库存量来进行限制的,这里不涉及到后台因此没加
},
minius (index) {
if (this.list[index].purchaseQuantity > 1) { //这里添加一个限制,最少要有一个商品
this.list[index].purchaseQuantity--;
}
}
复制代码
而后咱们在对应的加和减的按钮上绑定事件来触发这两个方法(index为列表循环时候的下标):
<td class="adddel">
<em v-on:click="minius(index)">-</em>
<input type="number" v-model.number="item.purchaseQuantity" />
<em v-on:click="add(index)">+</em>
</td>
<td>¥{{item.unitPrice * item.purchaseQuantity}}</td>
复制代码
从上面的代码能够看到咱们在小计一栏直接进行商品单价和数量相乘,这样就能够实现实时更新了。
一,如何实现批量删除? 二,在全选以后,咱们取消了一个商品的状态,全选框的选中状态仍然是选中的,此时应该是不选中的,或者当咱们一个一个把商品的选中状态所有勾选,全选框的状态仍然是补选中的,此时应该是选中状态(以下两图所示),这个现象如何解决?
本文的全部代码已经托管到GitHub,若是本文代码有误,请以GitHub上的为准,GitHub地址:github.com/cyixlq/vue_…