You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
5.6 KiB
253 lines
5.6 KiB
2 months ago
|
# 省市区选择组件使用说明
|
||
|
|
||
|
## 概述
|
||
|
|
||
|
`AreaPicker.vue` 是一个功能完整的省市区三级联动选择组件,支持自定义样式插槽,可以灵活地集成到各种页面中。
|
||
|
|
||
|
## 功能特性
|
||
|
|
||
|
- ✅ 省市区三级联动选择
|
||
|
- ✅ 支持默认值设置
|
||
|
- ✅ 支持插槽自定义显示样式
|
||
|
- ✅ 完整的事件回调
|
||
|
- ✅ 灵活的数据请求方式
|
||
|
- ✅ 错误处理和容错机制
|
||
|
|
||
|
## Props
|
||
|
|
||
|
| 参数 | 类型 | 默认值 | 说明 |
|
||
|
|------|------|--------|------|
|
||
|
| placeholder | String | '请选择' | 占位符文本 |
|
||
|
| defaultValue | Object | null | 默认选中值,格式:`{ provinceId, cityId, areaId }` |
|
||
|
| disabled | Boolean | false | 是否禁用 |
|
||
|
|
||
|
## Events
|
||
|
|
||
|
| 事件名 | 参数 | 说明 |
|
||
|
|--------|------|------|
|
||
|
| change | data | 选择改变时触发,返回选中的省市区信息 |
|
||
|
|
||
|
### change 事件返回数据格式
|
||
|
|
||
|
```javascript
|
||
|
{
|
||
|
provinceId: '110000', // 省份ID
|
||
|
cityId: '110100', // 城市ID
|
||
|
areaId: '110101', // 区域ID
|
||
|
fullText: '北京市北京市东城区' // 完整地址文本
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Methods
|
||
|
|
||
|
| 方法名 | 参数 | 返回值 | 说明 |
|
||
|
|--------|------|--------|------|
|
||
|
| getValue | - | Object | 获取当前选中的值 |
|
||
|
| reset | - | - | 重置选择 |
|
||
|
|
||
|
## 插槽使用
|
||
|
|
||
|
组件提供了默认插槽,允许完全自定义显示样式。插槽提供以下数据:
|
||
|
|
||
|
| 插槽参数 | 类型 | 说明 |
|
||
|
|----------|------|------|
|
||
|
| selectedText | String | 当前选中的完整文本 |
|
||
|
| placeholder | String | 占位符文本 |
|
||
|
| provinceData | Array | 省份数据列表 |
|
||
|
| cityData | Array | 城市数据列表 |
|
||
|
| areaData | Array | 区域数据列表 |
|
||
|
| multiIndex | Array | 当前选中的索引数组 |
|
||
|
| currentSelection | Object | 当前选中的详细信息 |
|
||
|
|
||
|
### currentSelection 对象结构
|
||
|
|
||
|
```javascript
|
||
|
{
|
||
|
province: { id: '110000', name: '北京市' },
|
||
|
city: { id: '110100', name: '北京市' },
|
||
|
area: { id: '110101', name: '东城区' },
|
||
|
fullText: '北京市北京市东城区'
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## 使用示例
|
||
|
|
||
|
### 基本使用
|
||
|
|
||
|
```vue
|
||
|
<template>
|
||
|
<view>
|
||
|
<!-- 使用默认样式 -->
|
||
|
<AreaPicker
|
||
|
ref="areaPicker"
|
||
|
placeholder="请选择省市区"
|
||
|
:defaultValue="{ provinceId: '110000', cityId: '110100', areaId: '110101' }"
|
||
|
@change="onAreaChange"
|
||
|
/>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
export default {
|
||
|
methods: {
|
||
|
onAreaChange(data) {
|
||
|
console.log('选中的地区:', data)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
### 自定义样式(插槽)
|
||
|
|
||
|
```vue
|
||
|
<template>
|
||
|
<view>
|
||
|
<!-- 自定义样式1:简单自定义 -->
|
||
|
<AreaPicker
|
||
|
placeholder="请选择省市区"
|
||
|
@change="onAreaChange"
|
||
|
>
|
||
|
<template v-slot="{ selectedText, placeholder }">
|
||
|
<view class="custom-display">
|
||
|
<text class="icon">📍</text>
|
||
|
<text class="text">{{ selectedText || placeholder }}</text>
|
||
|
<text class="arrow">▼</text>
|
||
|
</view>
|
||
|
</template>
|
||
|
</AreaPicker>
|
||
|
|
||
|
<!-- 自定义样式2:显示详细信息 -->
|
||
|
<AreaPicker
|
||
|
placeholder="请选择省市区"
|
||
|
@change="onAreaChange"
|
||
|
>
|
||
|
<template v-slot="{ selectedText, placeholder, currentSelection }">
|
||
|
<view class="detail-display">
|
||
|
<view v-if="currentSelection.province" class="detail-info">
|
||
|
<text>省:{{ currentSelection.province.name }}</text>
|
||
|
<text>市:{{ currentSelection.city.name }}</text>
|
||
|
<text>区:{{ currentSelection.area.name }}</text>
|
||
|
</view>
|
||
|
<text v-else class="placeholder">{{ placeholder }}</text>
|
||
|
</view>
|
||
|
</template>
|
||
|
</AreaPicker>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
export default {
|
||
|
methods: {
|
||
|
onAreaChange(data) {
|
||
|
console.log('选中的地区:', data)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
<style>
|
||
|
.custom-display {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
padding: 12px 16px;
|
||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
|
border-radius: 25px;
|
||
|
color: white;
|
||
|
}
|
||
|
|
||
|
.icon {
|
||
|
margin-right: 10px;
|
||
|
}
|
||
|
|
||
|
.text {
|
||
|
flex: 1;
|
||
|
}
|
||
|
|
||
|
.arrow {
|
||
|
margin-left: 10px;
|
||
|
}
|
||
|
|
||
|
.detail-display {
|
||
|
padding: 15px;
|
||
|
background-color: #f8f9fa;
|
||
|
border: 2px dashed #dee2e6;
|
||
|
border-radius: 8px;
|
||
|
}
|
||
|
|
||
|
.detail-info {
|
||
|
display: flex;
|
||
|
flex-direction: column;
|
||
|
gap: 5px;
|
||
|
}
|
||
|
|
||
|
.placeholder {
|
||
|
color: #adb5bd;
|
||
|
font-style: italic;
|
||
|
}
|
||
|
</style>
|
||
|
```
|
||
|
|
||
|
### 在 header 组件中使用
|
||
|
|
||
|
```vue
|
||
|
<template>
|
||
|
<view>
|
||
|
<header
|
||
|
:isSearch="true"
|
||
|
:isAreaPicker="true"
|
||
|
areaPlaceholder="请选择省市区"
|
||
|
:defaultAreaValue="{ provinceId: '110000', cityId: '110100', areaId: '110101' }"
|
||
|
@areaChange="onAreaChange"
|
||
|
/>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
export default {
|
||
|
methods: {
|
||
|
onAreaChange(data) {
|
||
|
console.log('选中的地区:', data)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
## 数据接口要求
|
||
|
|
||
|
组件需要后端提供省市区数据接口,接口返回格式如下:
|
||
|
|
||
|
```javascript
|
||
|
// 省份数据
|
||
|
[
|
||
|
{ id: '110000', name: '北京市' },
|
||
|
{ id: '120000', name: '天津市' },
|
||
|
// ...
|
||
|
]
|
||
|
|
||
|
// 城市数据(根据省份ID获取)
|
||
|
[
|
||
|
{ id: '110100', name: '北京市', pid: '110000' },
|
||
|
// ...
|
||
|
]
|
||
|
|
||
|
// 区域数据(根据城市ID获取)
|
||
|
[
|
||
|
{ id: '110101', name: '东城区', pid: '110100' },
|
||
|
{ id: '110102', name: '西城区', pid: '110100' },
|
||
|
// ...
|
||
|
]
|
||
|
```
|
||
|
|
||
|
## 注意事项
|
||
|
|
||
|
1. 组件会自动处理数据请求的多种方式(父组件 Post 方法、全局 Post 方法、uni.request)
|
||
|
2. 建议在使用前确保数据接口正常可用
|
||
|
3. 插槽内容会完全替换默认的显示样式
|
||
|
4. 可以通过 ref 调用组件的 getValue() 和 reset() 方法
|
||
|
5. 组件支持设置默认值,会自动回显对应的省市区信息
|
||
|
|
||
|
## 完整示例
|
||
|
|
||
|
查看 `AreaPickerSlotExample.vue` 文件获取完整的使用示例,包含多种自定义样式的演示。
|