從零開始,搭建一個簡單的購物平臺(十六)前端商城部分:
https://blog.csdn.net/time_____/article/details/108769229
專案原始碼(持續更新):https://gitee.com/DieHunter/myCode/tree/master/shopping
上篇文章講到了商品詳情頁面實作,最后一個功能是加入購物車,也就是通過串列對比商品是否存在,若存在,則對現有商品資料進行修改,若不存在,則初始化商品,并添加至購物車串列中,這篇文章將介紹對購物車資料進行操作功能
購物車功能包括
修改商品數量 洗掉單個商品 全選/反選 批量洗掉




這個頁面,將其分解成四個組件,分別是頂部的Title,選單欄Tabbar,單件商品shopCarItem和下面的批量操作shopCarOrder
修改商品數量在上篇文章中已介紹,通過countShopItem方法進行修改
洗掉單個商品
delShopItem(_id) {
let _shopCar = this.state//獲取現有購物車串列
_shopCar.splice(_id, 1)//陣列洗掉第_id項
this.state = _shopCar//重繪購物車串列
this.$events.emitEvent(EventName.CountShop);//重繪界面
}
全選/反選,這里有兩個注意的地方,全選/反選的實作有兩種狀態,一是每個商品單選被全選或反選后全選按鈕也會跟隨狀態,二是全選按鈕全選或反選后所有單選按鈕也會跟隨狀態
我們首先在store的action加一個方法,用于總計商品的全選狀態,商品總數,及總價格,每當商品被選中,就觸發這個方法,重繪資料
filterSelect() {//修改商品全選,單個商品驅動全選按鈕,重繪資料
let shopConfig = {//所有商品總計初始值
_count: 1,//是否全選
_selCount: 0,//商品總數
_sum: 0//商品總價
}
this.state.forEach(item => {
shopConfig._selCount += item.isSelect ? 1 : 0;
shopConfig._count *= item.isSelect;//判斷是否全選,初始值0,若全為false,相乘等于0,若全為true,相乘為1,即等于1是全選,等于0是未全選
shopConfig._sum += item.isSelect ? item.sum : 0
});
this.$events.emitEvent(EventName.SelectParent, shopConfig);
}
此外,我們需要再寫個方法,用于全選按鈕修改各個商品的選中狀態
selAllChild(_sel) {//修改商品全選,全選按鈕驅動單個商品,重繪資料
this.state = this.state.map(item => {
item.isSelect = _sel;//當全選按鈕選中,修改所有商品狀態
return item;
});
this.$events.emitEvent(EventName.SelectAllChild);
}
于是在單件商品shopCarItem組件中,我們進行呼叫action中的方法,修改全域state值
<template>
<div>
<ul v-if="shopList.length" class="shopCar">
<li v-for="(item,index) in shopList" :key="index">
<span class="mint-checkbox" @click="selectHandler(index)">
<input class="mint-checkbox-input" type="checkbox" :checked="item.isSelect" />
<span class="mint-checkbox-core"></span>
</span>
<img :src="imgPath+item.shopPic" alt />
<div class="shopInfo">
<div>
<span>{{item.shopName}} {{item.shopScale}}克</span>
<span>¥{{item.shopPrice}}</span>
</div>
<div>
<mt-button class="minus" type="default" @click="minusShopHandler(item)">-</mt-button>
<span>{{item.shopCount}}</span>
<mt-button class="add" type="default" @click="addShopHandler(item)">+</mt-button>
<mt-button class="del" type="default" @click="delShopHandler(index)">×</mt-button>
</div>
</div>
</li>
</ul>
<div v-else class="noShop">
<div class="icon-jiarugouwuche iconfont"></div>
<span>購物車為空</span>
</div>
</div>
</template>
<script>
import Config from "../../config/config";
import { Toast } from "mint-ui";
const { EventName } = Config;
export default {
name: "shopCarItem",
data() {
return {
shopCar: null,//初始化購物車
shopList: [],//購物車串列state
imgPath: Config.RequestPath,//靜態檔案根目錄
selectAll: false,//全選
};
},
created() {
this.shopCar = new this.$store.ShopCar();
this.shopList = this.shopCar.state;
this.$events.onEvent(EventName.CountShop, this.countHandler);//商品數量監聽
this.$events.onEvent(EventName.SelectAllChild, this.selAllHandler);//商品全選監聽
},
mounted() {
this.shopCar.filterSelect();//初始化全選,商品數量,商品總價
},
destroyed() {
this.$events.offEvent(EventName.CountShop, this.countHandler);
this.$events.offEvent(EventName.SelectAllChild, this.selAllHandler);
},
methods: {
countHandler(res) {//修改商品數量,重繪資料
this.shopList = this.shopCar.state;
this.shopCar.filterSelect();
},
selectHandler(_id) {//修改商品全選,單個商品驅動全選按鈕,重繪資料
this.shopList[_id].isSelect = !this.shopList[_id].isSelect;
this.shopCar.state = this.shopList;
this.shopCar.filterSelect();
},
selAllHandler() {//修改商品全選,全選按鈕驅動單個商品,重繪資料
this.shopList = this.shopCar.state;
this.shopCar.filterSelect();
},
addShopHandler(_data) {//添加商品,重繪資料
_data.shopCount = 1;
this.shopCar.countShopItem({
..._data,
});
},
minusShopHandler(_data) {//減少商品,重繪資料
_data.shopCount = -1;
this.shopCar.countShopItem({
..._data,
});
},
delShopHandler(_id) {//洗掉單個商品,重繪資料
this.shopCar.delShopItem(_id);
},
},
};
</script>
<style lang="less" scoped>
@import "../../style/init.less";
.noShop {
width: 100%;
height: 100%;
text-align: center;
span {
.f_s(36);
}
div {
.w(200);
.h(200);
border-radius: 100%;
background: @mainColor;
.titleFont();
box-shadow: 5px 5px 8px #777;
.l_h(200);
text-align: center;
margin: 100px auto 20px;
.f_s(100);
}
}
.shopCar {
.padbottom(130);
width: 100%;
li {
border-bottom: 1px solid #d3d3d3;
padding-left: unit(35 / @pxtorem, rem);
.h(320);
.mint-checkbox {
.h(320);
.l_h(320);
display: inline-block;
vertical-align: middle;
}
.mint-checkbox-input:checked + .mint-checkbox-core {
background: #ea3e3c;
border-color: #ea3e3c;
}
img {
.h(265);
.w(265);
margin-left: unit(20 / @pxtorem, rem);
display: inline-block;
vertical-align: middle;
background: #f5f6f5;
}
.shopInfo {
.h(235);
width: 50%;
.padtop(30);
padding-left: unit(10 / @pxtorem, rem);
display: inline-block;
vertical-align: middle;
div:nth-child(1) {
overflow: hidden;
span {
float: left;
}
span:nth-child(2) {
float: right;
}
}
div:nth-child(2) {
margin-top: unit(85 / @pxtorem, rem);
span {
display: inline-block;
vertical-align: middle;
padding: 0 unit(50 / @pxtorem, rem);
}
.add,
.minus,
.del {
display: inline-block;
vertical-align: middle;
background: white;
box-shadow: none;
.f_s(50);
}
.del {
float: right;
}
}
}
}
}
</style>
在批量操作shopCarOrder組件中同理
<template>
<div class="shopOrder">
<span class="mint-checkbox" @click="selectHandler">
<input class="mint-checkbox-input" type="checkbox" :checked="isSelAll" />
<span class="mint-checkbox-core"></span>
</span>
<span>全選({{selCount}})</span>
<span @click="delSelShop">洗掉({{selCount}})</span>
<span>
<span>¥{{sum}}</span>
<span class="icon-qianjin iconfont" @click="sendOrder"></span>
</span>
</div>
</template>
<script>
import Config from "../../config/config";
import ShopCarOrderBussiness from "./bussiness";
import { Toast } from "mint-ui";
const { EventName } = Config;
export default {
name: "shopCarOrder",
data() {
return {
shopCar: null,
isSelAll: false,//全選
selCount: 0,//商品數量
sum: 0,//商品總價
orderList: null,//提交訂單請求引數
shopCarOrderBussiness: null,
};
},
created() {
this.shopCar = new this.$store.ShopCar();
this.shopCarOrderBussiness = new ShopCarOrderBussiness(this);
this.$events.onEvent(EventName.SelectParent, this.selAllHandler);//全選按鈕監聽,通過監聽所有商品都選中或未全選,修改狀態
},
destroyed() {
this.$events.offEvent(EventName.SelectParent, this.selAllHandler);
},
methods: {
selectHandler() {//驅動修改所有商品選中狀態
this.isSelAll = !this.isSelAll;
this.shopCar.selAllChild(this.isSelAll);
},
selAllHandler({ _count, _selCount, _sum }) {
this.isSelAll = _count;
this.selCount = _selCount;
this.sum = _sum;
},
delSelShop() {//洗掉選中商品
this.shopCar.delSelShop();
},
sendOrder() {//提交訂單
this.shopCarOrderBussiness.sendOrderList();
},
},
};
</script>
<style lang="less" scoped>
@import "../../style/init.less";
.shopOrder {
.f_s(34);
color: #fff;
position: fixed;
.mcolor();
bottom: unit(130 / @pxtorem, rem);
width: 100%;
.h(130);
.l_h(130);
> span:nth-child(1),
> span:nth-child(2) {
padding-left: unit(35 / @pxtorem, rem);
}
> span:nth-child(3) {
padding-left: unit(200 / @pxtorem, rem);
}
> span:nth-child(4) {
float: right;
margin-right: unit(50 / @pxtorem, rem);
> span:nth-child(1) {
padding-left: unit(20 / @pxtorem, rem);
border-left: 1px dashed #fff;
}
> span:nth-child(2) {
padding-left: unit(50 / @pxtorem, rem);
}
}
> span {
display: inline-block;
}
.mint-checkbox-input + .mint-checkbox-core {
background: transparent;
border-color: #fff;
}
.mint-checkbox-input:checked + .mint-checkbox-core {
.mcolor();
}
}
</style>
在action中,我們還需要寫一個函式,用于洗掉選中商品
delSelShop() {//直接通過遍歷商品選中狀態值進行洗掉,并重繪資料
let _list = []
this.state.map(item => {
if (!item.isSelect) {
_list.push(item)
}
});
this.state = _list
this.$events.emitEvent(EventName.CountShop);
}
最后,在shopCar.vue界面中引入這四個組件,頁面實作完成
<template>
<div>
<Top title="購物車"></Top>
<div class="content">
<ShopCarItem></ShopCarItem>
<ShopCarOrder></ShopCarOrder>
</div>
<TabBar></TabBar>
</div>
</template>
<script>
import Top from "../../components/top/top";
import ShopCarItem from "../../components/shopCarItem/shopCarItem";
import ShopCarOrder from "../../components/shopCarOrder/shopCarOrder";
import TabBar from "../../components/tabBar/tabBar";
export default {
name: "shopCar",
data() {
return {};
},
components: {
Top,
ShopCarItem,
ShopCarOrder,
TabBar
},
created() {}
};
</script>
<style lang="less" scoped>
@import "../../style/init.less";
</style>
本篇文章主要對商品購物車操作進行了介紹,其中運用了資料重繪視圖的基本操作,將資料,邏輯,視圖三者分開,結合vue的資料系結渲染頁面,下篇文章將實作用戶的注冊,登錄功能(簡單的用戶名密碼注冊,登錄,和郵箱驗證模塊)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/166946.html
標籤:其他
