ゼロから、シンプルなショッピングプラットフォームを構築します(16)フロントエンドモールパーツ:
https ://blog.csdn.net/time_____/article/details/108769229
プロジェクトのソースコード(継続的な更新):https://gitee.com/ DieHunter / myCode / tree / master / Shopping
前回の記事では、商品詳細ページの実現について説明しました。最後の機能は、ショッピングカートを追加することです。つまり、リストから商品が存在するかどうかを比較します。存在する場合は、既存の商品データを変更します。存在しない場合は、商品を初期化してに追加します。この記事では、ショッピングカートリストで、ショッピングカートデータを操作する機能を紹介します。
ショッピングカート機能には
、製品の数量の変更、単一の製品の削除、すべての選択/反転、および一括削除が含まれます
このページは、上部のタイトル、メニューバーのタブバー、単一アイテムのshopCarItem、および下の一括操作shopCarOrderの4つのコンポーネントに分かれています。
商品数の変更は前回の記事で紹介しましたが、countShopItemメソッドで変更します
1つの製品を削除する
delShopItem(_id) {
let _shopCar = this.state//获取现有购物车列表
_shopCar.splice(_id, 1)//数组删除第_id项
this.state = _shopCar//刷新购物车列表
this.$events.emitEvent(EventName.CountShop);//刷新界面
}
すべて選択/反転選択、注意すべき2つの場所があります。すべて選択/反転選択の実現には2つの状態があります。1つは各製品の単一選択がすべて選択されるか、すべて選択ボタンが状態に従います。もう1つはすべて選択ボタンです。すべてのラジオボタンも、すべてを選択または選択解除した後の状態に従います
まず、ストアのアクションにメソッドを追加します。このメソッドは、選択した製品の状態、製品の総数、および合計価格を合計するために使用されます。製品が選択されるたびに、このメソッドがトリガーされてデータが更新されます
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コンポーネントでは、動作中のメソッドを呼び出して、グローバル状態の値を変更します。
<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>
実際には、選択した製品を削除する関数も作成する必要があります
delSelShop() {//直接通过遍历商品选中状态值进行删除,并刷新数据
let _list = []
this.state.map(item => {
if (!item.isSelect) {
_list.push(item)
}
});
this.state = _list
this.$events.emitEvent(EventName.CountShop);
}
最後に、これら4つのコンポーネントが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のデータバインディングを組み合わせてページをレンダリングする製品ショッピングカートの操作を紹介します。次の記事では、ユーザー登録およびログイン機能(単純なユーザー名とパスワードの登録、ログイン、および電子メール検証モジュール)を実装します。