当用户选择商品后,无论是否选择优惠券,最后都要提交订单,完成支付功能,为实现这个需求,Vant提供了SubmitBar组件,它的功能是用于展示订单金额并提交订单,同时可以根据提交数据时的完整性,实现禁用或正在加载的按钮状态。
SubmitBar组件的常用属性如下表11-12所示。
接下来通过一个完整的案例来演示使用SubmitBar组件实现的效果。
实例11-9 SubmitBar组件
- 功能描述
在实例【11-8】的基础之上,添加一个coupon组件,再添加一个SubmitBar组件,首次进入时,显示所选商品的总金额,如果修改数据,总金额则自动同步;如果用户选择了优惠券,则总金额将自动减去优惠券金额。
- 实现代码
在项目的components 文件夹中,添加一个名为“Subar”的.vue文件,该文件的保存路径是“components/ch11/buis/”,在文件中加入如清单11-9所示代码。
代码清单11-9 Subar.vue代码
<template>
<div>
<h3>SubmitBar 组件</h3>
<div class="row">
<van-card :num="curGoods.num" :tag="curGoods.tag"
:price="curGoods.price"
:desc="curGoods.desc"
:title="curGoods.title"
:thumb="curGoods.thumb"
:origin-price="curGoods.originPrice">
<template #tags>
<van-tag plain type="primary">
{{ curGoods.tags[0] }}
</van-tag>
<van-tag plain type="primary">
{{ curGoods.tags[1] }}
</van-tag>
</template>
<template #footer>
<van-button size="mini" @click="add">
+
</van-button>
<van-button size="mini" @click="reduce">
-
</van-button>
</template>
</van-card>
</div>
<!-- 优惠券单元格 -->
<van-coupon-cell :coupons="coupons"
:chosen-coupon="chosenCoupon"
@click="showList = true" />
<!-- 优惠券列表 -->
<van-popup :show="showList" round
position="bottom"
style="height: 70%; padding-top: 4px;">
<van-coupon-list :show-exchange-bar="false"
:coupons="coupons"
:chosen-coupon="chosenCoupon"
:disabled-coupons="disabledCoupons"
@change="onChange" />
</van-popup>
<van-submit-bar :price="sumPrice"
button-text="提交订单"
@submit="onSubmit" />
</div>
</template>
<script>
import goods from "../../../assets/goods.png"
export default {
data() {
return {
curGoods: {
num: 2, price: 9000,
desc: "一台笔记本电脑",
title: "thinkpad X1 系列",
thumb: goods,
originPrice: "11000",
tag: "超薄小巧型",
tags: ["一代经典", "超低价格"]
},
disabledCoupons: [{
available: 0,
condition: '满1000元\n再优惠 200 元',
reason: '',
value: 20000,
name: '老客户惊喜',
startAt: 1489104340,
endAt: 1514592670,
valueDesc: '200',
unitDesc: '元'
}],
coupons: [{
available: 1,
condition: '无门槛\n最高优惠 100 元',
reason: '',
value: 10000,
name: '新人惊喜',
startAt: 1589304340,
endAt: 1634595670,
valueDesc: '100',
unitDesc: '元'
}],
showList: false,
chosenCoupon: -1,
couponValue : 0
}
},
computed: {
sumPrice() {
return (this.curGoods.num *
this.curGoods.price * 100)-
this.couponValue;
}
},
methods: {
add() {
this.curGoods.num++;
},
onChange(index) {
this.showList = false;
this.chosenCoupon = index;
this.couponValue = this.coupons[index].value/100;
},
reduce() {
if (this.curGoods.num > 1)
this.curGoods.num--;
},
onSubmit(){
console.log("提交成功了!")
}
}
}
</script>
<style>
.row {
margin: 10px 0;
padding: 10px 0;
border-bottom: solid 1px #eee;
}
.van-image img {
object-fit: contain !important;
}
</style>
- 页面效果
保存代码后,页面在Chrome浏览器下执行的页面效果如图11-11所示。
4. 源码分析
在上述实例的加粗代码中,为了确保合计金额的即时同步,在computed中添加了一个名为sumPrice的函数,由该函数返回合计金额,在计算合计金额时,需要注意,合计金额不仅与商品数量和价格相关,同时,还要减去选中的优惠券金额值。
需要说明的是:在计算合计金额时,无论是商品的价格,还是优惠券的价格,必须统一成一个单位再进行计算,建议统一成分,因此,在sumPrice函数计算时,先将商品的价格乘以100,统一成分,然后才进行计算。