Files
ks-app-employment-service/components/area-cascade-picker/README.md
2025-11-10 15:27:34 +08:00

336 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 五级联动地址选择器组件
## 组件简介
`area-cascade-picker` 是一个支持省市区县街道社区的五级联动地址选择组件,适用于需要选择详细地址的场景。
## 功能特点
- ✅ 五级联动选择(省/市/区/街道/社区)
- ✅ 自动级联更新
- ✅ 支持取消和确认操作
- ✅ 底部弹出式交互
- ✅ 支持自定义标题
- ✅ 返回完整的地址信息和各级代码
## 使用方法
### 1. 引入组件
```vue
<template>
<view>
<button @click="openPicker">选择地址</button>
<area-cascade-picker ref="areaPicker"></area-cascade-picker>
</view>
</template>
<script setup>
import { ref } from 'vue'
import AreaCascadePicker from '@/components/area-cascade-picker/area-cascade-picker.vue'
const areaPicker = ref(null)
</script>
```
### 2. 打开选择器
```javascript
const openPicker = () => {
areaPicker.value?.open({
title: '选择地址',
maskClick: true,
success: (addressData) => {
console.log('选择的地址:', addressData)
// 处理选择结果
},
cancel: () => {
console.log('取消选择')
},
change: (addressData) => {
console.log('地址变化:', addressData)
}
})
}
```
## API 说明
### open(config)
打开地址选择器
#### 参数 config
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| title | String | 否 | '选择地址' | 选择器标题 |
| maskClick | Boolean | 否 | false | 是否允许点击遮罩关闭 |
| success | Function | 否 | - | 确认选择的回调函数 |
| cancel | Function | 否 | - | 取消选择的回调函数 |
| change | Function | 否 | - | 选择变化的回调函数 |
| defaultValue | Object | 否 | null | 默认选中的地址(暂未实现) |
| forceRefresh | Boolean | 否 | false | 是否强制刷新数据(忽略缓存) |
#### success 回调参数
```javascript
{
address: "新疆维吾尔自治区/喀什地区/喀什市/学府街道/学府社区居委会",
province: {
code: "650000",
name: "新疆维吾尔自治区"
},
city: {
code: "653100",
name: "喀什地区"
},
district: {
code: "653101",
name: "喀什市"
},
street: {
code: "65310101",
name: "学府街道"
},
community: {
code: "6531010101",
name: "学府社区居委会"
}
}
```
### close()
关闭地址选择器
```javascript
areaPicker.value?.close()
```
### clearCache()
清除地址数据缓存
```javascript
areaPicker.value?.clearCache()
```
## 数据格式
组件使用树形结构的地址数据,格式如下:
```javascript
[
{
code: '650000', // 行政区划代码
name: '新疆维吾尔自治区', // 名称
children: [ // 下级行政区
{
code: '653100',
name: '喀什地区',
children: [
{
code: '653101',
name: '喀什市',
children: [
{
code: '65310101',
name: '学府街道',
children: [
{
code: '6531010101',
name: '学府社区居委会'
}
]
}
]
}
]
}
]
}
]
```
## 完整示例
### 企业注册地址选择
```vue
<template>
<view class="form-item" @click="selectLocation">
<text class="label">企业注册地点</text>
<view class="input-content">
<text :class="{ placeholder: !formData.address }">
{{ formData.address || '请选择注册地点' }}
</text>
<uni-icons type="arrowright" size="16"></uni-icons>
</view>
</view>
<area-cascade-picker ref="areaPicker"></area-cascade-picker>
</template>
<script setup>
import { ref, reactive } from 'vue'
import AreaCascadePicker from '@/components/area-cascade-picker/area-cascade-picker.vue'
const areaPicker = ref(null)
const formData = reactive({
address: '',
provinceCode: '',
provinceName: '',
cityCode: '',
cityName: '',
districtCode: '',
districtName: '',
streetCode: '',
streetName: '',
communityCode: '',
communityName: ''
})
const selectLocation = () => {
areaPicker.value?.open({
title: '选择企业注册地点',
maskClick: true,
success: (addressData) => {
// 保存完整地址
formData.address = addressData.address
// 保存各级信息
formData.provinceCode = addressData.province?.code
formData.provinceName = addressData.province?.name
formData.cityCode = addressData.city?.code
formData.cityName = addressData.city?.name
formData.districtCode = addressData.district?.code
formData.districtName = addressData.district?.name
formData.streetCode = addressData.street?.code
formData.streetName = addressData.street?.name
formData.communityCode = addressData.community?.code
formData.communityName = addressData.community?.name
console.log('已选择地址:', formData)
}
})
}
</script>
```
## 性能优化
### 懒加载方案(已实现)⭐
组件已实现**懒加载**机制大幅优化90M+地址数据的加载性能:
#### 核心优化
1. **首次加载**:只加载省份列表(< 1MB3-5秒完成
2. **按需加载**用户选择省份后再加载该省份的详细数据2-5MB5-10秒
3. **智能缓存**已加载的数据会缓存切换省份时秒开
4. **自动降级**如果服务器不支持分片接口自动从完整数据中提取
#### 性能对比
| 场景 | 优化前 | 优化后懒加载 |
|------|--------|------------------|
| 首次打开选择器 | 加载90M+3-5分钟 | 加载省份列表< 1MB3-5秒 |
| 选择省份 | 无需加载 | 加载该省份数据2-5MB5-10秒 |
| 切换省份 | 无需加载 | 从缓存读取< 1秒 |
#### 使用方式
组件已自动使用懒加载模式无需修改调用代码
```javascript
// 正常使用,自动懒加载
areaPicker.value?.open({
success: (addressData) => {
console.log('选择的地址:', addressData)
}
})
// 强制刷新数据(忽略缓存)
areaPicker.value?.open({
forceRefresh: true, // 强制从服务器重新加载
success: (addressData) => {
console.log('选择的地址:', addressData)
}
})
// 清除缓存
areaPicker.value?.clearCache()
```
### 服务器分片接口(最佳方案)🚀
如果服务器可以提供分片接口性能会进一步提升详见[地址数据懒加载优化方案.md](../../docs/地址数据懒加载优化方案.md)
需要的接口
- 省份列表接口`/address_provinces.json`轻量级< 1MB
- 省份详情接口`/address_province_{code}.json`按需加载每个2-5MB
### 缓存机制
1. **自动缓存**已加载的数据会自动缓存到 IndexedDBH5 uni.storage小程序
2. **缓存有效期**默认7天过期后自动重新加载
3. **离线支持**网络失败时自动使用缓存数据
4. **存储方案**优先使用 IndexedDB自动降级到 uni.storage
## 注意事项
1. **数据来源**当前从远程JSON文件加载生产环境建议接入后端API
2. **数据更新**如需接入后端API修改 `loadAreaData` 方法即可
3. **性能优化**已集成缓存机制首次加载后速度大幅提升
4. **兼容性**支持 H5微信小程序等多端
5. **存储限制**小程序环境有存储限制如遇问题会自动清理旧缓存
## 接入后端API
在组件的 `loadAreaData` 方法中取消注释并配置API
```javascript
async loadAreaData() {
try {
const resp = await uni.request({
url: '/app/common/area/cascade',
method: 'GET'
});
if (resp.statusCode === 200 && resp.data && resp.data.data) {
this.areaData = resp.data.data;
return;
}
} catch (error) {
console.error('加载地区数据失败:', error);
}
// 失败时使用模拟数据
this.areaData = this.getMockData();
}
```
## 更新日志
### v1.2.0 (2025-01-XX)
- 🚀 **懒加载优化**实现按需加载首次加载从几分钟减少到几秒
- 首次只加载省份列表< 1MB3-5秒
- 按需加载省份详情选择省份时才加载
- 智能缓存已加载的数据切换省份秒开
- 支持服务器分片接口最佳性能
- 自动降级方案兼容完整数据
### v1.1.0 (2025-01-XX)
- 🚀 **性能优化**集成智能缓存系统优化90M+地址数据加载
- 支持 IndexedDB uni.storage 双缓存方案
- 支持缓存过期管理和自动清理
- 支持强制刷新数据
- 优化首次加载体验后续加载秒开
### v1.0.0 (2025-10-21)
- 初始版本
- 实现五级联动选择功能
- 支持省市区县街道社区选择
- 提供完整的地址信息返回