任务三 工单1
★5、实现对用户现有地址数据的编辑功能,通过 @tap.stop="edit(address.id)"指令阻止“修改图标”的点击事件继续传播。点击图3.1.10中的修改图标后,页面将跳转至“修改地址”界面,该界面的样式与新增地址页面相同。在跳转过程中,目标页面的onLoad生命周期函数将接收id参数,并将页面标题从“新增地址”动态更改为“修改地址”,如图3.1.11所示。
利用参数isUpdate来判断是否执行修改地址的功能。如果是,当保存时,采用splice方法对addresses数组进行操作,替换掉需要修改的地址信息,并通过store中的SET_ADDRESSES()方法将其存入状态数据中。保存完成后,使用uni.navigateBack()返回至前一个界面,并刷新显示。
涉及代码如下:
address.vue页面
<template>
<!-- 我的地址 -->
<view class="container">
<view class="main">
<!-- 用户无地址 画面 -->
<view v-if="!addresses.length" class="no-address-tips">
<view class="mb-30">暂无地址信息</view>
<view>请点击底部按钮添加地址信息</view>
</view>
<!-- 用户有地址 画面 -->
<template v-else>
<!-- 地址列表 -->
<uni-swipe-action>
<uni-swipe-action-item class="address-wrapper" :right-options="swipeOption"
@click="handleSwipeClick(address.id)" v-for="(address, index) in addresses" :key="index">
<view class="address" @tap="chooseAddress(address)">
<view class="left flex-fill overflow-hidden mr-20">
<view class="font-size-lg font-weight-bold text-truncate" style="margin-bottom: 10rpx;">
{{ address.street }}
</view>
<view class="font-size-sm text-color-assist">
{{ address.accept_name }} {{ !address.sex ? '先生' : '女士' }} {{ address.mobile }}
</view>
</view>
<image src="/static/images/edit.png" class="edit-icon" @tap.stop="edit(address.id)"></image>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</template>
</view>
<!-- 新增地址按钮 -->
<view class="btn-box">
<button type="primary" size="default" @tap="add">新增地址</button>
</view>
</view>
</template>
<script>
import {
mapState,mapMutations
} from 'vuex'
export default {
data() {
return {
swipeOption: [{
text: '删除',
style: {
backgroundColor: '#D12E32'
}
}]
};
},
computed: {
...mapState(['addresses'])//获取addresses数据
},
methods:{
...mapMutations(['SET_ADDRESS', 'SET_ADDRESSES', 'SET_ORDER_TYPE']),
chooseAddress(address) {
this.SET_ADDRESS(address) //添加派送的地址
this.SET_ORDER_TYPE('takeout') //设置状态,自取还是外卖
uni.switchTab({
url: '/pages/menu/menu'
})
},
handleSwipeClick(id) { //删除按钮点击
uni.showModal({
title: '提示',
content: '确定要删除?',
success: res => {
if (res.confirm) {
const index = this.addresses.findIndex(item => item.id == id)//流式处理,通过比较id在addresses找到选择中的一个
const addresses = JSON.parse(JSON.stringify(this.addresses))//json格式转对象
addresses.splice(index, 1) //切分,删除
this.SET_ADDRESSES(addresses)//重置addresses
uni.showToast({
title: '删除成功!',
icon: 'success'
})
}
}
})
},
add() {//新增地址
uni.navigateTo({
url: '/pages/address/add'
})
},
edit(id) {//修改地址
uni.navigateTo({
url: '/pages/address/add?id=' + id
})
},
}
}
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100%;
}
.main {
width: 100%;
padding: 30rpx;
display: flex;
flex-direction: column;
padding-bottom: 100rpx;
.no-address-tips {
text-align: center;
margin-top: 100rpx;
}
.address-wrapper {
margin-bottom: 30rpx;
}
.address {
width: 100%;
padding: 40rpx 30rpx;
background-color: #FFFFFF;
display: flex;
justify-content: space-between;
align-items: center;
.right {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.edit-icon {
width: 50rpx;
height: 50rpx;
flex-shrink: 0;
}
}
}
.btn-box {
height: 100rpx;
background-color: #FFFFFF;
box-shadow: 0 0 20rpx rgba($color: $text-color-assist, $alpha: 0.1);
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 10rpx 0;
display: flex;
align-items: center;
justify-content: center;
button {
height: 80rpx;
width: 80%;
border-radius: 50rem !important;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
add.vue页面
<template>
<!-- 新增地址 -->
<view class="container">
<view class="form-box">
<view class="form">
<list-cell :hover="false">
<view class="form-input">
<view class="label">收货人</view>
<input class="input" placeholder="请输入收货人" v-model="form.accept_name"
placeholder-class="text-color-assist" />
</view>
</list-cell>
<list-cell :hover="false">
<view class="form-input">
<view class="label">性别</view>
<view class="radio-group">
<view class="radio" :class="{'checked': !form.sex}" style="margin-right: 10rpx;"
@tap="form.sex=0">先生</view>
<view class="radio" :class="{'checked': form.sex}" @tap="form.sex=1">女士</view>
</view>
</view>
</list-cell>
<list-cell :hover="false">
<view class="form-input">
<view class="label">联系方式</view>
<input class="input" placeholder="请输入收货人联系方式" v-model="form.mobile"
placeholder-class="text-color-assist" type="number" />
</view>
</list-cell>
<list-cell :hover="false">
<view class="form-input">
<view class="label">收货地址</view>
<input class="input" placeholder="请选择收货地址" v-model="form.street"
placeholder-class="text-color-assist" />
</view>
</list-cell>
<list-cell :hover="false">
<view class="form-input">
<view class="label">门牌号</view>
<input class="input" placeholder="请输入收货人详细地址" v-model="form.door_number"
placeholder-class="text-color-assist" />
</view>
</list-cell>
</view>
<view class="btn-section">
<button type="primary" size="default" @tap="save">保存</button>
</view>
</view>
</view>
</template>
<script>
import listCell from '@/components/list-cell/list-cell'//引入自定义组件
import {
mapState,
mapMutations
} from 'vuex'
export default {
components: {
listCell
},
data() {
return {
form: {
accept_name: '',
sex: 0,
mobile: '',
street: '',
door_number: ''
},
isUpdate: false,//是否为更新地址
id: 0 //修改地址的id
}
},
async onLoad({id}) {
//为了方便演示,这里用本地缓存
if (id) {
this.isUpdate = true //修改地址
this.id = id
this.form = this.$store.state.addresses.find(item => item.id == id) //通过id找到当前地址信息
uni.setNavigationBarTitle({
title: '修改地址' // 重新动态设定 标题为修改地址
});
}
},
computed: {
...mapState(['addresses'])
},
methods: {
...mapMutations(['SET_ADDRESSES']),
save() { //新增地址
if (!this.form.accept_name) {
uni.showToast({
title: '请输入收货人',
icon: 'none'
});
return
}
if (!this.form.mobile) {
uni.showToast({
title: '请输入联系方式',
icon: 'none'
});
return
}
if (!this.form.street) {
uni.showToast({
title: '请输入收货人收货地址',
icon: 'none'
});
return
}
if (!this.form.door_number) {
uni.showToast({
title: '请输入收货人详细地址',
icon: 'none'
});
return
}
if (this.isUpdate) {//修改地址逻辑
this.form.id = this.id
// 更新地址的数据,索引为index,新对象为this.form
this.addresses.splice(this.id - 1, 1, this.form);
} else {//新增地址逻辑
this.form.id = this.addresses.length + 1 //加入一个对象的id
this.addresses.push(this.form) //加到数组中
}
this.SET_ADDRESSES(this.addresses) //存入store
uni.navigateBack()
}
}
}
</script>
<style lang="scss" scoped>
.form-box {
width: 100%;
height: 100%;
padding: 30rpx;
display: flex;
flex-direction: column;
color: $text-color-base;
.form-input {
display: flex;
align-items: center;
width: 100%;
}
.label {
width: 200rpx;
font-size: $font-size-lg;
color: $text-color-base;
font-weight: 500;
}
.input {
flex: 1;
display: flex;
align-items: center;
}
.radio-group {
display: flex;
justify-content: flex-start;
.radio {
padding: 10rpx 30rpx;
border-radius: 6rpx;
border: 2rpx solid $text-color-assist;
color: $text-color-assist;
font-size: $font-size-base;
&.checked {
background-color: $color-primary;
color: $text-color-white;
border: 2rpx solid $color-primary;
}
}
}
.btn-section {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
button {
font-size: $font-size-base;
height: 90rpx;
border-radius: 50rem !important;
width: 85%;
display: flex;
align-items: center;
justify-content: center;
}
}
}
</style>