承接上面一篇文章,没有看到上篇文章的童鞋请点这里uni-app微信公众号(4)——地址管理页面_徐小硕—心之所向,素履以往-CSDN博客当然在一个类似商城的公众号中,自然也少不了用户地址的添加,下面我们就写一个收货地址的页面,页面中,可以简单的自动识别地址信息,设置默认地址,设置地址标签等功能,先来看看效果截图。(1)地址管理页面(1.1)页面代码 其实HTML页面代码就是一个简单循环遍历,先把填写的地址保存在vuex中,然后缓存到localStorage中,然后获取localStorage中的缓存,v-for循环显示出来。其中需要注意的是,:class="{red:res.i...https://blog.csdn.net/qq_40601005/article/details/121080638接下来,我们介绍新增、修改地址的功能实现。下面是截图样式

 (1)新增、修改地址

        (1.1)页面代码

        页面中

        ①先使用uView组件的<u-form>表单组件,来填写地址信息

        ②然后使用一个textarea组件,用来自动识别收货信息,填写到<u-form>中,这个功能还只是简单的识别,不能像某宝做的那么强大

        ③然后是地址标签,三个已显示标签,还可以添加自定义标签,这个功能还算完善

        ④最后就是设置默认地址,所有地址中只有一个默认地址,此功能已实现

代码如下:

<template>
	<view class="wrap">
		<view class="top">
			<u-form class="formClass" :rules="addSiteRules" :model="recipientInfo" :errorType="errorType"
				ref="addSiteForm">
				<!-- <view class="item"> -->
				<u-form-item :label-width="labelWidth" label="收货人" prop="name">
					<u-input v-model="recipientInfo.name" :trim="true" type="text" placeholder="请填写收货人姓名" />
				</u-form-item>
				<u-form-item :label-width="labelWidth" label="手机号码" prop="phone">
					<u-input v-model="recipientInfo.phone" type="number" placeholder="请填写收货人手机号" />
				</u-form-item>
				<u-form-item :label-width="labelWidth" label="所在地区" prop="area">
					<u-input v-model="recipientInfo.area" :select-open="pickerShow" @click="pickerShow = true"
						type="select" placeholder="省市区县" />
				</u-form-item>
				<u-form-item :label-width="labelWidth" label="详细地址" prop="address">
					<u-input class="address" v-model="recipientInfo.address" type="textarea"
						placeholder="县、乡镇、街道、楼牌等" />
				</u-form-item>
			</u-form>
			<view class="site-clipboard">
				<view v-show="pasteText">
					<u-input class="address" :clearable="false" v-model="pasteTextarea" type="textarea"
						placeholder="粘贴收货人姓名、手机号、地址,可自动识别您的收货信息。如(张xx 151*****1234 北京市朝阳区**号)" />
					<!-- <textarea placeholder-class="line" v-model="pasteTextarea" value=""
						placeholder="粘贴收货人姓名、手机号、地址,可自动识别您的收货信息">
					</textarea> -->
					<view class="btn">
						<u-button class="clear" shape="circle" size="mini" @click="clearPaste">清空</u-button>
						<u-button class="sumbit" shape="circle" size="mini" type="success" @click="sumbitPaste">提交
						</u-button>
					</view>
				</view>
				<view class="clipboard" @click="showPasteText">
					地址粘贴板
					<u-icon :name="iconName" class="icon" :size="20"></u-icon>
				</view>
			</view>
		</view>
		<view class="bottom">
			<view class="tag">
				<view class="left">标签</view>
				<view class="right">
					<template v-for="(tag,i) in tagList">
						<text :class="[tag.checked ? 'active': '','tags']" :key="i"
							@click="tagSelect(tag.value,tag.checked,i)">{{tag.value}}</text>
					</template>
					<view class="tags plus" @click="addTag">
						<u-icon size="22" name="plus"></u-icon>
					</view>
				</view>
			</view>
			<view class="default">
				<view class="left">
					<view class="set">设置默认地址</view>
					<view class="tips">提醒:每次下单会默认推荐该地址</view>
				</view>
				<view class="right">
					<u-switch active-color="red" v-model="recipientInfo.isDefault"></u-switch>
				</view>
			</view>
			<view class="sumbitBtn">
				<u-button class="kmbtn" type="primary" plain size="medium" :ripple="true" ripple-bg-color="#4a94de"
					@click="submitInfo">保存</u-button>
				<u-button v-if="!isUpdate" class="kmbtn" type="warning" plain size="medium" :ripple="true"
					ripple-bg-color="#ffaa00" @click="resetInfo">重置</u-button>
				<u-button v-if="isUpdate" class="kmbtn" type="error" plain size="medium" :ripple="true"
					ripple-bg-color="#ffaa00" @click="deleteShow=true">删除</u-button>
			</view>
		</view>
		<u-picker mode="region" ref="uPicker" @confirm="areaSelect" v-model="pickerShow" />
		<u-modal v-model="addTagChecked" @confirm="confirmAddTag" :mask-close-able="true" title="" :zoom="true">
			<view class="slot-content">
				<u-input v-model="addTagValue" :maxlength="4" type="text" placeholder="请填写标签(最多4个字)" />
			</view>
		</u-modal>
		<u-toast ref="uToast" />
		<u-modal v-model="deleteShow" @confirm="deleteInfo(recipientInfo)" :show-cancel-button="true"
			confirm-color="red" :content="deleteContent"></u-modal>
	</view>
</template>

        (1.2)vue代码

①选择标签相关代码

       // 标签选择
            tagSelect(value, checked, index) {
                checked == false ? this.recipientInfo.tag = value : this.recipientInfo.tag = '';
                //只能选择一个标签
                this.tagList.forEach((tag, i) => {
                    if (i == index) {
                        this.tagList[i].checked = !this.tagList[i].checked
                    } else {
                        this.tagList[i].checked = false
                    }
                })
            },

//标签HTML代码

<view class="left">标签</view>
                <view class="right">
                    <template v-for="(tag,i) in tagList">
                        <text :class="[tag.checked ? 'active': '','tags']" :key="i"
                            @click="tagSelect(tag.value,tag.checked,i)">{{tag.value}}</text>
                    </template>
                    <view class="tags plus" @click="addTag">
                        <u-icon size="22" name="plus"></u-icon>
                    </view>
 </view>

 ②添加新的标签代码

        新的标签没有去判断是否存在,这个小BUG每个人可以根据自己需求去修改。

            // 打开添加标签
            addTag() {
                this.addTagChecked = true;
                this.addTagValue = ''
            },
            //确认添加标签
            confirmAddTag() {
                console.log(this.addTagValue);
                if (this.addTagValue != '') {
                    this.tagList.forEach((tag, i) => {
                        this.tagList[i].checked = false;
                    })
                    this.tagList.push({
                        value: this.addTagValue,
                        checked: true
                    })
                    this.recipientInfo.tag = this.addTagValue
                } else {
                    this.$refs.uToast.show({
                        title: '不能为空',
                        position: 'top',
                        type: 'error',
                    })
                    this.addTagChecked = true;
                }

            },

③自动识别地址代码

        自动识别的地址样式,如:张三18811112222江苏省南京市鼓楼区幸福花园街道幸福小区,或者如:姓名:张三电话:18811112222地址:江苏省南京市鼓楼区幸福花园街道幸福小区

可以自动识别以上两种类型的地址信息,没有做太过强大的识别功能。

        //提交粘贴的收件人信息
            sumbitPaste() {
                var text = this.pasteTextarea;
                text = text.replace(/\s*/g, ""); //清空文本全部空格
                // text = text.replace(/(^\s*)|(\s*$)/g, "") //清除文本前后空格
                console.log(text);
                if (text == '') {
                    this.recipientInfo = {
                        name: '',
                        phone: '',
                        area: '',
                        address: '',
                    }
                    return;
                }
                //电话号码正则表达式
                var regx = /(1[3|4|5|7|8][\d]{9}|0[\d]{2,3}-[\d]{7,8}|400[-]?[\d]{3}[-]?[\d]{4})/g;
                var phone_num = text.match(regx);
                console.log(phone_num);
                if (phone_num != null) {
                    var phone = text.indexOf(phone_num[0]);
                    console.log(phone);
                }

                //姓名,电话,地址
                var name = text.indexOf("姓名:")
                var u_area = ''
                if (name >= 0) {
                    var phone = text.indexOf("电话:"),
                        address = text.indexOf("地址:"),
                        cityOne = text.indexOf("省"),
                        cityTwo = text.indexOf("市"),
                        cityThree = text.indexOf('区') >= 0 ? text.indexOf('区') : text.indexOf("县");
                    console.log(cityOne);
                    console.log(cityTwo);
                    var u_name = text.substring(name + 3, phone),
                        u_phone = text.substring(phone + 3, address),
                        u_address = text.substring(address + 3, text.length);
                    if (cityOne >= 0) {
                        u_area = text.substring(address + 3, cityOne + 1) + '-' +
                            text.substring(cityOne + 1, cityTwo + 1) + '-' +
                            text.substring(cityTwo + 1, cityThree + 1)
                    } else {
                        u_area = text.substring(address + 3, cityTwo + 1) + '-' +
                            text.substring(cityTwo + 1, cityThree + 1)
                    }
                    this.recipientInfo = {
                        name: u_name,
                        phone: u_phone,
                        area: u_area,
                        address: u_address,
                        tag: '',
                        isDefault: false,
                    }
                    console.log(this.recipientInfo);
                } else if (phone >= 0) {
                    var cityOne = text.indexOf("省"),
                        cityTwo = text.indexOf('市'),
                        cityThree = text.indexOf('区') >= 0 ? text.indexOf('区') : text.indexOf("县");
                    // cityThree2 = text.indexOf("县");
                    var u_name = text.substring(0, phone),
                        u_phone = text.substring(phone, phone + 11),
                        u_address = text.substring(phone + 11, text.length);

                    if (cityOne >= 0) {
                        u_area = text.substring(phone + 11, cityOne + 1) + '-' +
                            text.substring(cityOne + 1, cityTwo + 1) + '-' +
                            text.substring(cityTwo + 1, cityThree + 1)
                    } else {
                        u_area = text.substring(phone + 11, cityTwo + 1) + '-' +
                            text.substring(cityTwo + 1, cityThree + 1)
                    }

                    this.recipientInfo = {
                        name: u_name,
                        phone: u_phone,
                        area: u_area,
                        address: u_address,
                        tag: '',
                        isDefault: false,
                    }
                    console.log(this.recipientInfo);
                } else {
                    this.recipientInfo = {
                        name: '',
                        phone: '',
                        area: '',
                        address: '',
                        tag: '',
                        isDefault: false,
                    }
                    return;
                }
                console.log(this.recipientInfo);
            },

④修改待更新地址信息代码

 

        //获取待更新数据
            updateAddress(info) {
                console.log(info);
                this.isUpdate = JSON.stringify(info) != "{}" ? true : false;
                console.log(this.isUpdate);
                let addressInfo = ''
                if (JSON.stringify(info) != "{}") {
                    addressInfo = JSON.parse(info.addressInfo);
                    this.recipientInfo = addressInfo;
                }
                console.log(this.recipientInfo);

                // 标签是否存在
                let isExist = this.tagList.find((n, i) => n.value == this.recipientInfo.tag)
                console.log(isExist);
                if(this.isUpdate && this.recipientInfo.tag!=''){
                    if (isExist != undefined ) {
                        this.tagList.forEach((tag, i) => {
                            if (tag.value == this.recipientInfo.tag) {
                                this.tagList[i].checked = true
                            }
                        })
                    } else {
                        this.tagList.push({
                            value: this.recipientInfo.tag,
                            checked: true
                        })
                    }
                }
            },

 (1.3)css样式代码

<style lang="scss" scoped>
	/deep/ .line {
		color: $u-light-color;
		font-size: 32rpx;
	}

	.wrap {
		background-color: #f2f2f2;

		.top {
			background-color: #ffffff;
			border-top: solid 2rpx $u-border-color;
			padding: 22rpx;

			.formClass {
				.u-form-item {
					font-size: 32rpx !important;
				}

			}

			.item {
				display: flex;
				font-size: 32rpx;
				line-height: 100rpx;
				align-items: center;
				border-bottom: solid 2rpx $u-border-color;

				.left {
					width: 180rpx;
				}

				input {
					text-align: left;
				}
			}

			.address {
				// width: 100%;
				height: 170rpx;
				background-color: #f7f7f7;
				line-height: 60rpx;
				margin: 10rpx auto;
				padding: 10rpx;
			}

			.site-clipboard {
				padding: 0 20rpx;

				.address {
					width: 100%;
					height: 200rpx;
					background-color: #f7f7f7;
					line-height: 60rpx;
					margin: 40rpx auto;
					padding: 20rpx;
				}

				.btn {
					display: flex;
					padding-bottom: 30rpx;
				}

				.clipboard {
					display: flex;
					justify-content: center;
					align-items: center;
					font-size: 26rpx;
					color: $u-tips-color;
					height: 80rpx;

					.icon {
						margin-top: 6rpx;
						margin-left: 10rpx;
					}
				}
			}
		}

		.bottom {
			margin-top: 20rpx;
			padding: 22rpx;
			background-color: #ffffff;
			font-size: 28rpx;

			.tag {
				display: flex;

				.left {
					width: 160rpx;
					line-height: 160rpx;
				}

				.right {
					display: flex;
					flex-wrap: wrap;

					.active {
						color: #2979FF !important;
						border: solid 2rpx #2979FF !important;
					}

					.tags {
						width: 140rpx;
						padding: 16rpx 8rpx;
						border: solid 2rpx $u-border-color;
						text-align: center;
						border-radius: 50rpx;
						margin: 0 10rpx 20rpx;
						display: flex;
						font-size: 28rpx;
						align-items: center;
						justify-content: center;
						color: $u-content-color;
						line-height: 1;
					}

					.plus {
						//padding: 10rpx 0;
					}
				}
			}

			.default {
				margin-top: 50rpx;
				display: flex;
				justify-content: space-between;
				border-bottom: solid 2rpx $u-border-color;
				line-height: 64rpx;

				.tips {
					font-size: 24rpx;
				}

				.right {
					padding-right: 30rpx;
				}
			}
		}

		.sumbitBtn {
			text-align: center;
			margin: 60rpx 0rpx 60rpx 0rpx;
		}

		.sumbitBtn .kmbtn {
			margin-right: 10rpx;
		}

		.slot-content {
			font-size: 28rpx;
			color: $u-content-color;
			padding-left: 30rpx;
		}
	}
</style>

(2)地址管理vuex代码

上面讲完,页面代码和逻辑代码,最重要的就是vuex代码对地址信息的增删改查。

import Vue from 'vue';

//初始化数据
const state = {
	address_list: jsAddressList.map((list, i) => {
		return list;
	}),
	addressList: []
};
// getter 抛出去的数据
const getters = {

};
// action 异步的操作
const actions = {
	//添加,更新操作
	addAddress({
		commit
	}, product) {
		commit('addToAddress', {
			product: product
		});
	},
	//删除操作
	deleteAddress({
		commit
	}, product) {
		commit('deleteToAddress', {
			id: product.id
		});
	},
};
//mutation
const mutations = {
	addToAddress(state, {
		product
	}) { //解析id
		console.log(product);
		let length = state.addressList.length;
		let lastId = state.addressList.slice(-1) == '' ? 0 : state.addressList.slice(-1)[0].id;
		// console.log("last_id----" + lastId);
		let isDef = product.isDefault;
		let isUpdate = state.addressList.find((n, i) => n.id == product.id);
		// console.log(isUpdate);
		if (isDef && length != 0) {
			console.log(isDef);
			let address = state.addressList.find((n, i) => n.isDefault == true);
			console.log(address);
			if (address != undefined) {
				address.isDefault = false
			}
		}
		if (!isUpdate) {
			let list = {};
			list.id = lastId + 1
			for (let a in product) {
				list[a] = product[a]
			}
			state.addressList.push({
				...list,
			});
		} else {
			for (let a in isUpdate) {
				isUpdate[a] = product[a]
			}
			console.log(isUpdate);
		}
		console.info(state.addressList);
		localStorage.setItem('addressList', JSON.stringify(state.addressList));
	},
	//删除收货地址信息
	deleteToAddress(state, {
		id
	}) {
		console.log(id);
		state.addressList.forEach((n, i) => {
			if (n.id == id) {
				state.addressList.splice(i, 1);
			}
		});
		localStorage.setItem('addressList', JSON.stringify(state.addressList));
	},
	// 获取缓存
	getLocalAddressList(state) {
		if (localStorage.getItem('addressList')) {
			state.addressList = JSON.parse(localStorage.getItem('addressList')).map(item => Object.assign({},
				item));

		}
	},
};
export default {
	state,
	mutations,
	actions,
	getters
};

        这两篇文章,详细的介绍了大多数地址管理的应用场景,也只是仅供大家参考,文章如有不正确的地方,还望斧正~

        如果文章对您有些许帮助,还望一键三连,谢谢~

Logo

前往低代码交流专区

更多推荐