uniapp自定义多列选择器省市两级联动

本文详细介绍了如何模仿uniapp的多列选择器,将省市数据转换为适配项目需求的二维数组结构,并通过监听滑动事件动态切换城市数据。最后展示了整个实现过程和回显功能的运用,以满足联动选择省市的需求。
部署运行你感兴趣的模型镜像

背景

这次项目有一个需求是实现省市的选择联动,可是uniapp官方提供的组件默认是省市区三级的。所以我打算自己模仿uniapp提供的多列选择器写一个符合项目需求的选择器

解决过程

首先这肯定是一个多列选择器

在这里插入图片描述
在这里插入图片描述

range

在这里可以看到,多列选择器中的数据是放在 range 中的,它是一个二维数组,长度表示列数,每一项表示每一列的数据。
所以我要把省市处理成下面这样的:

const a = [['河南省', '山东省'], ['许昌市','郑州市','洛阳市']]

value

value每一项的值,表示了选择range中对应项的第几个
例如,我选择了 河南省许昌市,那么 value 的值就是:0 0

@change

选中事件

columnchange

列选择器滑动的事件

至此,我有了实现的思路

1.找到省市的shuj
2.把省单独放在一个数组中,市放在一个数组中
3.当我滑动到某个省的时候,把市数组换成相应的数据(这一步有坑)
4.选中省市后,要把选中的下标也存一份,方便用户再点进来的时候进行回显

解决方法

1.找到省市数据

在这里插入图片描述

2.将省市数据转换为二维数组

getAddressData() {
	const that = this;
	// 所有城市列表,二维数组
	let cityAllList = [];
	// 省列表
	let provinceList = [];
	// address为省市区的json数据
	for (let key in address) {
		let newDataList = [];
		if (address[key].children) {
			for (let key2 in address[key].children) {
				newDataList.push(address[key].children[key2].name);
			}
		}
		provinceList.push(address[key].name);
		cityAllList.push(newDataList);
	}
	that.provinceList = provinceList;
	that.cityAllList = cityAllList;
	that.address = [provinceList, cityAllList[0]];
	//that.address = [provinceList, cityAllList[this.cityList[0]]]; // 考虑回显
},

维护选择器

<view class="cu-form-group">
	<text class="required"></text>
	<view class="title">所在地区</view>
	<picker
		class="pickerS"
		mode="multiSelector"
		@change="selCity"
		@columnchange="selMonitor"
		:value="cityList"
		:range="address"
	>
		<view class="setAns picker" :class="addressNode.province === '请选择城市' ? 'opcity-half':''">
			{{ addressNode.province }} {{ addressNode.city ? ','+ addressNode.city : '' }}
		</view>
	</picker>
</view>
// 监听省市区滚动
selMonitor(e) {
	const that = this
	let column = e.detail.column
	if (column == 0) {
		let index = e.detail.value
		let length = that.address[1].length
		// 改变市
		that.address[1].splice(0,length, ...that.cityAllList[index])
	}
},
// 选择省市
// 获取地址信息
selCity(e) {
	const that = this;
	let val = e.target.value
	this.cityList = val
	that.addressNode = {
		province: that.address[0][this.cityList[0]],
		city: that.address[1][this.cityList[1]]
	}
	console.log(val, that.addressNode, '123123123123123')
}

考虑回显

在onLoad中,获取用户上次选中的 value 数组,并且存起来

在执行省市转换数组时,初始化的时候,将市数据列指定为上次选中的列

that.address = [provinceList, cityAllList[this.cityList[0]]]; //this.cityList保存的是上次用户选择的value数组

至此,就完成了工作

效果

在这里插入图片描述
在这里插入图片描述

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

### 如何在 UniApp 中实现 Picker 组件的二级联动效果 #### 1. 页面结构设计 在页面中引入 `u-picker` 或原生 `<picker>` 组件作为多列选择器的基础。以下是基于 `u-picker` 的示例代码: ```html <u-picker keyName="name" :show="isPickerVisible" @cancel="isPickerVisible=false" ref="uPicker" class="uPicker" :columns="pickerColumns" @confirm="onPickerConfirm" @change="onChangeHandler" ></u-picker> ``` 上述代码定义了一个双列表的选择器,其中每一列的内容由 `pickerColumns` 控制。 --- #### 2. 数据准备与初始化 为了实现二级联动,需要预先准备好基础数据并设置默认状态。以下是一个简单的省份和城市的数据模型: ```javascript data() { return { isPickerVisible: false, // 是否显示选择器 pickerColumns: [[], []], // 初始化两列为空数组 provinceCityData: [ { name: '北京', children: [{ name: '北京市' }] }, { name: '广东', children: [{ name: '广州市' }, { name: '深圳市' }] }, { name: '江苏', children: [{ name: '南京市' }, { name: '苏州市' }] } ], selectedProvinceIndex: 0, selectedCityIndex: 0 }; } ``` 在此处,`provinceCityData` 是一个嵌套对象数组,表示省份及其对应的城市集合[^3]。 --- #### 3. 方法实现 ##### 显示/隐藏选择器 通过修改 `isPickerVisible` 来控制选择器的可见性: ```javascript methods: { togglePickerVisibility() { this.isPickerVisible = !this.isPickerVisible; if (this.pickerColumns[0].length === 0) { this.initPickerColumns(); } }, initPickerColumns() { const provinces = this.provinceCityData.map(item => item.name); this.pickerColumns = [provinces, []]; } } ``` 当首次打开选择器时,调用 `initPickerColumns()` 将第一列填充为所有可用的省份名称,并将第二列置为空。 --- ##### 联动逻辑处理 监听选择器的变化事件,在切换第一列(省份)时动态更新第二列(城市)的内容: ```javascript onChangeHandler(e) { const currentColumn = e.detail.column; // 当前改变的是哪一列 const currentIndex = e.detail.index; // 改变后的索引位置 if (currentColumn === 0) { // 如果是第一列发生变化 const selectedProvinceChildren = this.provinceCityData[currentIndex].children || []; const cityNames = selectedProvinceChildren.map(city => city.name); this.selectedProvinceIndex = currentIndex; this.pickerColumns[1] = cityNames; // 默认重置第二列为第一个城市的值 this.$refs.uPicker.setIndexes([currentIndex, 0]); } }, ``` 此部分实现了核心的联动机制:每当用户更改第一列的选项时,都会重新计算第二列的内容并刷新视图[^2]。 --- ##### 确认按钮回调 确认用户的最终选择并将结果显示出来: ```javascript onPickerConfirm(e) { const result = e.detail.value; // 获取每列的当前选中项 const chosenProvince = this.pickerColumns[0][result[0]]; const chosenCity = this.pickerColumns[1][result[1]]; console.log(`您选择了 ${chosenProvince} -> ${chosenCity}`); this.isPickerVisible = false; // 关闭选择器 } ``` 此处提取了用户最后选定的结果,并将其打印到控制台或用于其他业务逻辑[^1]。 --- ### 完整示例总结 以上代码片段展示了如何利用 `u-picker` 实现二级联动的效果。具体来说,它涵盖了以下几个方面: - **页面布局**:使用 `u-picker` 插件构建多列选择器。 - **数据绑定**:通过 `pickerColumns` 属性管理各列内容。 - **联动逻辑**:借助 `@change` 事件动态调整子列内容。 - **结果获取**:捕获用户提交的信息并通过 `@confirm` 进行后续处理。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值