uniapp项目之小兔鲜儿小程序商城(六) 地址模块:地址管理页的实现,地址表单页的实现
文章目录
- 一.地址模块
- 1.静态结构
- 2.动态设置标题
- 3.功能:新建地址
- 3.1.封装api接口
- 3.2.类型声明
- 3.3.收集表单数据
- 4.address页的列表渲染
一.地址模块
地址模块共两个页面:地址管理页 address.vue
和地址表单页address-form.vue
,两个页面都作为会员中心页my.vue
的分包,可以在pageMember路径下创建:新建uniapp 页面(分包)
业务流程:
在`my`页点击我的收货地址可以跳转到`address`页,该页负责地址的管理(增删改),
点击删除可以在当前页操作,点击增加或修改时会跳转到`address-form`页,并根据是否传入id来区分具体是增加还是修改
1.静态结构
新建src/pageMember/address/address.vue
,并准备静态页面如下
<script setup lang="ts">
//
</script><template><view class="viewport"><!-- 地址列表 --><scroll-view class="scroll-view" scroll-y><view v-if="true" class="address"><view class="address-list"><!-- 收货地址项 --><view class="item"><view class="item-content"><view class="user">黑马小王子<text class="contact">13111111111</text><text v-if="true" class="badge">默认</text></view><view class="locate">广东省 广州市 天河区 黑马程序员</view><navigatorclass="edit"hover-class="none":url="`/pagesMember/address-form/address-form?id=1`">修改</navigator></view></view><!-- 收货地址项 --><view class="item"><view class="item-content"><view class="user">黑马小公主<text class="contact">13222222222</text><text v-if="false" class="badge">默认</text></view><view class="locate">北京市 北京市 顺义区 黑马程序员</view><navigatorclass="edit"hover-class="none":url="`/pagesMember/address-form/address-form?id=2`">修改</navigator></view></view></view></view><view v-else class="blank">暂无收货地址</view></scroll-view><!-- 添加按钮 --><view class="add-btn"><navigator hover-class="none" url="/pagesMember/address-form/address-form">新建地址</navigator></view></view>
</template><style lang="scss">
page {height: 100%;overflow: hidden;
}/* 删除按钮 */
.delete-button {display: flex;justify-content: center;align-items: center;width: 50px;height: 100%;font-size: 28rpx;color: #fff;border-radius: 0;padding: 0;background-color: #cf4444;
}.viewport {display: flex;flex-direction: column;height: 100%;background-color: #f4f4f4;.scroll-view {padding-top: 20rpx;}
}.address {padding: 0 20rpx;margin: 0 20rpx;border-radius: 10rpx;background-color: #fff;.item-content {line-height: 1;padding: 40rpx 10rpx 38rpx;border-bottom: 1rpx solid #ddd;position: relative;.edit {position: absolute;top: 36rpx;right: 30rpx;padding: 2rpx 0 2rpx 20rpx;border-left: 1rpx solid #666;font-size: 26rpx;color: #666;line-height: 1;}}.item:last-child .item-content {border: none;}.user {font-size: 28rpx;margin-bottom: 20rpx;color: #333;.contact {color: #666;}.badge {display: inline-block;padding: 4rpx 10rpx 2rpx 14rpx;margin: 2rpx 0 0 10rpx;font-size: 26rpx;color: #27ba9b;border-radius: 6rpx;border: 1rpx solid #27ba9b;}}.locate {line-height: 1.6;font-size: 26rpx;color: #333;}
}.blank {margin-top: 300rpx;text-align: center;font-size: 32rpx;color: #888;
}.add-btn {height: 80rpx;text-align: center;line-height: 80rpx;margin: 30rpx 20rpx;color: #fff;border-radius: 80rpx;font-size: 30rpx;background-color: #27ba9b;
}
</style>
2.动态设置标题
新建地址和修改地址共用一个地址表单页,根据页面参数id来动态设置页面标题
(携带id 的是修改地址,不携带的是新建地址)
在address-form
页中动态设置页面标题如下:
// 获取页面参数
const query = defineProps<{id?: string
}>()
// 动态设置标题
uni.setNavigationBarTitle({ title: query.id ? '修改地址' : '新建地址' })
3.功能:新建地址
业务逻辑:新用户没有收货地址,必须先新建地址,新建成功后返回上一页(address
页)
功能实现:前端提供表单数据,并提交表单给后端
3.1.封装api接口
接口文档:https://www.apifox.cn/apidoc/shared/0e6ee326-d646-41bd-9214-29dbf47648fa/api-43426957
新建src/services/address.ts
import type { AddressParams } from '@/types/address'
import { http } from '@/utils/http'
/**
* 添加收货地址
* @param data 请求参数
*/
export const postMemberAddressAPI = (data: AddressParams) => {return http({method: 'POST',url: '/member/address',data,})
}
3.2.类型声明
新建 src/types/address.d.ts
/** 添加收货地址: 请求参数 */
export type AddressParams = {/** 收货人姓名 */receiver: string/** 联系方式 */contact: string/** 省份编码 */provinceCode: string/** 城市编码 */cityCode: string/** 区/县编码 */countyCode: string/** 详细地址 */address: string/** 默认地址,1为是,0为否 */isDefault: number
}
3.3.收集表单数据
*注:switch也不支持v-model,处理方法和picker一样,通过@change收集数据
- step1:通过在组件上绑定@change事件或v-model收集数据
<form><!-- 表单内容 --><view class="form-item"><text class="label">收货人</text><input class="input" placeholder="请填写收货人姓名" value="" /></view><view class="form-item"><text class="label">手机号码</text><input class="input" placeholder="请填写收货人手机号码" value="" /></view><view class="form-item"><text class="label">所在地区</text><!-- picker通过@change收集数据 --><!-- :value是用于前端展示,@change收集地区数据 --><pickerclass="picker"mode="region":value="form.fullLocation.split(' ')"@change="onRegionChange"><view v-if="false">{{ form.fullLocation }}</view><view v-else class="placeholder">请选择省/市/区(县)</view></picker></view><view class="form-item"><text class="label">详细地址</text><!-- input直接通过v-model绑定数据 --><input class="input" placeholder="街道、楼牌号等信息" v-model="form.address" /></view><view class="form-item"><label class="label">设为默认地址</label><!-- switch通过@change收集数据 --><switchclass="switch"color="#27ba9b":checked="form.isDefault === 1"@change="onSwitchChange"/></view></form>
- step2:在事件中获取数据
// 获取省市区数据
const onRegionChange = (e) => {// 省市区(前端展示)form.value.fullLocation = e.detail.value.join(' ') //数组转字符串// 省市区编码(后端参数)const { provinceCode, cityCode, countyCode } = e.detail.code!// 合并数据Object.assign(form.value, {provinceCode,cityCode,countyCode,})
}
// 获取是否是默认地址
const onSwitchChange: UniHelper.SwitchOnChange = (e) => {form.value.isDefault = e.detail.value ? 1 : 0
}
- step3:提交更新数据:页面调用api接口
<!-- 提交按钮 -->
<button @tap="onSubmit" class="button">保存并使用</button>
import { postMemberAddressAPI } from '@/services/address'
// 提交数据
const onSubmit = async () => {// 新建地址请求await postMemberAddressAPI(form.value)// 成功提示uni.showToast({title: '添加成功',icon: 'success',})// 返回上一页setTimeout(() => {uni.navigateBack()}, 400)
}