vuejs手把手教你寫一個(gè)完整的購(gòu)物車實(shí)例代碼
由于我們公司是主營(yíng)業(yè)務(wù)是海淘,所以每個(gè)項(xiàng)目都是類似淘寶天貓之類的商城,那么購(gòu)物車就是一個(gè)重點(diǎn)開(kāi)發(fā)功能模塊。介于之前我都是用jq來(lái)寫購(gòu)物車的,這次就用vuejs來(lái)寫一個(gè)購(gòu)物車。下面我就從全選,數(shù)量控制器,運(yùn)費(fèi),商品金額計(jì)算等方法來(lái)演示一下一個(gè)能用在實(shí)際場(chǎng)景的購(gòu)物車是怎么做出來(lái)的以及記錄一下這次用vuejs踩過(guò)的坑。
1.一層數(shù)據(jù)結(jié)構(gòu)-全選
下面這段代碼和vuejs官網(wǎng)里面checkbox綁定很像。不明白的可以直接上vuejs官網(wǎng)看看。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs-全選</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
a {
color: #333;
text-decoration:none;
}
</style>
</head>
<body>
<label>
<input type="checkbox" name="all" v-on:click="chooseAll" v-model="selectArr.length==goodsList.length" />
<span>全選</span>
</label>
<div v-for="(index, item) in goodsList">
<a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<input type="checkbox" :value="index" v-model="selectArr" />
商品名稱:<span v-html="item.name"></span> |
價(jià)格:<span v-html="item.price"></span>
</a>
</div>
<label>
<input type="checkbox" name="all" v-on:click="chooseAll" v-model="selectArr.length==goodsList.length" />
<span>全選</span>
</label>
<script src="http://cdn.bootcss.com/vue/1.0.7/vue.js"></script>
<script>
var vue = new Vue({
el : 'body',
data : {
goodsList : [
{
name : '山本漢方1',
price : '19.00'
},
{
name : '山本漢方2',
price : '19.00'
},
{
name : '山本漢方3',
price : '19.00'
},
{
name : '山本漢方4',
price : '19.00'
},
{
name : '山本漢方5',
price : '19.00'
},
],
selectArr : []
},
ready : function() {},
methods : {
chooseAll : function(event) {
var oThis = this;
oThis.selectArr = [];
if ( event.currentTarget.checked ) {
oThis.goodsList.forEach(function(item , index) {
oThis.selectArr.push(index);
});
}
console.log(oThis.selectArr);
}
}
})
</script>
</body>
</html>
2.二層數(shù)據(jù)結(jié)構(gòu)-全選
一層數(shù)據(jù)結(jié)構(gòu)的購(gòu)物車在現(xiàn)實(shí)中是很少看到的,比如我們最熟悉的淘寶購(gòu)物車是按照店鋪分的,那么必然是多層的數(shù)據(jù)結(jié)構(gòu)。這次在寫這個(gè)二層數(shù)據(jù)接口的全選,碰到一個(gè)很大的坑,一開(kāi)始我是用了一層數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù),發(fā)現(xiàn)當(dāng)對(duì)象數(shù)組里面的某個(gè)值改變了,視圖竟然沒(méi)有觸發(fā)!,所以會(huì)造成下面所有的checkbox都被選中了,最上面的那個(gè)全選checkbox竟然還是沒(méi)有被選中。感覺(jué)告訴我這是vuejs的坑,后來(lái)發(fā)現(xiàn)是js的坑。具體可以看這個(gè)。方法是百度到了,可是放我這里沒(méi)有用(應(yīng)該是版本問(wèn)題)。于是我就改了數(shù)據(jù)結(jié)構(gòu)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs-全選</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
a {
color: #333;
text-decoration:none;
}
.goods-item {
display: block;
}
.store-item {
margin-bottom: 20px;
}
</style>
</head>
<body>
<div v-for="(index1, item) in goodsObj" class="store-item">
<p>
<span v-html="item.name"></span>
<label>
<input type="checkbox" name="all" v-on:click="chooseShopGoods(index1)" v-model="item.checked" />
<span>全選</span>
</label>
</p>
<a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" v-for="(index, data) in item.list" class="goods-item">
<input type="checkbox" v-model="data.checked" v-on:click="choose(index1, index)" />
商品名稱:<span v-html="data.name"></span> |
價(jià)格:<span v-html="data.price"></span>
</a>
</div>
<label>
<input type="checkbox" name="all" v-on:click="chooseAllGoods()" v-model="allChecked" />
<span>全選</span>
</label>
<script src="http://cdn.bootcss.com/vue/1.0.7/vue.js"></script>
<script>
var goodsObj = [
{
name : '大胖的店',
checked : false,
list : [
{
name : '麻辣二胖',
price : 23.00,
realStock : 10,
fare : 1.5,
num : 1,
checked : false,
},
{
name : '香辣二胖',
price : 21.00,
realStock : 2,
fare : 1.5,
num : 2,
checked : false,
},
{
name : '紅燒二胖',
price : 88.00,
realStock : 8,
fare : 1.5,
num : 4,
checked : false,
}
]
},
{
name : '二胖的店',
checked : false,
list : [
{
name : '漂亮的裙子',
price : 166.00,
realStock : 10,
fare : 2,
num : 1,
checked : false,
},
{
name : '漂亮的短袖',
price : 188.00,
realStock : 2,
fare : 1.5,
num : 2,
checked : false,
},
{
name : '漂亮的鞋子',
price : 299.00,
realStock : 1,
fare : 3,
num : 1,
checked : false,
}
]
},
{
name : '胖胖的店',
checked : false,
list : [
{
name : '福滿多',
price : 3.00,
realStock : 10,
fare : .5,
num : 10,
checked : false,
},
{
name : '精品衛(wèi)龍',
price : 1.50,
realStock : 2,
fare : 2,
num : 2,
checked : false,
},
{
name : '周長(zhǎng)江',
price : 2.50,
realStock : 3,
fare : 5,
num : 2,
checked : false,
}
]
},
];
var vue = new Vue({
el : 'body',
data : {
goodsObj : goodsObj,
allChecked : false
},
ready : function() {
},
methods : {
// 全部商品全選
chooseAllGoods : function() {
var flag = true;
if ( this.allChecked ) {
flag = false;
}
for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) {
this.goodsObj[i]['checked'] = flag;
var list = this.goodsObj[i]['list'];
for ( var k = 0, len1 = list.length; k < len1; k++ ) {
list[k]['checked'] = flag;
}
}
this.allChecked = !this.allChecked;
},
// 每個(gè)店鋪全選
chooseShopGoods : function( index) {
var list = this.goodsObj[index]['list'],
len = list.length;
if ( this.goodsObj[index]['checked'] ) {
for (var i = 0; i < len; i++ ) {
list[i]['checked'] = false;
}
} else {
for (var i = 0; i < len; i++ ) {
list[i]['checked'] = true;
}
}
this.goodsObj[index]['checked'] = !this.goodsObj[index]['checked'];
// 判斷是否選擇所有商品的全選
this.isChooseAll();
},
// 單個(gè)選擇
choose : function( index1, index) {
var list = this.goodsObj[index1]['list'],
len = list.length;
if ( list[index]['checked'] ) {
this.goodsObj[index1]['checked'] = false;
this.allChecked = false;
list[index]['checked'] = !list[index]['checked'];
} else {
list[index]['checked'] = !list[index]['checked'];
// 判斷是否選擇當(dāng)前店鋪的全選
var flag = true;
for (var i = 0; i < len; i++ ) {
if ( list[i]['checked'] == false ) {
flag = false;
break;
}
}
flag == true ? this.goodsObj[index1]['checked'] = true : this.goodsObj[index1]['checked'] = false;
}
// 判斷是否選擇所有商品的全選
this.isChooseAll();
},
// 判斷是否選擇所有商品的全選
isChooseAll : function() {
var flag1 = true;
for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) {
if ( this.goodsObj[i]['checked'] == false ) {
flag1 = false;
break;
}
}
flag1 == true ? this.allChecked = true : this.allChecked = false;
},
}
})
</script>
</body>
</html>
3.一層數(shù)據(jù)結(jié)構(gòu)-數(shù)量選擇器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs-數(shù)量選擇器(1層數(shù)據(jù)結(jié)構(gòu))</title>
<style type="text/css">
*{
padding:0;
margin: 0;
box-sizing: border-box;
font-size: 16px;
}
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: .1px;
font-size: .1em;
line-height: 0;
clear: both;
}
.quantity-selector {
margin-bottom: 20px;
width: 8.571rem;
line-height: 2.857rem;
border: 1px solid #d1d6e4;
border-radius: 3px;
}
.quantity-selector .reduce,
.quantity-selector .add {
float: left;
width: 33.33%;
border-right: 1px solid #d1d6e4;
text-align: center;
cursor: pointer;
}
.quantity-selector .number {
float: left;
width: 33.33%;
height: 2.857rem;
padding: .5rem 0;
line-height: 1rem;
border: none;
text-align: center;
}
.quantity-selector .add {
border-left: 1px solid #d1d6e4;
border-right: none;
}
.quantity-selector .disable {
color: #d2d2d2;
cursor: default;
}
</style>
</head>
<body>
<div v-for="data in goodsList">
<p>商品數(shù)量 :<span v-html="data.num"></span></p>
<p>商品庫(kù)存 :<span v-html="data.realStock"></span></p>
<div class="quantity-selector clearfix">
<span class="reduce" v-on:click="numChange($index, -1)" v-bind:class="{ 'disable' : data.num==1 }">-</span>
<input type="number" v-bind:value="data.num" class="number" v-bind:data-realStock="data.realStock" v-on:keyUp="numEntry($index)" v-on:keyDown="numEntry($index)" v-model="data.num"/>
<span class="add" v-on:click="numChange($index, 1)" v-bind:class="{ 'disable' : data.num==data.realStock }">+</span>
</div>
</div>
<script src="http://cdn.bootcss.com/vue/1.0.7/vue.js"></script>
<script>
var vue = new Vue({
el : 'body',
data : {
goodsList : [
{
name : '山本漢方1',
price : '19.00',
realStock : 10,
num : 1
},
{
name : '山本漢方1',
price : '19.00',
realStock : 7,
num : 8
},
{
name : '山本漢方1',
price : '19.00',
realStock : 2,
num : 2
},
]
},
ready : function() {},
methods : {
numChange : function(index, numChange) {
var goods = this.goodsList[index];
if ( numChange == 1 ) {
goods.num++;
} else if ( numChange == -1 ) {
goods.num--;
}
if ( goods.num <= 1 ) {
goods.num = 1;
}
if ( goods.num >= goods.realStock ) {
goods.num = goods.realStock;
}
},
numEntry : function(index) {
var goods = this.goodsList[index];
if ( goods.num <=1 ) {
goods.num = 1;
}
if ( goods.num > goods.realStock ) {
goods.num = goods.realStock;
}
}
}
})
</script>
</body>
</html>
4.二層數(shù)據(jù)結(jié)構(gòu)-數(shù)據(jù)選擇器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs-數(shù)量選擇器(2層數(shù)據(jù)結(jié)構(gòu))</title>
<style type="text/css">
*{
padding:0;
margin: 0;
box-sizing: border-box;
font-size: 16px;
}
a {
text-decoration: none;
color: #333;
}
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: .1px;
font-size: .1em;
line-height: 0;
clear: both;
}
.quantity-selector {
margin: 0 auto;
width: 8.571rem;
line-height: 30px;
border: 1px solid #d1d6e4;
border-radius: 3px;
}
.quantity-selector .reduce,
.quantity-selector .add {
float: left;
width: 33.33%;
border-right: 1px solid #d1d6e4;
text-align: center;
cursor: pointer;
}
.quantity-selector .number {
float: left;
width: 33.33%;
height: 30px;
border: none;
padding-left: 10px;
text-align: center;
}
.quantity-selector .add {
border-left: 1px solid #d1d6e4;
border-right: none;
}
.quantity-selector .disable {
color: #d2d2d2;
cursor: default;
}
/*店鋪開(kāi)始*/
.store-item {
width: 600px;
margin: 30px auto;
}
.store-item th {
height: 40px;
background: #d2d2d2;
-webkit-text-stroke: 1px #ff7500;
font-size: 18px;
}
.store-item td {
height: 60px;
text-align: center;
}
.cal-store-box {
text-align: right;
}
.store-footer {
width: 600px;
margin: 50px auto;
display: flex;
justify-content: space-between;
align-items: center;
}
/*店鋪結(jié)束*/
</style>
</head>
<body>
<div class="store-item" v-for="(index1, item) in goodsObj">
<p v-html="index1"></p>
<table class="store-item">
<col width="10%"></col>
<col width="10%"></col>
<col width="20%"></col>
<col width="10%"></col>
<col width="40%"></col>
<col width="10%"></col>
<thead class="thead">
<tr>
<th>選擇</th>
<th>商品</th>
<th>單價(jià)</th>
<th>運(yùn)費(fèi)</th>
<th>數(shù)量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(index, data) in item">
<td>
</td>
<td>
<p><span v-html="data.name"></span></p>
</td>
<td v-html="(data.price).toFixed(2)"></td>
<td v-html="(data.fare).toFixed(2)"></td>
<td>
<div class="quantity-selector clearfix">
<span class="reduce" v-on:click="numChange(index1, $index, -1)" v-bind:class="{ 'disable' : data.num==1 }">-</span>
<input type="number" v-bind:value="data.num" class="number" v-bind:data-realStock="data.realStock" v-on:keyUp="numEntry(index1, $index)" v-on:keyDown="numEntry(index1, $index)" v-model="data.num"/>
<span class="add" v-on:click="numChange(index1, $index, 1)" v-bind:class="{ 'disable' : data.num==data.realStock }">+</span>
</div>
</td>
<td>
<a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >刪除</a>
</td>
</tr>
</tbody>
</table>
<div class="cal-store-box">
<p>店鋪總運(yùn)費(fèi): <span v-html="calEveryFare(index1)"></span></p>
<p>店鋪商品總金額: <span v-html="calEveryStore(index1)"></span></p>
</div>
</div>
<div class="store-footer">
<!-- <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<input type="checkbox" />
<span>全選</span>
</a> -->
<div class="cal-box">
<p>商品總金額:<span v-html="totalFare"></span></p>
<p>運(yùn)費(fèi)總金額:<span v-html="totalMoney"></span></p>
</div>
</div>
<script src="http://cdn.bootcss.com/vue/1.0.7/vue.js"></script>
<script>
var goodsObj = {
'大胖的店' : [
{
name : '康師傅',
price : 23.00,
realStock : 10,
fare : 1.5,
num : 1
},
{
name : '今麥郎',
price : 26.00,
realStock : 2,
fare : 1.5,
num : 2
},
{
name : '比巴卜',
price : 88.00,
realStock : 8,
fare : 1.5,
num : 4
}
],
'二胖的店' : [
{
name : '好看的鞋子',
price : 23.00,
realStock : 7,
fare : 2,
num : 1
},
{
name : '好看的裙子',
price : 26.00,
realStock : 5,
fare : 2,
num : 5
},
{
name : '好看的短袖',
price : 88.00,
realStock : 10,
fare : 2,
num : 1
}
],
'胖胖的店' : [
{
name : '福滿多1號(hào)',
price : 26.00,
realStock : 7,
fare : 3,
num : 1
},
{
name : '福滿多2號(hào)',
price : 26.00,
realStock : 7,
fare : 3,
num : 1
},
{
name : '經(jīng)典衛(wèi)龍辣條',
price : 16.00,
realStock : 50,
fare : 3,
num : 5
},
{
name : '霸王牛津',
price : 80.00,
realStock : 10,
fare : 3,
num : 6
}
]
};
var vue = new Vue({
el : 'body',
data : {
goodsObj : goodsObj,
totalMoney : 0,
totalFare : 0
},
ready : function() {
this.calTotalMoney();
this.calTotalFare();
},
methods : {
numChange : function(index1, index, numChange) {
var goods = this.goodsObj[index1][index],
oThis = this;
if ( numChange == 1 ) {
goods.num++;
} else if ( numChange == -1 ) {
goods.num--;
}
if ( goods.num <= 1 ) {
goods.num = 1;
}
if ( goods.num >= goods.realStock ) {
goods.num = goods.realStock;
}
this.calTotalMoney();
},
numEntry : function(index1, index) {
var goods = this.goodsObj[index1][index];
if ( goods.num <=1 ) {
goods.num = 1;
}
if ( goods.num > goods.realStock ) {
goods.num = goods.realStock;
}
this.calTotalMoney();
},
calEveryStore : function(index) {
var everyStoreMoney = 0;
this.goodsObj[index].forEach(function(item, index, arr) {
everyStoreMoney += parseFloat(item.price) * parseFloat(item.num);
});
return everyStoreMoney.toFixed(2);
},
calEveryFare : function(index) {
var everyStoreFare = 0;
this.goodsObj[index].forEach(function(item, index, arr) {
everyStoreFare += parseFloat(item.fare) * parseFloat(item.num);
});
return everyStoreFare.toFixed(2);
},
calTotalMoney : function () {
var oThis = this;
this.totalMoney = 0;
for ( var x in this.goodsObj ) {
this.goodsObj[x].forEach(function(item, index, arr) {
oThis.totalMoney += parseFloat(item.price) * parseFloat(item.num);
});
}
this.totalMoney = this.totalMoney.toFixed(2);
},
calTotalFare : function () {
var oThis = this;
this.totalFare = 0;
for ( var x in this.goodsObj ) {
this.goodsObj[x].forEach(function(item, index, arr) {
oThis.totalFare += parseFloat(item.fare) * parseFloat(item.num);
});
}
this.totalFare = this.totalFare.toFixed(2);
},
}
})
</script>
</body>
</html>
5.一個(gè)完整的購(gòu)物車
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs-數(shù)量選擇器(2層數(shù)據(jù)結(jié)構(gòu))</title>
<style type="text/css">
*{
padding:0;
margin: 0;
box-sizing: border-box;
font-size: 16px;
}
a {
text-decoration: none;
color: #333;
}
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: .1px;
font-size: .1em;
line-height: 0;
clear: both;
}
.quantity-selector {
margin: 0 auto;
width: 8.571rem;
line-height: 30px;
border: 1px solid #d1d6e4;
border-radius: 3px;
}
.quantity-selector .reduce,
.quantity-selector .add {
float: left;
width: 33.33%;
border-right: 1px solid #d1d6e4;
text-align: center;
cursor: pointer;
}
.quantity-selector .number {
float: left;
width: 33.33%;
height: 30px;
border: none;
padding-left: 10px;
text-align: center;
}
.quantity-selector .add {
border-left: 1px solid #d1d6e4;
border-right: none;
}
.quantity-selector .disable {
color: #d2d2d2;
cursor: default;
}
label {
cursor: pointer;
}
.choose-all {
margin-left: 20px;
}
/*店鋪開(kāi)始*/
.store-item {
width: 600px;
margin: 30px auto;
}
.store-item th {
height: 40px;
background: #d2d2d2;
-webkit-text-stroke: 1px #ff7500;
font-size: 18px;
}
.store-item td {
height: 60px;
text-align: center;
}
.cal-store-box {
text-align: right;
}
.store-footer {
width: 600px;
margin: 50px auto;
display: flex;
justify-content: space-between;
align-items: center;
}
/*店鋪結(jié)束*/
</style>
</head>
<body>
<div class="store-item" v-for="(index1, item) in goodsObj">
<p>
<span v-html="item.name"></span>
<label class="choose-all">
<input type="checkbox" name="all" v-on:click="chooseShopGoods(index1)" v-model="item.checked" />
<span>全選</span>
</label>
</p>
<table class="store-item">
<col width="10%"></col>
<col width="15%"></col>
<col width="15%"></col>
<col width="10%"></col>
<col width="40%"></col>
<col width="10%"></col>
<thead class="thead">
<tr>
<th>選擇</th>
<th>商品</th>
<th>單價(jià)</th>
<th>運(yùn)費(fèi)</th>
<th>數(shù)量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(index, data) in item.list">
<td>
<input type="checkbox" name="all" v-model="data.checked" v-on:click="choose(index1, index)" />
</td>
<td>
<p><span v-html="data.name"></span></p>
</td>
<td v-html="(data.price).toFixed(2)"></td>
<td v-html="(data.fare).toFixed(2)"></td>
<td>
<div class="quantity-selector clearfix">
<span class="reduce" v-on:click="numChange(index1, $index, -1)" v-bind:class="{ 'disable' : data.num==1 }">-</span>
<input type="number" v-bind:value="data.num" class="number" v-bind:data-realStock="data.realStock" v-on:keyUp="numEntry(index1, $index)" v-on:keyDown="numEntry(index1, $index)" v-model="data.num"/>
<span class="add" v-on:click="numChange(index1, $index, 1)" v-bind:class="{ 'disable' : data.num==data.realStock }">+</span>
</div>
</td>
<td>
<a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" v-on:click="delGoods(index1, index)">刪除</a>
</td>
</tr>
</tbody>
</table>
<div class="cal-store-box">
<p>店鋪總運(yùn)費(fèi): <span v-html="calEveryFare(index1)"></span></p>
<p>店鋪商品總金額: <span v-html="calEveryStore(index1)"></span></p>
</div>
</div>
<div class="store-footer">
<label>
<input type="checkbox" v-on:click="chooseAllGoods($event)" v-model="allChecked" />
<span>全選</span>
</label>
<div class="cal-box">
<p>商品總運(yùn)費(fèi):<span v-html="totalFare.toFixed(2)"></span></p>
<p>商品總金額:<span v-html="totalMoney.toFixed(2)"></span></p>
</div>
</div>
<script src="http://cdn.bootcss.com/vue/1.0.7/vue.js"></script>
<script>
var goodsObj = [
{
name : '大胖的店',
checked : false,
list : [
{
name : '麻辣二胖',
price : 23.00,
realStock : 10,
fare : 1.5,
num : 1,
checked : false,
},
{
name : '香辣二胖',
price : 21.00,
realStock : 2,
fare : 1.5,
num : 2,
checked : false,
},
{
name : '紅燒二胖',
price : 88.00,
realStock : 8,
fare : 1.5,
num : 4,
checked : false,
}
]
},
{
name : '二胖的店',
checked : false,
list : [
{
name : '漂亮的裙子',
price : 166.00,
realStock : 10,
fare : 2,
num : 1,
checked : false,
},
{
name : '漂亮的短袖',
price : 188.00,
realStock : 2,
fare : 1.5,
num : 2,
checked : false,
},
{
name : '漂亮的鞋子',
price : 299.00,
realStock : 1,
fare : 3,
num : 1,
checked : false,
}
]
},
{
name : '胖胖的店',
checked : false,
list : [
{
name : '福滿多',
price : 3.00,
realStock : 10,
fare : .5,
num : 10,
checked : false,
},
{
name : '精品衛(wèi)龍',
price : 1.50,
realStock : 2,
fare : 2,
num : 2,
checked : false,
},
{
name : '周長(zhǎng)江',
price : 2.50,
realStock : 3,
fare : 5,
num : 2,
checked : false,
}
]
},
];
var vue = new Vue({
el : 'body',
data : {
goodsObj : goodsObj,
totalMoney : 0,
totalFare : 0,
allChecked : false
},
ready : function() {},
methods : {
// 全部商品全選
chooseAllGoods : function() {
var flag = true;
if ( this.allChecked ) {
flag = false;
}
for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) {
this.goodsObj[i]['checked'] = flag;
var list = this.goodsObj[i]['list'];
for ( var k = 0, len1 = list.length; k < len1; k++ ) {
list[k]['checked'] = flag;
}
}
this.allChecked = !this.allChecked;
this.calTotalMoney();
this.calTotalFare();
},
// 每個(gè)店鋪全選
chooseShopGoods : function( index) {
var list = this.goodsObj[index]['list'],
len = list.length;
if ( this.goodsObj[index]['checked'] ) {
for (var i = 0; i < len; i++ ) {
list[i]['checked'] = false;
}
} else {
for (var i = 0; i < len; i++ ) {
list[i]['checked'] = true;
}
}
this.goodsObj[index]['checked'] = !this.goodsObj[index]['checked'];
// 判斷是否選擇所有商品的全選
this.isChooseAll();
this.cal(index);
},
// 單個(gè)選擇
choose : function( index1, index) {
var list = this.goodsObj[index1]['list'],
len = list.length;
if ( list[index]['checked'] ) {
this.goodsObj[index1]['checked'] = false;
this.allChecked = false;
list[index]['checked'] = !list[index]['checked'];
} else {
list[index]['checked'] = !list[index]['checked'];
// 判斷是否選擇當(dāng)前店鋪的全選
var flag = true;
for (var i = 0; i < len; i++ ) {
if ( list[i]['checked'] == false ) {
flag = false;
break;
}
}
flag == true ? this.goodsObj[index1]['checked'] = true : this.goodsObj[index1]['checked'] = false;
}
// 判斷是否選擇所有商品的全選
this.isChooseAll();
this.cal(index);
},
// 判斷是否選擇所有商品的全選
isChooseAll : function() {
var flag1 = true;
for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) {
if ( this.goodsObj[i]['checked'] == false ) {
flag1 = false;
break;
}
}
flag1 == true ? this.allChecked = true : this.allChecked = false;
},
// 商品數(shù)量控制
numChange : function(index1, index, numChange) {
var goods = this.goodsObj[index1]['list'][index],
oThis = this;
if ( numChange == 1 ) {
goods.num++;
} else if ( numChange == -1 ) {
goods.num--;
}
if ( goods.num <= 1 ) {
goods.num = 1;
}
if ( goods.num >= goods.realStock ) {
goods.num = goods.realStock;
}
this.cal(index);
},
// 用戶填寫容錯(cuò)處理
numEntry : function(index1, index) {
var goods = this.goodsObj[index1]['list'][index];
if ( goods.num <=1 ) {
goods.num = 1;
}
if ( goods.num > goods.realStock ) {
goods.num = goods.realStock;
}
this.cal(index);
},
// 計(jì)算每個(gè)店鋪的商品總額
calEveryStore : function(index) {
var everyStoreMoney = 0,
list = this.goodsObj[index]['list'];
list.forEach(function(item, index, arr) {
if ( list[index]['checked'] ) {
everyStoreMoney += parseFloat(item.price) * parseFloat(item.num);
}
});
return everyStoreMoney.toFixed(2);
},
// 計(jì)算每個(gè)店鋪的運(yùn)費(fèi)總額
calEveryFare : function(index) {
var everyStoreFare = 0,
list = this.goodsObj[index]['list'];
list.forEach(function(item, index, arr) {
if ( list[index]['checked'] ) {
everyStoreFare += parseFloat(item.fare) * parseFloat(item.num);
}
});
return everyStoreFare.toFixed(2);
},
// 計(jì)算商品總金額
calTotalMoney : function () {
var oThis = this;
this.totalMoney = 0;
for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) {
var list = this.goodsObj[i]['list'];
list.forEach(function(item, index, arr) {
if ( list[index]['checked'] ) {
oThis.totalMoney += parseFloat(item.price) * parseFloat(item.num);
}
});
}
},
// 計(jì)算商品總運(yùn)費(fèi)
calTotalFare : function () {
var oThis = this;
this.totalFare = 0;
for ( var i = 0, len = this.goodsObj.length; i < len; i++ ) {
var list = this.goodsObj[i]['list'];
list.forEach(function(item, index, arr) {
if ( list[index]['checked'] ) {
oThis.totalFare += parseFloat(item.fare) * parseFloat(item.num);
}
});
}
},
// 計(jì)算方法集合
cal : function(index) {
this.calEveryStore(index);
this.calEveryFare(index);
this.calTotalMoney();
this.calTotalFare();
},
// 刪除操作
delGoods : function(index1, index) {
console.log(index1);
console.log(index);
this.goodsObj[index1]['list'].splice(index, 1);
this.cal(index);
}
}
})
</script>
</body>
</html>
效果如下:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- js購(gòu)物車實(shí)現(xiàn)思路及代碼(個(gè)人感覺(jué)不錯(cuò))
- JavaScript編寫一個(gè)簡(jiǎn)易購(gòu)物車功能
- Javascript實(shí)現(xiàn)購(gòu)物車功能的詳細(xì)代碼
- js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車有圖有代碼
- Jsp+Servlet實(shí)現(xiàn)購(gòu)物車功能
- 原生js模擬淘寶購(gòu)物車項(xiàng)目實(shí)戰(zhàn)
- Javascript操縱Cookie實(shí)現(xiàn)購(gòu)物車程序
- 簡(jiǎn)單的前端js+ajax 購(gòu)物車框架(入門篇)
- js實(shí)現(xiàn)購(gòu)物車功能
- JavaScript實(shí)現(xiàn)淘寶購(gòu)物件數(shù)選擇
相關(guān)文章
Vue后臺(tái)實(shí)現(xiàn)點(diǎn)擊圖片放大功能的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Vue實(shí)現(xiàn)點(diǎn)擊圖片放大功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-12-12
vue項(xiàng)目運(yùn)行npm?install報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了vue項(xiàng)目運(yùn)行npm?install報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
vue element Cascader級(jí)聯(lián)選擇器解決最后一級(jí)顯示空白問(wèn)題
這篇文章主要介紹了vue element Cascader級(jí)聯(lián)選擇器解決最后一級(jí)顯示空白問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
element-plus日歷(Calendar)動(dòng)態(tài)渲染以及避坑指南
這篇文章主要給大家介紹了關(guān)于element-plus日歷(Calendar)動(dòng)態(tài)渲染以及避坑指南的相關(guān)資料,這是最近幫一個(gè)后端朋友處理一個(gè)前端問(wèn)題,elementUI中calendar日歷組件內(nèi)容進(jìn)行自定義顯示,實(shí)現(xiàn)類似通知事項(xiàng)的日歷效果,需要的朋友可以參考下2023-08-08
淺談element關(guān)于table拖拽排序問(wèn)題
本文主要介紹了element關(guān)于table拖拽排序問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10

