UniappDay06
1.填写订单-渲染基本信息
- 静态结构(分包)
- 封装请求API
import { http } from \'@/utils/http\'import { OrderPreResult } from \'@/types/order\'export const getmemberOrderPreAPI = () => { return http({ method: \'GET\', url: \'/member/order/pre\', })}
- 初始化调用
// 获取订单信息const orderPre = ref()const getmemberOrderPreData = async () => { const res = await getmemberOrderPreAPI() orderPre.value = res.result}// 初始化调用onLoad(() => { getmemberOrderPreData()})
- 类型声明
- 界面渲染
{{ item.name }} {{ item.attrsText }} {{ item.payPrice }} {{ item.price }} x{{ item.count }} {{ orderPre?.summary.totalPayPrice.toFixed(2) }} 提交订单
2. 收货地址
- 计算默认收货地址
const selectedAddress = computed(() => { // 查找默认收货地址 return orderPre.value?.userAddresses.find((v) => v.isDefault)})
- 地址列表页
- 修改收货地址
- 收货地址Store
import { AddressItem } from \'@/types/address\'import { defineStore } from \'pinia\'import { ref } from \'vue\'export const useAddressStore = defineStore(\'address\', () => { const selectedAddress = ref() const changeSelectedAddress = (val: AddressItem) => { selectedAddress.value = val } return { selectedAddress, changeSelectedAddress, }})
- 选中收货地址
// 单纯的阻止冒泡,否则修改页面没法跳转 @tap.stop=\"() => {}\"// 修改收货地址const onChangeAddress = (item: AddressItem) => { //修改地址 const addressStore = useAddressStore() addressStore.changeSelectedAddress(item) // 返回上一页 uni.navigateBack()}
3.立即购买
- 封装
export const getmemberOrderPreNowAPI = (data: { skuId: string count: string addressId?: string}) => { return http({ method: \'GET\', url: \'/member/order/pre/now\', data, })}
- 立即购买事件,跳转页面传参
@buy-now=\"onBuyNow\"// 立即购买const onBuyNow = (ev: SkuPopupEvent) => { // 跳转并传参 uni.navigateTo({ url: `/pagesOrder/create/create?skuId=${ev._id}&count=${ev.buy_num}` })}
- 立即购买
// 页面参数const query = defineProps()// 获取订单信息const orderPre = ref()const getmemberOrderPreData = async () => { if (query.count && query.skuId) { const res = await getmemberOrderPreNowAPI({ skuId: query.skuId, count: query.count, }) orderPre.value = res.result } else { const res = await getmemberOrderPreAPI() orderPre.value = res.result }}
4.提交订单
- 封装请求API
// /member/orderexport const postMemberOrderAPI = (data: OrderCreateParams) => { return http({ method: \'POST\', url: \'/member/order\', data, })}
- 类型声明文件
- 提交按钮事件
- 调用接口成功
- 跳转订单详情
// 提交订单const onOrderSubmit = async () => { if (!selectedAddress.value?.id) { uni.showToast({ title: \'请选择收货地址\' }) } const res = await postMemberOrderAPI({ addressId: selectedAddress.value!.id, buyerMessage: buyerMessage.value, deliveryTimeType: activeDelivery.value.type, goods: orderPre.value!.goods.map((v) => ({ count: v.count, skuId: v.skuId })), payChannel: 2, payType: 1, }) // 关闭当前页面,再跳转 uni.redirectTo({ url: `/pagesOrder/detail/detail?id=${res.result.id}` })}
- 无收货地址交互
5.自定义导航栏交互
- 导航栏左上角按钮,返回首页
// 获取页面栈// pages是一个数组const pages = getCurrentPages()// 获取当前页面实例,数组最后一项const pageInstance = pages.at(-1) as any 1\" open-type=\"navigateBack\" class=\"back icon-left\" >
- 滚动驱动的动画
// 页面渲染完毕,绑定动画效果donReady(() => { // 动画效果,导航栏背景色 pageInstance.animate( \'.navbar\', // 选择器 [{ backgroundColor: \'transparent\' }, { backgroundColor: \'#f8f8f8\' }], // 关键帧信息 1000, // 动画持续时长 { scrollSource: \'#scroller\', // scroll-view 的选择器 startScrollOffset: 0, // 开始滚动偏移量 endScrollOffset: 50, // 停止滚动偏移量 timeRange: 1000, // 时间长度 }, ) // 动画效果,导航栏标题 pageInstance.animate(\'.navbar .title\', [{ color: \'transparent\' }, { color: \'#000\' }], 1000, { scrollSource: \'#scroller\', timeRange: 1000, startScrollOffset: 0, endScrollOffset: 50, }) // 动画效果,导航栏返回按钮 pageInstance.animate(\'.navbar .back\', [{ color: \'#fff\' }, { color: \'#000\' }], 1000, { scrollSource: \'#scroller\', timeRange: 1000, startScrollOffset: 0, endScrollOffset: 50, })})
6.订单状态渲染
- 渲染订单状态
等待付款 应付金额: ¥ 99.00 支付剩余 00 时 29 分 59 秒 去支付 {{ orderStateList[order.orderState].text }} 再次购买 模拟发货
- 订单状态常量
/** 订单状态枚举 */export enum OrderState { /** 待付款 */ DaiFuKuan = 1, /** 待发货 */ DaiFaHuo = 2, /** 待收货 */ DaiShouHuo = 3, /** 待评价 */ DaiPingJia = 4, /** 已完成 */ YiWanCheng = 5, /** 已取消 */ YiQuXiao = 6,}/** 订单状态列表 */export const orderStateList = [ { id: 0, text: \'\' }, { id: 1, text: \'待付款\' }, { id: 2, text: \'待发货\' }, { id: 3, text: \'待收货\' }, { id: 4, text: \'待评价\' }, { id: 5, text: \'已完成\' }, { id: 6, text: \'已取消\' },]
7.待支付倒计时
//倒计时const onTimeUp = () => { // 修改订单状态为已取消 order.value!.orderState = OrderState.YiQuXiao}
8. 代付款-订单支付
// 去支付const onOrderPay = async () => { if (import.meta.env.DEV) { // 开发环境模拟支付 await getPayMockAPI({ orderId: query.id }) } else { // 正式微信支付 const res = await getPayWxPayMiniPayAPI({ orderId: query.id }) wx.requestPayment(res.result) } // 关闭当前页,再跳转 uni.redirectTo({ url: `/pagesOrder/Payment/Payment?id=${query.id}` })}
主要测试,开发环境模拟支付,即可
9.待发货-模拟发货
- dev环境
// 是否为开发环境const isDev = import.meta.env.DEV 模拟发货
- 模拟发货,并更新订单状态
// 模拟发货const onOrderSend = async () => { if (isDev) { await getMemberOrderConsignmentByIdAPI(query.id) // 轻提示 uni.showToast({ icon: \'success\', title: \'模拟成功\' }) // 主动更新订单状态 order.value!.orderState = OrderState.DaiFaHuo }}
打包时这里的代码会被自动剔除,优化掉
10.待收货-确认收货
仅在订单状态为待收货时,可确认收货
// 待收货=>确认收货const onOrderConfirm = () => { // 二次确认弹窗 uni.showModal({ content: \'为保障你的权益,请收到货并确认无误后,再确认收货\', success: async (success) => { if (success.confirm) { const res = await putMemberOrderReceiptByIdAPI(query.id) // 主动更新 order.value = res.result } }, })} 确认收货
11.订单详情-待收货-订单物流
- 封装请求API
- 获取订单详情后
- 判断订单状态
// 获取订单详情const order = ref()const getMemberOrderByIdData = async () => { const res = await getMemberOrderByIdAPI(query.id) order.value = res.result // include的数是否包含在[]前面的这个数组里面,包含就是true,反之 if ( [OrderState.DaiShouHuo, OrderState.DaiPingJia, OrderState.YiWanCheng].includes( order.value.orderState, ) ) { getMemberOrderLogisticsByIdData() }}
- 获取物流信息
注意:仅在订单状态为待收货、待评价、已完成时,可获取物流信息
// 获取物流信息const logisticList = ref([])const getMemberOrderLogisticsByIdData = async () => { const res = await getMemberOrderLogisticsByIdAPI(query.id) logisticList.value = res.result.list}
- 渲染物流信息
{{ item.text }} {{ item.time }} {{ order.receiverContact }} {{ order.receiverMobile }} {{ order.receiverAddress }}
12.删除订单
注意:仅在订单状态为待评价,已完成,已取消,可删除订单
- 封装请求API
- 条件渲染&事件绑定
= OrderState.DaiPingJia\" > 删除订单
- 二次确认弹窗
- 调用API成功
- 跳转到订单列表
// 删除订单const onOrderDelete = () => { // 二次确认 uni.showModal({ content: \'是否删除订单\', success: async (success) => { if (success.confirm) { await deleteMemberOrderAPI({ ids: [] }) uni.redirectTo({ url: \'/pagesOrder/list/list\' }) } }, })}
13.订单列表-Tabs滑动切换
- 静态结构
- Tabs文字渲染
- 点击文字高亮切换
// 高亮下标const activeIndex = ref(0) {{ item.orderState }}
- swiper滑动切换
可以实现上下两个模块的关联,交互
14.tabs页面跳转高亮
- 个人中心页
- 页面传参
- 订单详情页
- 接收页面参数
- 查找高亮下标
// 获取页面参数const query = defineProps()// 高亮下标const activeIndex = ref(orderTabs.value.findIndex((v) => v.orderState === Number(query.type)))
15.列表渲染
- 封装列表组件
- 订单状态父传子
// 定义propsconst props = defineProps()
- 封装请求API
- 准备请求参数
// 请求参数const queryParams: OrderListParams = { page: 1, pageSize: 5, orderState: props.orderState,}// 获取订单列表const orderList = ref([])const getMemberOrderData = async () => { const res = await getMemberOrderAPI(queryParams) orderList.value = res.result.items}
- 初始化调用
// 初始化调用onMounted(() => { getMemberOrderData()})
- 页面渲染
16.订单支付
// 订单支付const onOrderPay = async (id: string) => { if (import.meta.env.DEV) { // 开发环境模拟支付 await getPayMockAPI({ orderId: id }) } else { // 正式微信支付 const res = await getPayWxPayMiniPayAPI({ orderId: id }) wx.requestPayment(res.result) } // 成功提示 uni.showToast({ title: \'支付成功!\' }) // 更新订单状态 const order = orderList.value.find((v) => v.id === id) order!.orderState = OrderState.DaiFaHuo} 去支付
17.项目打包-微信小程序端发布上线
pnpm build:mp-weixin
18.项目打包-条件编译和网页端打包
常见问题:按照 uni-app 规范开发可保证多平台兼容,但每个平台有自己的一些特性,该如何处理?
注意事项:网页端不支持微信平台授权登录等功能,可通过条件编译,让代码按条件编译到不同平台。
条件编译语法:通过特殊注释,以 #ifdef 或 #ifndef 加平台名称开头,以 #endif 结尾。
pnpm dev:h5
// #ifdef MP-WEIXINwx.login()wx.requestOrderPayment()// #endif
支持: vue, js, ts, css, scss, pages.json 等文件
编译网页端
pnpm build:h5
将绝对定位改为相对定位
// 在manifest中配置/* 网页端特有配置 */ \"h5\": { \"router\": { \"base\": \"./\" } }, // 最后重启,pnpm build:h5