uview2.x 下,使用u-picker封装省市区选择器独立组件

需求:

只需要展示省市区名字就行了

难点:

uview没有专门的省市区选择器,而且他的选择器也做的不太好,不支持tree树,所以要自己准备好省市区json数据,还需要处理数据变成多维数组

这里我借鉴了csdn众多人的示例代码,封装的独立组件

组件代码:

<template>
	<view class="addressPicker">
		<u-picker :show="shows" ref="uPicker" :defaultIndex="defaultIndex" :columns="columns" keyName="name"
			@change="changeHandler" @cancel="cancel" @confirm="confirm"></u-picker>
	</view>
</template>

<script>
	import address from '@/utils/address.json'
	export default {
		name: "addressPicker",
		props: {
			show: {
				type: Boolean,
				default: false,
			},
			defaultIndex: {
				type: Array,
				default: () => {
					return [0, 0, 0]
				},
			}
		},
		watch: {
			show: {
				handler(newVal) {
					this.shows = newVal;
				},
				//   deep: true, //true 深度监听
				immediate: true, //声明后立刻调用
			}
		},
		data() {
			return {
				shows: false,
				columns: [], //省份数据显示,三级联动需要三维数组,展示初始数据
				columnData: [], //市数据
				columnDatas: [], //区地址
			};
		},
		created() {
			this.initDataPicker()
		},
		methods: {
			// 回调参数为包含columnIndex、value、values
			confirm(e) {
				// console.log('confirm', e.value)
				let address = ''
				if (e.value.length > 0) {
					e.value.forEach(item => {
						address += item.name
					})
					console.log('address', address)
				}
				// this.shows = false
				this.$emit("confirm", address);
			},
			// 取消
			cancel(e) {
				console.log('cancel', e)
				// this.shows = false
				this.$emit("confirm");
			},
			// 初始化省份列表
			initDataPicker() {
				//此处的province主要用作数据的初始化,即刚打开就需要进行展示的数据,这个跟第一条省份数据相关,我的第一条是北京市,所以需要columns中的三维数组,第一维度是省份数据数组,第二维度是市数据数组,第三维度是区数据数组
				let province = []; //初始数据需要展示的省份
				let province1 = [{
					name: '市辖区',
					code: '1101'
				}]; //因为第一个市北京市,所以就直接添加北京市下辖的直辖市了 也即初始数据需要展示的市,北京市只有一个市辖区
				let province2 = []; //初始数据需要展示的区域数据,也即是 北京市市辖区内的区
				address.map(item => {
					province.push(item);
				});
				address[0].children[0].children.map(item => {
					province2.push(item);
				});
				//省数据 因为要做数据初始化,所以是三维数组 
				// 数据格式 [ [所有的省份数据:{},{}] , [第一个省份下的所有的市:{},{},{}] , [第一个市下面所有的区:{},{},{}] ]
				this.columns.push(province);
				this.columns.push(province1);
				this.columns.push(province2);
				// 市数据数组,筛选address.json文件,将全国所有省下面的市数据放入数组
				// 格式[ [第一个省下面所有市,{},{},{}] , [第二个省下面所有市{},{},{}] , [第三个省下面所有市{},{},{}] ] 注意,以上的第一第二对应着 columns[0] 的数据
				address.map(item => {
					let city = [];
					item.children.map(item1 => {
						city.push(item1);
					});
					this.columnData.push(city);
				});
				//区数据数组
				//数据格式: [ 所有省下面所有市的所有区 [ 第一个省下面所有市的区:[ [第一个省下面第一个市的所有区] , [第一个省下面第二个市的所有区] ,]   ,   [ 第二个省下面所有市的区:[ [第二个省下面第一个市的所有区] , [第二个省下面第二个市的所有区] ,]   ]
				let area = [];
				address.map((item, index) => {
					let area1 = []; //省下面所有市的初始化
					item.children.map(item1 => {
						area = []; //市下面的区初始化
						item1.children.map(item2 => {
							area.push(item2);
						});
						area1.push(area); // 每循环一个市,添加该市下面的所有区
					});
					this.columnDatas.push(area1); // 每循环一个省,添加该省下面的所有市
				});
			},
			changeHandler(e) { //城市选择时触发
				const {
					columnIndex, //当前选择的列,省 / 市 / 区
					value, // 当前选择的数组内容
					values, // values为当前变化列的数组内容
					index, // 当前列的下标值
					indexs, // 当前选择 省 市 区的下表值
					picker = this.$refs.uPicker
				} = e;
				// 当第一列值发生变化时,变化第二列和第三列的值(省份变更,市和区跟着变更)
				if (columnIndex === 0) { // 判断当前变更的是省还是市还是区
					// picker为选择器this实例,变化第二列对应的选项
					picker.setColumnValues(1, this.columnData[
						index]); //设置市为该省下面的所有市,index是当前省在省份数组的下标,对应市数组中的下表就是 该省下面的所有市 的数据
					picker.setColumnValues(2, this.columnDatas[index][0]); // 设置区域为该省下面第一个市下面的所有区域
				}
				if (columnIndex === 1) {
					// 当第二列发生变化 变化对应的第三列 
					picker.setColumnValues(2, this.columnDatas[indexs[0]][index]); //同上
				}
			}
		}
	}
</script>

<style lang="scss" scoped>

</style>

使用:(一些基本代码就不弄出来了,html复制到template, js复制到script去 )

<view class="inputBox" @click="show = true">
</view>

<addressPicker :show="show" @confirm="addressConfirm" />


data() {
	return {
		// 控制组件显示隐藏
		show: false,
	}
},

methods: {
	addressConfirm(value) {
		if (value) {
			this.form.address = value
		}
		this.show = false
	}
}

示例:

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值