// 接口数据格式:
{
"code": 1000,
"msg": "成功",
"data": {
"list": [{
"citycode": "",
"adcode": "410000",
"name": "河南省",
"center": "113.753094,34.767052",
"level": "province",
"districts": [{
"citycode": "0379",
"adcode": "410300",
"name": "洛阳市",
"center": "112.453895,34.619702",
"level": "city",
"districts": [{
"citycode": "0379",
"adcode": "410323",
"name": "新安县",
"center": "112.13246,34.728909",
"level": "district",
"districts": []
}, {
"citycode": "0379",
"adcode": "410327",
"name": "宜阳县",
"center": "112.179187,34.51462",
"level": "district",
"districts": []
}, {
"citycode": "0379",
"adcode": "410328",
"name": "洛宁县",
"center": "111.652958,34.389371",
"level": "district",
"districts": []
}]
}, {
"citycode": "0398",
"adcode": "411200",
"name": "三门峡市",
"center": "111.200482,34.773196",
"level": "city",
"districts": [{
"citycode": "0398",
"adcode": "411202",
"name": "湖滨区",
"center": "111.188552,34.771296",
"level": "district",
"districts": []
}, {
"citycode": "0398",
"adcode": "411221",
"name": "渑池县",
"center": "111.761753,34.767937",
"level": "district",
"districts": []
}, {
"citycode": "0398",
"adcode": "411281",
"name": "义马市",
"center": "111.874726,34.747563",
"level": "district",
"districts": []
}]
}, {
"citycode": "0374",
"adcode": "411000",
"name": "许昌市",
"center": "113.852004,34.03732",
"level": "city",
"districts": [{
"citycode": "0374",
"adcode": "411003",
"name": "建安区",
"center": "113.822869,34.124729",
"level": "district",
"districts": []
}, {
"citycode": "0374",
"adcode": "411002",
"name": "魏都区",
"center": "113.830826,34.047189",
"level": "district",
"districts": []
}, {
"citycode": "0374",
"adcode": "411024",
"name": "鄢陵县",
"center": "114.177329,34.102985",
"level": "district",
"districts": []
}]
}]
}, {
"citycode": "",
"adcode": "440000",
"name": "广东省",
"center": "113.266887,23.133306",
"level": "province",
"districts": [{
"citycode": "0757",
"adcode": "440600",
"name": "佛山市",
"center": "113.121586,23.021351",
"level": "city",
"districts": [{
"citycode": "0757",
"adcode": "440608",
"name": "高明区",
"center": "112.892573,22.900047",
"level": "district",
"districts": []
}, {
"citycode": "0757",
"adcode": "440607",
"name": "三水区",
"center": "112.897271,23.156675",
"level": "district",
"districts": []
}, {
"citycode": "0757",
"adcode": "440605",
"name": "南海区",
"center": "113.143246,23.028875",
"level": "district",
"districts": []
}]
}, {
"citycode": "0758",
"adcode": "441200",
"name": "肇庆市",
"center": "112.465245,23.047747",
"level": "city",
"districts": [{
"citycode": "0758",
"adcode": "441225",
"name": "封开县",
"center": "111.512177,23.423928",
"level": "district",
"districts": []
}, {
"citycode": "0758",
"adcode": "441224",
"name": "怀集县",
"center": "112.166908,23.920806",
"level": "district",
"districts": []
}, {
"citycode": "0758",
"adcode": "441223",
"name": "广宁县",
"center": "112.440694,23.634808",
"level": "district",
"districts": []
}]
}]
},
}
}
在components 文件夹下新建cus-city-picker目录,新建cus-city-picker.vue页面
<template>
<view class="pupop">
<view class="popup-box" :animation="animationData">
<view class="pupop-btn">
<view @tap="onCancel">取消</view>
<view @tap="onConfirm" style="color: #2979ff;">确定</view>
</view>
<picker-view :value="value" :indicator-style="indicatorStyle" @change="onBindChange" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item,index) in provinceList" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in cityList" :key="index">{{item.name}}</view>
</picker-view-column>
<picker-view-column v-if="column == 3">
<view class="item" v-for="(item,index) in areaList" :key="index">{{item.name}}</view>
</picker-view-column>
</picker-view>
</view>
<view @tap="onClose" @touchmove.stop.prevent :class="visible ? 'pupop-model' : 'pupop-models'"></view>
</view>
</template>
<script>
export default {
data() {
return {
value: [],
provinceList: [],
cityList: [],
areaList: [],
indicatorStyle: `height: 50px;`,
provinceIndex: 0,
cityIndex: 0,
areaIndex: 0,
animationData: {}
}
},
props: {
addressList: {
type: Array,
default: []
},
column: {
type: Number,
default: 3
},
defaultValue: {
default: () => ''
},
visible: {
type: Boolean,
default: () => false
},
maskCloseAble: {
type: Boolean,
default: () => true
},
},
watch: {
addressList(val) {
this.init()
},
visible(val) {
this.onChangeActive()
},
},
methods: {
init() {
var provinceList = []
this.addressList.filter(item => {
provinceList.push({
adcode: item.adcode,
name: item.name
})
})
this.provinceList = [...provinceList]
if (!this.defaultValue) {
this.cityList = this.addressList[0].districts
this.areaList = this.addressList[0].districts[0].districts
} else {
if (Array.isArray(this.defaultValue) && this.defaultValue.length >= 2) {
var province = this.defaultValue[0]
var city = this.defaultValue[1]
this.provinceIndex = this.addressList.findIndex(obj => {
return obj.name == province
})
this.provinceIndex = this.provinceIndex >= 0 ? this.provinceIndex : 0;
this.cityList = this.addressList[this.provinceIndex].districts
this.cityIndex = this.cityList.findIndex(obj => {
return obj.name == city
})
this.cityIndex = this.cityIndex >= 0 ? this.cityIndex : 0;
this.areaList = this.cityList[this.cityIndex].districts
if (this.defaultValue.length > 2) {
this.areaIndex = this.areaList.findIndex(obj => {
return obj.name == this.defaultValue[2]
})
}
this.areaIndex = this.areaIndex >= 0 ? this.areaIndex : 0;
this.$nextTick(() => {
if (this.column == 3) {
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex, this
.areaIndex
]))
} else if (this.column == 2) {
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex]))
}
})
} else if (/^\d{6}$/.test(this.defaultValue)) {
var province = this.defaultValue.substr(0, 2)
var city = this.defaultValue.substr(0, 4);
this.provinceIndex = this.addressList.findIndex(obj => {
return obj.adcode == province
})
this.provinceIndex = this.provinceIndex >= 0 ? this.provinceIndex : 0;
this.cityList = this.addressList[this.provinceIndex].districts
this.cityIndex = this.cityList.findIndex(obj => {
return obj.adcode == city
})
this.cityIndex = this.cityIndex >= 0 ? this.cityIndex : 0;
this.areaList = this.cityList[this.cityIndex].districts
this.areaIndex = this.areaList.findIndex(obj => {
return obj.adcode == this.defaultValue
})
this.areaIndex = this.areaIndex >= 0 ? this.areaIndex : 0;
this.$nextTick(() => {
if (this.column == 3) {
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex, this
.areaIndex
]))
} else if (this.column == 2) {
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex]))
}
})
} else {
uni.showToast({
title: '地区编码格式不正确',
icon: 'none'
})
}
}
this.onChangeActive()
},
onConfirm() {
if (this.column == 3) {
this.$emit('confirm', {
adcode: this.addressList[this.provinceIndex].districts[this.cityIndex].districts[this
.areaIndex]
.adcode,
name: this.addressList[this.provinceIndex].name + this.addressList[this.provinceIndex]
.districts[this
.cityIndex].name + this.addressList[this.provinceIndex].districts[this.cityIndex]
.districts[this.areaIndex].name,
provinceName: this.addressList[this.provinceIndex].name,
cityName: this.addressList[this.provinceIndex].districts[this.cityIndex].name,
areaName: this.addressList[this.provinceIndex].districts[this.cityIndex].districts[this
.areaIndex].name
})
} else if (this.column == 2) {
this.$emit('confirm', {
adcode: this.addressList[this.provinceIndex].districts[this.cityIndex].districts[this
.areaIndex]
.adcode.substring(0, 4) + '00',
name: this.addressList[this.provinceIndex].name + this.addressList[this.provinceIndex]
.districts[this
.cityIndex].name,
provinceName: this.addressList[this.provinceIndex].name,
cityName: this.addressList[this.provinceIndex].districts[this.cityIndex].name
})
} else {
uni.showToast({
title: '目前column只能传2和3',
icon: 'none'
})
}
},
onCancel() {
this.$emit('cancel')
},
// 动画
onChangeActive() {
var active = '-315px'
if (this.visible) {
active = 0
}
var animation = uni.createAnimation({
duration: 400,
timingFunction: 'linear'
})
animation.bottom(active).step()
this.animationData = animation.export()
},
onBindChange(e) {
e.detail.value[0] = e.detail.value[0] || 0
e.detail.value[1] = e.detail.value[1] || 0
e.detail.value[2] = e.detail.value[2] || 0
if (e.detail.value[0] != this.provinceIndex) {
this.onProvinceChange(e.detail.value[0])
} else if (e.detail.value[1] != this.cityIndex) {
this.onCityChange(e.detail.value[1])
} else if (e.detail.value[2] != this.areaIndex) {
this.onAreaChange(e.detail.value[2])
}
},
// 监听第一列变化
onProvinceChange(e) {
this.provinceIndex = e
this.cityIndex = 0
this.areaIndex = 0
this.value = [...[e, 0, 0]]
this.cityList = this.addressList[e].districts
this.areaList = this.addressList[e].districts[0].districts
},
// 监听第二列变化
onCityChange(e) {
this.cityIndex = e
this.areaIndex = 0
this.value = [...[this.provinceIndex, e, 0]]
this.cityList = this.addressList[this.provinceIndex].districts
this.areaList = this.addressList[this.provinceIndex].districts[e].districts
},
// 监听第三列变化
onAreaChange(e) {
this.areaIndex = e
},
// 点击模态框
onClose() {
if (this.maskCloseAble) {
this.onCancel()
}
}
}
}
</script>
<style scoped lang="scss">
.pupop {
.popup-box {
position: fixed;
left: 0;
bottom: -315px;
z-index: 99999;
background: #fff;
padding-bottom: 50px;
.pupop-btn {
height: 40px;
display: flex;
align-items: center;
padding: 0 30upx;
justify-content: space-between;
}
}
.pupop-model {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9999;
background: rgba(0, 0, 0, .5);
}
.pupop-models {
display: none;
}
.picker-view {
width: 750rpx;
height: 225px;
margin-top: 20rpx;
}
.item {
height: 50px;
align-items: center;
justify-content: center;
text-align: center;
line-height: 50px;
}
}
</style>
在index.vue页面调用组件
<template>
<view class="w-100">
<view class="w-100 cus-flex-start-j">
<view style="width: 150rpx;font-size: 32rpx;font-weight: bold;">所在地区</view>
<view @click="onChooseCity">
<u-input v-model="district" border="none" placeholder="请选择" readonly customStyle="margin-top:0rpx;"
suffixIcon="arrow-down" suffixIconStyle="color: #D7D7D7"></u-input>
</view>
</view>
<!-- 选择所在地区 -->
<cityPicker :column="3" :default-value="cityInfo.defaultValue" :addressList='addressList'
:mask-close-able="true" :visible="cityInfo.visible" @confirm="onConfirmCity" @cancel="onCancelCity">
</cityPicker>
</view>
</template>
<script>
import api from "@/utils/api.js";
import cityPicker from '@/subpackages/components/cus-city-picker-http/cus-city-picker-http'
export default {
components: {
cityPicker
},
data() {
return {
addressList: [],
district: '', //地区:省,市,区(用,分割)
cityInfo: {
visible: false,
defaultValue: '',
},
}
},
created() {
this.getCitys();
},
methods: {
//获取城市列表
getCitys() {
api.getCitys({
data: {
type: 'district'
}
}).then(res => {
this.addressList = res.data.list
});
},
//选择城市
onChooseCity() {
this.cityInfo.visible = true
},
onConfirmCity(val) {
this.district = val.provinceName + ',' + val.cityName + ',' + val.areaName;
this.cityInfo.visible = false;
},
onCancelCity() {
this.cityInfo.visible = false;
if (this.district == '') {
console.log("请选择所在地区")
}
},
},
}
</script>