目的:实现收货地址的添加。
大致步骤:
落的代码:
1.独立组件,准备一个对话框
src/views/member/pay/components/address-edit.vue
添加地址组件
<template>
<XtxDialog title="添加收货地址" v-model:visible="dialogVisible">
<div class="address-edit">
表单
div>
<template v-slot:footer>
<XtxButton type="gray" style="margin-right:20px">取消XtxButton>
<XtxButton type="primary">确认XtxButton>
template>
XtxDialog>
template>
<script>
import { ref } from 'vue'
export default {
name: 'AddressEdit',
setup () {
const dialogVisible = ref(false)
// 打开函数
const open = () => {
dialogVisible.value = true
}
return { dialogVisible, open }
}
}
script>
<style scoped lang="less">
.address-edit {
}
style>
src/views/member/pay/components/checkout-address.vue
使用添加地址组件
// 添加收货地址组件
+ const addressEdit = ref(null)
+ const openAddressEdit = () => {
+ addressEdit.value.open()
+ }
return {
showAddress,
dialogVisible,
selectedAddress,
openDialog,
confirmAddress,
+ addressEdit,
+ openAddressEdit
}
<XtxButton @click="openAddressEdit()" class="btn">添加地址XtxButton>
2.完成表单布局
src/views/member/pay/components/address-edit.vue
结构和样式
<div class="xtx-form">
<div class="xtx-form-item">
<div class="label">收货人:div>
<div class="field">
<input class="input" placeholder="请输入收货人" />
div>
div>
<div class="xtx-form-item">
<div class="label">手机号:div>
<div class="field">
<input class="input" placeholder="请输入手机号" />
div>
div>
<div class="xtx-form-item">
<div class="label">地区:div>
<div class="field">
<XtxCity placeholder="请选择所在地区"/>
div>
div>
<div class="xtx-form-item">
<div class="label">详细地址:div>
<div class="field">
<input class="input" placeholder="请输入详细地址" />
div>
div>
<div class="xtx-form-item">
<div class="label">邮政编码:div>
<div class="field">
<input class="input" placeholder="请输入邮政编码" />
div>
div>
<div class="xtx-form-item">
<div class="label">地址标签:div>
<div class="field">
<input class="input" placeholder="请输入地址标签,逗号分隔" />
div>
div>
div>
.xtx-dialog {
:deep(.wrapper){
width: 780px;
.body {
font-size: 14px;
}
}
}
.xtx-form {
padding: 0;
input {
outline: none;
&::placeholder {
color: #ccc;
}
}
}
.xtx-city {
width: 320px;
:deep(.select) {
height: 50px;
line-height: 48px;
display: flex;
padding: 0 10px;
justify-content: space-between;
.placeholder {
color: #ccc;
}
i {
color: #ccc;
font-size: 18px;
}
.value {
font-size: 14px;
}
}
:deep(.option) {
top: 49px;
}
}
src/components/library/xtx-city.vue
暴露占位文字
placeholder: {
type: String,
default: '请选择配送地址'
}
<span v-if="!fullName" class="placeholder">{{placeholder}}span>
3.完成确认添加操作
src/views/member/pay/components/address-edit.vue
动态绑定表单
// 表单数据
const formData = reactive({
receiver: '',
contact: '',
provinceCode: '',
cityCode: '',
countyCode: '',
address: '',
postalCode: '',
addressTags: '',
isDefault: 0,
fullLocation: ''
})
// 选择地区
const changeCty = (data) => {
formData.provinceCode = data.provinceCode
formData.cityCode = data.cityCode
formData.countyCode = data.countyCode
formData.fullLocation = data.fullLocation
}
return { dialogVisible, open, formData, changeCty }
<div class="xtx-form">
<div class="xtx-form-item">
<div class="label">收货人:div>
<div class="field">
+ <input v-model="formData.receiver" class="input" placeholder="请输入收货人" />
div>
div>
<div class="xtx-form-item">
<div class="label">手机号:div>
<div class="field">
+ <input v-model="formData.contact" class="input" placeholder="请输入手机号" />
div>
div>
<div class="xtx-form-item">
<div class="label">地区:div>
<div class="field">
<XtxCity
placeholder="请选择所在地区"
+ :fullLocation="form.fullLocation"
+ @change="changeCty"
/>
div>
div>
<div class="xtx-form-item">
<div class="label">详细地址:div>
<div class="field">
+ <input v-model="formData.address" class="input" placeholder="请输入详细地址" />
div>
div>
<div class="xtx-form-item">
<div class="label">邮政编码:div>
<div class="field">
+ <input v-model="formData.postalCode" class="input" placeholder="请输入邮政编码" />
div>
div>
<div class="xtx-form-item">
<div class="label">地址标签:div>
<div class="field">
+ <input v-model="formData.addressTags" class="input" placeholder="请输入地址标签,逗号分隔" />
div>
div>
div>
src/api/order.js
接口函数
/**
* 添加收货地址信息
* @param {Object} address - 地址对象
*/
export const addAddress = (address) => {
return request('/member/address', 'post', address)
}
src/components/library/xtx-city.vue
提供占位文字属性
placeholder: {
type: String,
default: '请选择配送地区'
}
<span class="placeholder" v-if="!fullLocation">{{placeholder}}span>
src/views/member/pay/components/address-edit.vue
进行提交操作
// 选择地区
const changeCty = (data) => {
formData.provinceCode = data.provinceCode
formData.cityCode = data.cityCode
formData.countyCode = data.countyCode
+ formData.fullLocation = data.fullLaction
}
+ // 提交操作
+ const submit = () => {
+ addAddress(formData).then(data => {
+ // 添加成功
+ Message({ text: '添加收货地址成功', type: 'success' })
+ formData.id = data.result.id
+ dialogVisible.value = false
+ emit('on-success', formData)
+ })
+ }
+ return { dialogVisible, open, formData, changeCty, submit }
src/views/member/pay/components/checkout-address.vue
接受添加成功的地址对象
+ // 成功
+ const successHandler = (formData) => {
+ const json = JSON.stringify(formData) // 需要克隆下,不然使用的是对象的引用
+ // eslint-disable-next-line vue/no-mutating-props
+ props.list.unshift(JSON.parse(json))
+ }
return {
showAddress,
dialogVisible,
selectedAddress,
openDialog,
confirmAddress,
addressEdit,
openAddressEdit,
+ successHandler
}
<AddressEdit ref="addressEdit" @on-success="successHandler" />
src/views/member/pay/components/address-edit.vue
每次打开对话框清空表单
// 打开函数
const open = (form) => {
dialogVisible.value = true
+ // 传人{}的时候就是清空,否则就是赋值
+ for (const key in formData) {
+ formData[key] = form[key]
+ }
}
目的:在添加收货地址组件基础之上完成修改逻辑。
大致步骤:
落的代码:
1.打开对话框的时候传人当前需需改的地址对象
src/views/member/pay/checkout-address.vue
<a @click="openAddressEdit(showAddress)" v-if="showAddress" href="javascript:;">修改地址a>
2.再添加组件open函数处,接收数据赋值给表单,修改标题
src/views/member/pay/address-edit.vue
const formData = reactive({
+ id: '',
receiver: '',
contact: '',
provinceCode: '',
cityCode: '',
countyCode: '',
+ fullLocation: '',
address: '',
postalCode: '',
addressTags: '',
isDefault: 0
})
<XtxDialog :title="(formData.id?'编辑':'添加')+'收货地址'" v-model:visible="dialogVisible">
3.封装一个API接口函数实现修改,在提交事件中合并修改操作
src/api/order.js
/**
* 编辑收货地址信息
* @param {Object} address - 地址对象
*/
export const editAddress = (address) => {
return request('/member/address', 'put', address)
}
src/views/member/pay/address-edit.vue
// 打开对话框函数
const open = (address) => {
// 先填充数据 - 编辑
if (address.id) {
for (const key in formData) {
formData[key] = address[key]
}
} else {
// 先清空数据 - 添加
for (const key in formData) {
if (key !== 'isDefault') {
formData[key] = ''
}
}
}
dialogVisible.value = true
}
// 提交操作
const app = getCurrentInstance()
const submit = () => {
+ if (formData.id) {
+ editAddress(formData).then(data => {
+ // 修改成功
+ Message(app, { text: '修改收货地址成功', type: 'success' })
+ dialogVisible.value = false
+ emit('on-success', formData)
+ })
+ } else {
addAddress(formData).then(data => {
// 添加成功
Message(app, { text: '添加收货地址成功', type: 'success' })
formData.id = data.result.id
dialogVisible.value = false
emit('on-success', formData)
})
+ }
}
4.父组件修改数据
src/views/member/pay/components/checkout-address.vue
// 成功
const successHandler = (formData) => {
+ const editAddress = props.list.find(item => item.id === formData.id)
+ if (editAddress) {
+ // 修改
+ for (const key in editAddress) {
+ editAddress[key] = formData[key]
+ }
+ } else {
// 添加
const json = JSON.stringify(formData) // 需要克隆下,不然使用的是对象的引用
// eslint-disable-next-line vue/no-mutating-props
props.list.unshift(JSON.parse(json))
+ }
目的:汇总提交订单需要的数据,进行提交。
大致步骤:
落的代码:
1.定义需要提交的数据对象
src/views/member/pay/checkout.vue
setup () {
const checkoutInfo = ref(null)
findCheckoutInfo().then(data => {
checkoutInfo.value = data.result
+ // 设置提交时候的商品
+ requestParams.goods = checkoutInfo.value.goods.map(item => {
+ return {
+ skuId: item.skuId,
+ count: item.count
+ }
+ })
})
// 需要提交的字段
const requestParams = reactive({
addressId: null,
+ deliveryTimeType: 1,
+ payType: 1,
+ buyerMessage: '',
+ goods: []
})
2.绑定提交订单点击事件,进行提交即可
src/api/order.js
提交订单API函数
/**
* 提交订单
* @param {Object} order - 订单信息对象
*/
export const createOrder = (order) => {
return request('/member/order', 'post', order)
}
src/views/member/pay/checkout.vue
提交订单
<div class="submit">
<XtxButton @click="submitOrder" type="primary">提交订单XtxButton>
div>
// 提交订单
const router = useRouter()
const submitOrder = () => {
if (!requestParams.addressId) return Message({ text: '请选择收货地址' })
createOrder(requestParams).then(data => {
router.push({ path: '/member/pay', query: { id: data.result.id } })
})
}
return { checkoutInfo, changeAddress, submitOrder }