从gitee仓库可以拿到demo 以及 json省市区 文件
// 这是组件部分
<template>
<uni-popup ref="popup" type="bottom">
<view class="popup">
<view class="picker-btn">
<view class="left" @click="cancel">取消</view>
<view class="right" @click="confirm">确定</view>
</view>
<picker-view
:indicator-style="indicatorStyle"
:value="valueArr"
@change="bindChange"
>
<picker-view-column>
<view
class="item"
v-for="(item, index) in province[0]"
:key="index"
>{{ item.name }}</view
>
</picker-view-column>
<picker-view-column v-if="province[1]">
<view
class="item"
v-for="(item, index) in province[1]"
:key="index"
>{{ item.name }}</view
>
</picker-view-column>
<picker-view-column v-if="province[2]">
<view
class="item"
v-for="(item, index) in province[2]"
:key="index"
>{{ item.name }}</view
>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
</template>
<script>
import provinces from "./provinces.json";
import cities from "./cities.json";
import areas from "./areas.json";
export default {
props: {
value: {
type: String,
default: "",
},
twoStage: {
type: Boolean,
default: false,
},
},
name: "ZlAddress",
data() {
return {
indicatorStyle: `height: ${Math.round(
uni.getSystemInfoSync().screenWidth / (750 / 100)
)}px;`,
valueArr: [0, 0, 0], // 用于判断当前滑动的是哪一列
province: [provinces], // 数据列表
};
},
methods: {
setIndex(i, value) {
this.$set(this.valueArr, i, value);
},
initLoadArea() {
this.loadCity(provinces[0].code);
},
loadCity(code) {
let children = cities.filter((v) => v.provinceCode == code);
this.$set(this.province, 1, children);
if (!this.twoStage) {
this.loadArea(children[this.valueArr[1]]?.code || children[0].code);
}
},
loadArea(code) {
this.$set(
this.province,
2,
areas.filter((v) => v.cityCode == code)
);
},
bindChange(e) {
const val = e.detail.value;
if (this.valueArr[0] !== val[0]) {
let code = provinces[val[0]].code;
this.loadCity(code);
} else if (this.valueArr[1] !== val[1]) {
if (!this.twoStage) {
let code = this.province[1][val[1]].code;
this.loadArea(code);
}
}
this.valueArr = val;
},
confirm() {
let addressDetail = "";
if (!this.twoStage) {
addressDetail = `${this.province[0][this.valueArr[0]].name}-${
this.province[1][this.valueArr[1]].name
}-${this.province[2][this.valueArr[2]]?.name}`;
} else {
addressDetail = `${this.province[0][this.valueArr[0]].name}-${
this.province[1][this.valueArr[1]].name
}`;
}
this.$emit("confirm", addressDetail);
},
open() {
this.$refs.popup.open();
if (!this.value) {
this.initLoadArea();
} else {
this.$nextTick(() => {
this.echoLoad();
});
}
},
echoLoad() {
let val = this.value.split("-");
let sheng = provinces.findIndex((v) => v.name == val[0]);
let shengcode = provinces.find((v) => v.name == val[0])?.code;
this.setIndex(0, sheng);
let children = cities.filter((v) => v.provinceCode == shengcode);
this.$set(this.province, 1, children);
let shi = this.province[1].findIndex((v) => v.name == val[1]);
let shicode = this.province[1].find((v) => v.name == val[1])?.code;
this.setIndex(1, shi);
if (!this.twoStage) {
let children2 = areas.filter((v) => v.cityCode == shicode);
this.$set(this.province, 2, children2);
let qu = this.province[2].findIndex((v) => v.name == val[2]);
this.setIndex(2, qu);
}
},
cancel() {
this.$refs.popup.close();
},
},
};
</script>
<style lang="scss" scoped>
.popup {
height: fit-content;
width: 100%;
background: #fff;
}
.picker-btn {
display: flex;
height: 100rpx;
width: 100%;
line-height: 100rpx;
background: #fff;
font-size: 34rpx;
z-index: 1;
border-bottom: 1rpx solid #f8f8f8;
.left {
flex: 1;
color: #0076ff;
padding-left: 40rpx;
box-sizing: border-box;
}
.right {
flex: 1;
text-align: right;
padding-right: 40rpx;
color: #fe4533;
box-sizing: border-box;
}
}
picker-view {
width: 100%;
height: 500rpx;
display: relative;
}
.item {
line-height: 100rpx;
text-align: center;
}
</style>
// 这是 使用部分
<template>
<view class="content">
<div @click="changeAddress">
{{ address ? address : "请选择省市区" }}
</div>
<Address :value="address" @confirm="confirmAddress" ref="address"></Address>
<div @click="changeAddress2">
{{ address2 ? address2 : "请选择省市" }}
</div>
<Address
:value="address2"
@confirm="confirmAddress2"
ref="address2"
two-stage
></Address>
</view>
</template>
<script>
import Address from "@/components/address.vue";
export default {
data() {
return {
address: "",
address2: "",
};
},
components: {
Address,
},
onLoad() {},
methods: {
changeAddress() {
this.$refs.address.open();
},
changeAddress2() {
this.$refs.address2.open();
},
confirmAddress(val) {
console.log(val, "eee");
this.address = val;
this.$refs.address.cancel();
},
confirmAddress2(val) {
console.log(val, "eee");
this.address2 = val;
this.$refs.address2.cancel();
},
},
};
</script>
<style>
.content {
display: flex;
flex-direction: column;
gap: 40rpx;
padding: 40rpx;
}
</style>