uni-app省市区查询组件的封装

一.最终实现效果

 

 

二. 组件结构

 

三.使用 

<pickerAddress @change="changeAddress">
	<view class="address-cl">{{ addressText }}</view>
</pickerAddress>

 @change里面会有点击确定的回调,回调里面包含了参数

addreeText是显示在那一行的地址信息

四.pickerAddress.vue

<template>
	<picker @change="bindPickerChange" @columnchange="columnchange" :range="array" range-key="name" :value="value" mode="multiSelector"><slot></slot></picker>
</template>

<script>
import AllAddress from './data';
import provinceCode from './province.js';
import cityCode from './city.js';
import areaCode from './area.js';
let selectVal = ['', '', ''];

export default {
	data() {
		return {
			value: [0, 0, 0],
			array: [],
			index: 0
		};
	},
	created() {
		this.initSelect();
	},
	methods: {
		// 初始化地址选项
		initSelect() {
			this.updateSourceDate() // 更新源数据
				.updateAddressDate(); // 更新结果数据
			// this.$forceUpdate(); // 触发双向绑定
		},
		// 地址控件改变控件
		columnchange(d) {
			this.updateSelectIndex(d.detail.column, d.detail.value) // 更新选择索引
				.updateSourceDate() // 更新源数据
				.updateAddressDate(); // 更新结果数据
			// this.$forceUpdate(); // 触发双向绑定
		},

		/**
		 * 更新源数据
		 * */
		updateSourceDate() {
			this.array = [];
			this.array[0] = AllAddress.map(obj => {
				return {
					name: obj.name
				};
			});
			this.array[1] = AllAddress[this.value[0]].city.map(obj => {
				return {
					name: obj.name
				};
			});
			this.array[2] = AllAddress[this.value[0]].city[this.value[1]].area.map(obj => {
				return {
					name: obj
				};
			});
			return this;
		},

		/**
		 * 更新索引
		 * */
		updateSelectIndex(column, value) {
			let arr = JSON.parse(JSON.stringify(this.value));
			arr[column] = value;
			if (column === 0) {
				arr[1] = 0;
				arr[2] = 0;
			}
			if (column === 1) {
				arr[2] = 0;
			}
			this.value = arr;
			return this;
		},

		/**
		 * 更新结果数据
		 * */
		updateAddressDate() {
			selectVal[0] = this.array[0][this.value[0]].name;
			selectVal[1] = this.array[1][this.value[1]].name;
			selectVal[2] = this.array[2][this.value[2]].name;
			return this;
		},

		/**
		 * 点击确定
		 * */
		bindPickerChange(e) {
			//将value转码返回出去
			let code = this.getAddressCode() || [];

			this.$emit('change', {
				index: this.value,
				data: selectVal,
				code: code
			});
			return this;
		},

		getAddressCode() {
			let reArr = [];

			//省
			let p_key;
			for (p_key in provinceCode) {
				if (provinceCode[p_key] == selectVal[0]) {
					reArr.push(p_key);
					break;
				}
			}
			if (reArr.length != 1) {
				return [];
			}
			let province_pre = reArr[0].substr(0, 2);

			//市
			let mainKey, c_key;
			for (mainKey in cityCode) {
				for (c_key in cityCode[mainKey]) {
					if (cityCode[mainKey][c_key] == selectVal[1]) {
						if (c_key.substr(0, 2) == province_pre) {
							reArr.push(c_key);
							break;
						}
					}
				}
			}
			if (reArr.length != 2) {
				return [];
			}
			let city_pre = reArr[1].substr(0, 4);

			//区
			let a_key;
			for (mainKey in areaCode) {
				for (a_key in areaCode[mainKey]) {
					if (areaCode[mainKey][a_key] == selectVal[2]) {
						if (a_key.substr(0, 4) == city_pre) {
							reArr.push(a_key);
							break;
						}
					}
				}
			}

			return reArr;
		}
	}
};
</script>

<style></style>

 另外几个文件放在旁边的博客文章里面,太长了.....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一路追求匠人精神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值