一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第25天,点击查看活动详情。
前言
截止到昨天,我们已经将商城小程序的所有tabBar下对应的所有页面。到现在可以说我们的小程序的业务逻辑已经完成了70%了,剩下的逻辑比较重点的就是订单和售后页面了。
今天我们开始探索确认订单页面的逻辑开发
需求分析
我们可以看到,从上到下依次有
- 收货地址信息
- 店铺下的商品信息
- 优惠券信息
- 发票信息
实现逻辑
我们还是先进行组件拆分。将地址、优惠券、发票分别拆分为不同的组件用来进行切换、选择操作。将商品信息放到确认订单的index组件中即可。
这几个组件的显示和交互和当前用户选择的规格又换,例如:
- 如果商品在选择的地址中不包邮,则地址处显示超出配送范围
- 选择优惠券时,只能选择当前商品可用的优惠券 因为这几个组件涉及到确认订单的流程的属性比较简单,且没有什么复杂的交互。在组件中传参的时候,我们使用父子组件传参。
实现逻辑
初始化分包
我们还是将确认订单放在分包的文件夹中,在sub-detail-pages文件夹下创建文件目录层级如下
创建完成后我们将分包配置的sub-detail-pagesrootroot层级,修改为如下代码
{
root: "sub-detail-pages",
name: "detail-pages",
pages: ["goods-detail/index", "confirm-order/index"],
},
我们初始的确认订单页面
sub-detail-pages/confirm-order/index.tsx内容如下
import { View } from "@tarojs/components";
import AddressInfo from "./address-info";
import CouponInfo from "./coupon-info";
import InvoiceInfo from "./invoice-info";
export default function ConfirmOrder() {
return (
<View>
<AddressInfo></AddressInfo>
123123123
<CouponInfo></CouponInfo>
<InvoiceInfo></InvoiceInfo>
</View>
);
}
找个地方作为入口
我们一开始做商城小程序的时候就分析过,用户有两个地方可以跳转到确认订单页面。1个是立即购买,另一个是购物车跳转。
因为这个两个路径传参是不一样的,例如立即购买路径传参就是规格id和数量,购物车时购物车唯一标识。所以我们在进入确认订单页面的时候,应该先请求一遍接口。
整体的流程如下:
- 路径传参,购物车和立即购买分别请求不同的接口,返回同样的数据结构体
- 根据返回的结构体来渲染数据
- 切换地址和优惠券时,通过使用结构体封装商品参数,加上修改后的属性,请求接口继续返回上次的结构体
也就是说,在进入确认订单后的所有请求属性里的商品数据,都是根据第一次请求的结构体封装的
我们在购物车和立即购买中分别添加跳转到确认订单路径的方法如下:
购物车
<AtButton
onClick={() => {
let cartIds = [] as any;
shopCartList.map((item) => {
item["shopList"].map((cart) => {
if (cart.isChecked) {
cartIds.push(cart.id);
}
});
});
Taro.redirectTo({
url:
"/sub-detail-pages/confirm-order/index?urlType='shopCart'&cartIds=" +
JSON.stringify(cartIds),
});
}}
>
去结算
</AtButton>
立即购买。大家可以直接找个地方将规格id写死,只要能实现跳转就可以了
<AtButton
type="secondary"
onClick={() =>
url: `/sub-detail-pages/confirm-order/index?urlType='buyNow'&productId='123123123'&buyNum=10`,
})
}
>
立即购买
</AtButton>
我们在这一步实现的功能就是跳转到确认订单页面之后显示页面如下
最后,我们模拟一下选择子组件之后父组件重新计算的代码
确认订单index.tsx\
import { View } from "@tarojs/components";
import AddressInfo from "./address-info";
import CouponInfo from "./coupon-info";
import InvoiceInfo from "./invoice-info";
import { getCurrentInstance } from "@tarojs/taro";
import { useEffect, useState } from "react";
export default function ConfirmOrder() {
const { router } = getCurrentInstance() || {};
const [loading, setLoading] = useState(true);
const [addressId, setAddressId] = useState("1111");
const [couponId, setCouponId] = useState("2222");
const [invoiceId, setInvoiceId] = useState("3333");
const [confirmOrderData, setConfirmOrderData] = useState({
shopData: [
{
shopName: "测试店铺",
goodList: [
{
goodsId: "123123123",
goodsName: "商品名称",
goodsPrice: "123",
goodsNum: "1",
},
{
goodsId: "123123123",
goodsName: "商品名称",
goodsPrice: "123",
goodsNum: "1",
},
],
},
],
});
useEffect(() => {
console.log(router?.params);
setTimeout(() => {
setLoading(false);
}, 1000);
}, []);
useEffect(() => {
console.log(addressId);
console.log(couponId);
console.log(invoiceId);
console.log("计算");
}, [addressId, couponId, invoiceId]);
return (
<View>
{loading ? (
"加载中"
) : (
<View>
{addressId} {couponId} {invoiceId}
<AddressInfo
addressId={addressId}
updateAddressId={setAddressId}
></AddressInfo>
<CouponInfo
couponId={couponId}
updateCouponId={setCouponId}
></CouponInfo>
<InvoiceInfo
invoiceId={invoiceId}
updateInvoiceId={setInvoiceId}
></InvoiceInfo>
</View>
)}
</View>
);
}
模拟切换地址的代码,order-inifo/index.tsx
import { View } from "@tarojs/components";
import { AtButton } from "taro-ui";
import './index.scss';
export default function AddressInfo(props) {
const updateAddressId = () => {
let addressId = new Date().getTime();
props.updateAddressId(addressId);
};
return (
<View>
<AtButton onClick={() => updateAddressId()}>
点我覆盖地址唯一标识
</AtButton>
</View>
);
}
我们可以看到,在点击覆盖确认订单的地址唯一标识之后,在控制台中会实时显示正在计算,如下图所示
结语
通过这几天的更文活动,算是从0开始搭建了一个商场小程序的骨架和基本的业务实现。美中不足的是样式看起来比较糟糕,我们在完成4月份的更文活动之后,逐步的优化,并整理一下优化的步骤,到时候和大家共享css样式优化落地
从明天开始,我们准备写5篇其他方面的文章,计划是前端方面的。欢迎大家多多关注,点赞!