uniapp省市区懒加载封装

一、z-region.vue 直接复制就可用,需要修改请求接口 getAddressList

vue2和vue3皆可使用(微信小程序,H5支持)

javascript 复制代码
<template>
	<view>
		<view class="list">
			<picker class="picker" mode="multiSelector" :range="region" range-key="name" :value="regionIndex"
				@change="pickerChange" @columnchange="pickerColumnchange">
				<view class="pbox" :class="{'pbox_hover':regionStr != '请选择'}">
					<view class="region-str" :style="{textAlign: inputAlign}">{{regionStr}}</view>
					<text class="iconfont icon-you"></text>
				</view>
			</picker>
		</view>
	</view>
</template>

<script>
	import {
		getAddressList,
	} from '@/api/address/index.js'
	export default {
		data() {
			return {
				// 原数组
				oldRegion: [],
				// 处理后的数组
				region: [
					[],
					[],
					[]
				],
				// 选择省市区的下标Index
				regionIndex: [0, 0, 0],
				// 省市区字符串
				regionStr: '请选择'
			};
		},
		props: {
			height: {
				type: [Number],
				default: 92
			},
			width: {
				type: [Number],
				default: 710
			},
			previnceId: {
				type: [Number],
				default: 11
			},
			cityId: {
				type: [Number],
				default: 1101
			},
			countyId: {
				type: [Number],
				default: 110101
			},
			isRevise: {
				type: [Boolean],
				default: false
			},
			inputAlign: {
				type: [String],
				default: 'right'
			},
			country: {
				type: [String],
				default: 'domestic'
			}
		},
		methods: {
			pickerChange(e) {
				this.regionIndex = e.detail.value;
				if (this.region[2].length > 0) {
					this.regionStr = this.region[2][this.regionIndex[2]].name;

					// 组件传值,返回所需格式
					this.$emit('region', {
						name: this.region[2][this.regionIndex[2]].name,
						code: this.region[2][this.regionIndex[2]].code
					});
				}
			},
			pickerColumnchange(e) {
				if (e.detail.column === 0) {
					// 选择了省,发起请求获取城市
					this.regionIndex = [e.detail.value, 0, 0];
					this.loadCities(this.region[0][e.detail.value].code);
				} else if (e.detail.column === 1) {
					// 选择了城市,发起请求获取县区
					this.regionIndex[1] = e.detail.value;
					this.regionIndex[2] = 0;
					this.loadCounties(this.region[1][e.detail.value].code);
					// this.regionIndex[1] = e.detail.value;
					// this.regionIndex[2] = 0; // 重置县区选择
				} else if (e.detail.column === 2) {
					this.regionIndex[2] = e.detail.value;
				}
			},
			loadCities(provinceCode) {
				getAddressList({
					parentCode: provinceCode
				}).then((response) => {
					const cityArr = response.data.map(item => ({
						name: item.name,
						code: item.code
					}));
					this.$set(this.region, 1, cityArr);
					if (cityArr.length > 0) {
						this.loadCounties(cityArr[0].code); // 默认加载第一个城市的县区
					}
				})
			},
			loadCounties(cityCode) {

				getAddressList({
					parentCode: cityCode
				}).then((response) => {
					const countyArr = response.data.map(item => ({
						name: item.name,
						code: item.code
					}));
					this.$set(this.region, 2, countyArr);
				})
			},

			getAddress() {
					getAddressList({
						parentCode: 0
					}).then((response) => {
						this.oldRegion = response.data;

						// 在 region[0] 数组的开头添加"请选择"选项
						this.region[0].push({
							name: '请选择',
							code: null // 或者使用一个特定的值,表示未选择
						});

						this.oldRegion.map((item, index) => {
							this.region[0].push({
								name: item.name,
								code: item.code
							});
							if (this.previnceId == item.code) {
								this.regionIndex[0] = index;
								if (item.code !== null) {
									this.loadCities(item.code); // 加载选中省的城市
								}
							}
						});
					})
			}
		},

		created() {
			// 初始加载省份
			this.getAddress();
		}
	}
</script>

<style lang="scss" scoped>
	.list {
		padding: 0 8rpx;
		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		position: relative;

		.picker {
			flex: 1;
			height: 92rpx;

			.pbox {
				width: 100%;
				height: 92rpx;
				display: flex;
				flex-direction: row;
				align-items: center;
				justify-content: space-between;
				color: #808080;

				.region-str {
					width: 100%;
				}

				.icon-you {
					font-size: 28rpx;
				}
			}

			.pbox_hover {
				color: #383838;
			}
		}

		.name {
			width: 168rpx;
			font-size: 32rpx;
			color: #383838;
		}

		.icon-you {
			font-size: 28rpx;
			color: #999999;
		}

		.input {
			flex: 1;
			height: 100%;
			line-height: 92rpx;
			color: #9080A1;
		}

		.textarea {
			flex: 1;
			height: 100%;
			color: #A9A9A9;
		}
	}
</style>

二、页面中使用

javascript 复制代码
<template>
    <view>
		<Region @region="resgclick">
	</view>
</template>


<script setup>
    /** 引入 */
	import Region from '@/components/w-region.vue';

    // 起始地行政区划
	function resgclick(e) {

        /** 本人是需要区的名称和code,所以只返回了区的,若想全部返回请看(三) */
		form.value.qsd = e.name;
		form.value.qsdCode = e.code;
	}

</script>

三、返回全部(省市区)名称和code

javascript 复制代码
/** 修改w-region中的代码 */

pickerChange(e) {
				this.regionIndex = e.detail.value;
				if (this.region[2].length > 0) {
					this.regionStr = this.region[2][this.regionIndex[2]].name;

					// 组件传值,返回所需格式
					this.$emit('region', {
						name: [
                            this.region[0][this.regionIndex[0]].name
                            this.region[1][this.regionIndex[1]].name
                            this.region[2][this.regionIndex[2]].name
                        ],
						code: [
                            this.region[0][this.regionIndex[0]].code
                            this.region[1][this.regionIndex[1]].code
                            this.region[2][this.regionIndex[2]].code
                        ]
					});
				}
			},

++我也是拿其他 大佬 的进行修改的(只不过他的是本地数据,内容太大),所以进行了修改,若是遇到问题 欢迎讨论++

相关推荐
歪歪100几秒前
Redux和MobX在React Native状态管理中的优缺点对比
前端·javascript·react native·react.js·架构·前端框架
东风西巷4 分钟前
Atlantis Word Processor:全方位的文字处理专家
前端·学习·word·软件需求
今天不要写bug16 分钟前
基于elementUI实现一个可编辑的表格(简洁版)
前端·javascript·elementui
上优19 分钟前
Vue3纯前端同源跨窗口通信移动AGV小车
前端·vue.js·状态模式
h_k1008620 分钟前
Chrome 插件开发入门技术文章大纲
前端·chrome
一只小阿乐20 分钟前
vue-router 的实现原理
前端·javascript·vue.js·路由·vue-router
Zz_waiting.21 分钟前
案例开发 - 日程管理 - 第七期
开发语言·前端·javascript·vue.js·html·路由
writeone21 分钟前
9-10关于JS初学产生的问题
开发语言·javascript·ecmascript
一只小风华~24 分钟前
Vue:事件处理机制详解
前端·javascript·vue.js·typescript·前端框架
dy17174 小时前
element-plus表格默认展开有子的数据
前端·javascript·vue.js