当前位置: 首页 > news >正文

ArkTS省市区三级联动选择器实现详解

在鸿蒙应用开发中,省市区三级联动是一个常见的功能需求,如收货地址选择、用户信息注册等场景。本文将基于ArkTS语言,详细介绍如何实现一个高效、可复用的省市区三级联动选择器

功能特点

•支持省、市、区三级数据联动

•平滑的滚动选择体验

•高性能的数据加载与渲染

•灵活的定制化选项

实现原理

三级联动选择器的核心原理是基于数据驱动视图更新。当用户选择省份时,城市列表会根据所选省份动态更新;同样,选择城市后,区县列表也会相应变化。

关键技术点

•使用TextPicker组件实现滚动选择

•采用@State装饰器管理组件状态

•通过异步数据加载提升用户体验

•利用函数防抖优化性能

基础实现

数据结构定义

首先需要定义省市区数据的结构模型:

// 省份信息模型
class ProvinceBean {id: number;code: string;label: string;
}
​
// 城市信息模型  
class CityBean {id: number;province_code: string;code: string;label: string;
}
​
// 区县信息模型
class DistrictBean {id: number;city_code: string;code: string;label: string;
}
[4](@ref)
​
​
​
​

基础组件框架

@Entry
@Component
struct AreaPickerPage {// 控制弹窗显示/隐藏@State isPickerVisible: boolean = false;// 省市区数据数组@State provinceData: ProvinceBean[] = [];@State cityData: CityBean[] = [];@State districtData: DistrictBean[] = [];// 当前选中的索引@State selectedProvinceIndex: number = 0;@State selectedCityIndex: number = 0;@State selectedDistrictIndex: number = 0;
​build() {Column() {// 页面内容Button('选择地址').onClick(() => {this.isPickerVisible = true;})}.bindSheet(this.isPickerVisible, this.pickerBuilder(), {height: 300})}
​@BuilderpickerBuilder() {// 选择器内容}
}
[1](@ref)
​
​
​
​

完整实现方案

数据加载与初始化

应用启动时加载初始数据:

async aboutToAppear() {// 获取省份数据const provinces = await this.loadProvinceData();this.provinceData = provinces;if (provinces.length > 0) {// 获取第一个省份的城市数据const cities = await this.loadCityData(provinces[0].code);this.cityData = cities;if (cities.length > 0) {// 获取第一个城市的区县数据const districts = await this.loadDistrictData(cities[0].code);this.districtData = districts;}}
}
[1](@ref)
​
​
​
​

联动选择器实现

@Builder
pickerBuilder() {Column() {// 顶部操作栏Row() {Text('取消').onClick(() => {this.isPickerVisible = false;})Blank()Text('确定').onClick(() => {this.onAddressSelected();this.isPickerVisible = false;})}.width('100%').padding(20)
​// 三级选择器Row() {// 省份选择TextPicker({ range: this.getProvinceNames(), selected: this.selectedProvinceIndex }).onChange((value: string, index: number) => {this.onProvinceChange(index);}).layoutWeight(1)
​// 城市选择  TextPicker({ range: this.getCityNames(), selected: this.selectedCityIndex }).onChange((value: string, index: number) => {this.onCityChange(index);}).layoutWeight(1)
​// 区县选择TextPicker({ range: this.getDistrictNames(), selected: this.selectedDistrictIndex }).layoutWeight(1)}.height(200)}
}
[7](@ref)
​
​
​
​

联动逻辑处理

// 省份变更处理
async onProvinceChange(index: number) {// 使用防抖避免频繁触发if (this.debounceTimer) {clearTimeout(this.debounceTimer);}this.debounceTimer = setTimeout(async () => {this.selectedProvinceIndex = index;const province = this.provinceData[index];// 加载城市数据this.cityData = await this.loadCityData(province.code);this.selectedCityIndex = 0;if (this.cityData.length > 0) {// 加载区县数据this.districtData = await this.loadDistrictData(this.cityData[0].code);this.selectedDistrictIndex = 0;}}, 300);
}
​
// 城市变更处理
async onCityChange(index: number) {this.selectedCityIndex = index;const city = this.cityData[index];// 加载区县数据this.districtData = await this.loadDistrictData(city.code);this.selectedDistrictIndex = 0;
}
[1](@ref)
​
​
​
​

性能优化

函数防抖处理

在处理快速滚动时,通过函数防抖避免频繁请求:

@State debounceTimer: number = -1;
​
// 防抖函数
debounce(func: Function, delay: number) {return (...args: any[]) => {if (this.debounceTimer !== -1) {clearTimeout(this.debounceTimer);}this.debounceTimer = setTimeout(() => {func.apply(this, args);}, delay);};
}
[1](@ref)
​
​
​
​

数据缓存策略

实现数据缓存避免重复请求:

// 数据缓存对象
private static dataCache: Map<string, any> = new Map();
​
// 带缓存的数据加载
async loadDataWithCache(url: string): Promise<any> {if (AreaPickerPage.dataCache.has(url)) {return AreaPickerPage.dataCache.get(url);}const data = await this.requestData(url);AreaPickerPage.dataCache.set(url, data);return data;
}
[4](@ref)
​
​
​
​

高级功能扩展

自定义样式配置

支持深色模式适配和自定义主题:

@Extend(TextPicker)
function customPickerStyle() {.selectedTextStyle({color: $r('app.color.picker_selected'),font: { size: 18, weight: FontWeight.Medium }}).textStyle({color: $r('app.color.picker_normal'),font: { size: 16 }})
}
[7](@ref)
​
​
​
​

云端数据集成

支持从云端动态加载地址数据:

// 调用云函数获取省份数据
async loadProvinceFromCloud() {try {const functionCallable = agconnect.function().wrap("province-query-$latest");const result = await functionCallable.call({});this.provinceData = result.getValue().result;} catch (error) {console.error('Failed to load province data:', error);}
}
[3,4](@ref)
​
​
​
​

组件封装与复用

将三级联动选择器封装为独立组件,便于复用:

@Component
export struct AreaPickerComponent {@Prop onConfirm: (province: ProvinceBean, city: CityBean, district: DistrictBean) => void;@Prop onCancel: () => void;@Link selectedProvince: ProvinceBean;@Link selectedCity: CityBean; @Link selectedDistrict: DistrictBean;
​build() {// 组件实现}
}
​
​
​
​

调用方式:

// 在父组件中使用
AreaPickerComponent({onConfirm: (province, city, district) => {console.log(`选中: ${province.label} ${city.label} ${district.label}`);},onCancel: () => {console.log('选择取消');}
})
[2,7](@ref)
​
​
​
​

总结

通过ArkTS实现省市区三级联动选择器,关键点在于:合理的状态管理高效的数据加载流畅的联动交互。本文介绍了从基础实现到高级优化的完整方案,开发者可以根据实际需求进行调整和扩展。

http://www.dtcms.com/a/533251.html

相关文章:

  • 自己代码做网站做商城的网站用什么框架好
  • 怎么上传自己的网站红豆网桂林论坛
  • 西乡移动网站建设网投网站怎么做
  • 【第十九周】机器学习笔记08
  • 文件管理百度seo学院
  • 成都网站建设 龙兵做网站应该注意什么
  • CDC(Communication Device Class)是什么?
  • 东台建设网站的公司成都纯手工seo
  • fopen 函数实现追踪(glibc 2.9)(了解和选学)
  • 国产数据库之XuguDB:虚怀若谷
  • 湖南移动官网网站建设微信营销的优缺点
  • 自建网站推广的最新发展河北网络建站
  • 精品课程网站建设意义最近免费韩国电影hd无
  • 怎么建设小说网站中国企业500强排行榜
  • 建设银行企业网站首页wordpress图像缩放插件
  • 奇偶分家:破解n^4+4^n的合数身份
  • js微任务输出
  • Linux小课堂: 守护进程与初始化进程服务详解
  • synchronized 和 Lock
  • 2.2.1.2 大数据方法论与实践指南-基于飞书项目的项目管理规范
  • 做防腐木网站优秀网站设计流程
  • LangChain最详细教程之Model I/O(二)Prompt Template
  • STM32F103C8T6_UART串口通信完整教程
  • Gorm(一)查询方法
  • 网站管理工具wordpress中文版和英文版区别
  • 新网网站空间到期停了 咋续费北海哪里做网站建设
  • 百日挑战-单词篇(第四天)
  • 6.1 操作系统的启动流程
  • 英语学习 第四天
  • Compose笔记(五十四)--Card