@tanzhenxing/zx-address
Version:
四级地址选择组件,支持自定义地址选择和已有地址选择两种模式。
331 lines (269 loc) • 7.36 kB
Markdown
# zx-address 四级地址选择
地址选择组件,支持自定义地址选择和已有地址选择两种模式。
## 平台兼容性
| H5 | App | 小程序 |
| :-: | :-: | :----: |
| √ | √ | √ |
## 引入
```javascript
import ZxAddress from '@tanzhenxing/zx-address/zx-address.vue';
```
## 代码演示
### 基础用法
```vue
<template>
<view>
<zx-button @click="showAddress = true">选择地址</zx-button>
<zx-address
v-model="showAddress"
:province="province"
:city="city"
:country="country"
:town="town"
custom-address-title="请选择所在地区"
@change="onChange"
@close="onClose"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
const showAddress = ref(false)
const province = ref([
{ id: 1, name: '北京' },
{ id: 2, name: '广西' },
{ id: 3, name: '江西' },
{ id: 4, name: '四川' }
])
const city = ref([
{ id: 7, name: '朝阳区' },
{ id: 8, name: '崇文区' },
{ id: 9, name: '昌平区' },
{ id: 6, name: '石景山区' }
])
const country = ref([
{ id: 3, name: '八里庄街道' },
{ id: 9, name: '北苑' },
{ id: 4, name: '常营乡' }
])
const town = ref([])
const onChange = (data) => {
console.log('地址改变:', data)
// 根据选择的层级动态加载下一级数据
if (data.next && data.next.length > 0) {
// 可以在这里请求下一级数据
} else {
// 选择完成,关闭弹窗
showAddress.value = false
}
}
const onClose = (data) => {
console.log('关闭弹窗:', data)
if (data.type === 'custom') {
console.log('选择的地址:', data.data.addressStr)
}
}
</script>
```
### 选择已有地址
```vue
<template>
<view>
<zx-button @click="showExistAddress = true">选择已有地址</zx-button>
<zx-address
v-model="showExistAddress"
type="exist"
:exist-address="existAddress"
exist-address-title="配送至"
:is-show-custom-address="false"
@selected="onSelected"
@close="onClose"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
const showExistAddress = ref(false)
const existAddress = ref([
{
id: 1,
name: '张三',
tel: '13800138000',
addressDetail: 'xx小区xx号楼xx单元xx室',
cityName: '石景山区',
countyName: '城区',
provinceName: '北京',
townName: '',
selectedAddress: true
},
{
id: 2,
name: '李四',
tel: '13900139000',
addressDetail: 'yy大厦yy层yy室',
cityName: '朝阳区',
countyName: '建外街道',
provinceName: '北京',
townName: '',
selectedAddress: false
}
])
const onSelected = (item, index, list) => {
console.log('选中地址:', item)
console.log('地址索引:', index)
console.log('地址列表:', list)
}
const onClose = (data) => {
console.log('关闭弹窗:', data)
}
</script>
```
### 自定义图标
```vue
<template>
<zx-address
v-model="showAddress"
type="exist"
:exist-address="existAddress"
:default-icon="defaultIcon"
:selected-icon="selectedIcon"
@selected="onSelected"
/>
</template>
<script setup>
import { ref } from 'vue'
const showAddress = ref(false)
const defaultIcon = ref('circle')
const selectedIcon = ref('success')
const existAddress = ref([
// ... 地址数据
])
const onSelected = (item, index, list) => {
console.log('选中地址:', item)
}
</script>
```
### 自定义地址与已有地址切换
```vue
<template>
<zx-address
v-model="showAddress"
type="all"
:province="province"
:city="city"
:country="country"
:town="town"
:exist-address="existAddress"
:show-tabs="true"
@change="onChange"
@selected="onSelected"
@close="onClose"
/>
</template>
<script setup>
import { ref } from 'vue'
const showAddress = ref(false)
// 省市区数据
const province = ref([...])
const city = ref([...])
const country = ref([...])
const town = ref([])
// 已有地址数据
const existAddress = ref([...])
const onChange = (data) => {
// 处理自定义地址选择
}
const onSelected = (item, index, list) => {
// 处理已有地址选择
}
const onClose = (data) => {
// 处理关闭事件
}
</script>
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
|--|--|--|--|
| v-model | 控制弹窗显示隐藏 | `Boolean` | `false` |
| title | 弹窗标题 | `String` | `选择地址` |
| show-tabs | 是否显示标签栏 | `Boolean` | `true` |
| custom-address-title | 自定义地址标题 | `String` | `请选择所在地区` |
| exist-address-title | 已有地址标题 | `String` | `配送至` |
| province | 省份数据 | `Array` | `[]` |
| city | 城市数据 | `Array` | `[]` |
| country | 区县数据 | `Array` | `[]` |
| town | 乡镇数据 | `Array` | `[]` |
| exist-address | 已有地址列表 | `Array` | `[]` |
| is-show-custom-address | 是否显示自定义地址 | `Boolean` | `true` |
| close-on-click-overlay | 点击遮罩是否关闭 | `Boolean` | `true` |
| default-icon | 默认选中的图标 | `String` | `''` |
| selected-icon | 选中状态的图标 | `String` | `''` |
| type | 组件类型 | `String` | `all` |
### type 可选值
| 值 | 说明 |
|--|--|
| all | 显示自定义地址和已有地址两个标签页 |
| exist | 只显示已有地址 |
| custom | 只显示自定义地址 |
### Events
| 事件名 | 说明 | 回调参数 |
|--|--|--|
| change | 自定义地址选择改变时触发 | `data: { next: string, value: Array, selectedData: Object }` |
| close | 弹窗关闭时触发 | `data: { type: string, data: Object }` |
| selected | 选中已有地址时触发 | `item: Object, index: Number, list: Array` |
### 数据结构
#### 省市区数据格式
```javascript
[
{
id: 1, // 唯一标识
name: '北京' // 显示名称
}
]
```
#### 已有地址数据格式
```javascript
[
{
id: 1, // 唯一标识
name: '张三', // 姓名
tel: '13800138000', // 电话
provinceName: '北京', // 省份名称
cityName: '朝阳区', // 城市名称
countyName: '建外街道', // 区县名称
townName: '', // 乡镇名称
addressDetail: 'xx小区xx号楼', // 详细地址
selectedAddress: true // 是否选中
}
]
```
### change 事件回调参数
| 参数 | 说明 | 类型 |
|--|--|--|
| next | 下一级数据类型 | `String` |
| value | 当前选中的值数组 | `Array` |
| selectedData | 当前选中的数据对象 | `Object` |
#### next 可能的值
| 值 | 说明 |
|--|--|
| city | 需要加载城市数据 |
| country | 需要加载区县数据 |
| town | 需要加载乡镇数据 |
| '' | 选择完成 |
### close 事件回调参数
| 参数 | 说明 | 类型 |
|--|--|--|
| type | 关闭时的类型 | `String` |
| data | 相关数据 | `Object` |
#### type 可能的值
| 值 | 说明 |
|--|--|
| custom | 自定义地址选择 |
| exist | 已有地址选择 |
## 注意事项
1. 省市区数据需要按照指定格式提供,包含 `id` 和 `name` 字段
2. 已有地址数据需要包含完整的地址信息字段
3. 组件内部会根据 `change` 事件的 `next` 参数来判断是否需要加载下一级数据
4. 当 `next` 为空字符串时,表示选择完成,建议关闭弹窗
5. 组件支持 H5、小程序、App 三端,使用了 uni-app 的跨平台特性