123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- <template>
- <view class="picker-address">
- <uni-popup ref="popRef">
- <view class="picker-address-content">
- <view class="picker-address-top">
- <view class="picker-address-action cancel" @click="onCancel">取消</view>
- <view class="picker-address-action confirm" @click="onConfirm">确定</view>
- </view>
- <picker-view indicator-class='is-selected' :value="areaIndex" @change="onAreaChange">
- <picker-view-column>
- <view class="addr-item" :class="areaIndex[0] == index ?'selected':''"
- v-for="(item, index) in areaList[0]" :key="index">
- {{ item.name }}
- </view>
- </picker-view-column>
- <picker-view-column>
- <view class="addr-item" :class="areaIndex[1] == index ?'selected':''"
- v-for="(item, index) in areaList[1]" :key="index">
- {{ item.name }}
- </view>
- </picker-view-column>
- <picker-view-column>
- <view class="addr-item" :class="areaIndex[2] == index ?'selected':''"
- v-for="(item, index) in areaList[2]" :key="index">
- {{ item.name }}
- </view>
- </picker-view-column>
- </picker-view>
- </view>
- </uni-popup>
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, onMounted, computed, watch } from 'vue'
- import dataTree from "@/static/json/pca-code.json"
-
- const emits = defineEmits(['change'])
- const props = defineProps({
- province: {
- type: String,
- default: ""
- },
- city: {
- type: String,
- default: ""
- },
- area: {
- type: String,
- default: ""
- },
- })
-
- watch(
- () => props.province,
- () => {
- if (props.province){
- updateAreaIndex(props.province,props.city,props.area)
- }
- }
- )
-
- const popRef = ref()
- const areaList = ref([[], [], []])//todo类型
- const areaIndex = ref([0, 0, 0])
-
- const provinceName = computed(() => {
- return areaList.value[0][areaIndex.value[0]] ? areaList.value[0][areaIndex.value[0]]["name"] : '省';
- })
- const cityName = computed(() => {
- return areaList.value[1][areaIndex.value[1]] ? areaList.value[1][areaIndex.value[1]]["name"] : '市';
- })
- const areaName = computed(() => {
- return areaList.value[2][areaIndex.value[2]] ? areaList.value[2][areaIndex.value[2]]["name"] : '区';
- })
- const onCancel = ()=> {
- popRef.value.close()
- }
- const onConfirm = async()=> {
- const data = {
- province:provinceName.value,
- city:cityName.value,
- area:areaName.value,
- }
- emits('change',data);
- onCancel()
- }
- const onAreaChange = async (e) => {
- const originalIndex = [...areaIndex.value];
- console.log("原来", areaIndex.value)
- areaIndex.value = e.detail.value
- console.log("现在", areaIndex.value)
-
- if (originalIndex[0] !== areaIndex.value[0]) {
- areaIndex.value[1] = 0
- areaIndex.value[2] = 0
- await initArea();
- } else if (originalIndex[1] !== areaIndex.value[1]) {
- areaIndex.value[2] = 0
- await getCity();
- }
- }
- const openPop = () => {
- popRef.value.open('bottom')
- }
-
- // 获取所有省
- const getProvinces = (data) => {
- return data.map(province => ({
- id: province.code,
- name: province.name ,
- }));
- };
-
- // 匹配省里面的所有市
- const getCitiesByProvinceIndex = (data, index) => {
- if (data[index] && data[index].children) {
- return data[index].children.map(city => ({
- id: city.code,
- name: city.name
- }));
- }
- return [];
- };
- // 匹配省里面的市的区
- const getAreasByCityIndex = (data, provinceIndex, cityIndex) => {
- if (data[provinceIndex] && data[provinceIndex].children &&
- data[provinceIndex].children[cityIndex] && data[provinceIndex].children[cityIndex].children) {
- return data[provinceIndex].children[cityIndex].children.map(area => ({
- id: area.code,
- name: area.name
- }));
- }
- return [];
- };
- //初始化地址选择器
- const initArea = async () => {
- //获取省
- let result = getProvinces(dataTree)
- console.log("省",result)
- if (result == null) {
- console.log("获取省出错");
- return false;
- } else {
- areaList.value.splice(0, 1, result);
- await getCity();
- }
- }
- //获取市
- const getCity = async () => {
- let pid = areaIndex.value[0];
- let result = getCitiesByProvinceIndex(dataTree, pid)
- console.log("对应市",result)
- if (result == null) {
- console.log("获取市出错");
- return false;
- } else {
- areaList.value.splice(1, 1, result);
- await getArea();
- }
- }
- //获取区
- const getArea = async () => {
- let pid = areaIndex.value[0];
- let cid = areaIndex.value[1];
- let result = getAreasByCityIndex(dataTree,pid,cid)
- console.log("对应区",result)
- if (result == null) {
- console.log("获取区出错");
- return false;
- } else {
- areaList.value.splice(2, 1, result);
- }
- }
-
-
- const findIndexes = (dataTree, provinceName, cityName, areaName) => {
- let provinceIndex = 0;
- let cityIndex = 0;
- let areaIndex = 0;
-
- dataTree.some((province, pIndex) => {
- if (province.name === provinceName) {
- provinceIndex = pIndex;
- return province.children.some((city, cIndex) => {
- if (city.name === cityName) {
- cityIndex = cIndex;
- return city.children.some((area, aIndex) => {
- if (area.name === areaName) {
- areaIndex = aIndex;
- return true;
- }
- return false;
- });
- }
- return false;
- });
- }
- return false;
- });
-
- return [provinceIndex, cityIndex, areaIndex];
- }
-
- const updateAreaIndex = (provinceName, cityName, areaName) => {
- const indexes = findIndexes(dataTree, provinceName, cityName, areaName);
- areaIndex.value = indexes;
- }
-
- onMounted(async () => {
- if (props.province){
- updateAreaIndex(props.province,props.city,props.area)
- }
- await initArea();
- // getInfo()
- })
- defineExpose({ openPop })
- </script>
- <style lang="scss" scoped>
- .picker-address {
- .picker-address-content {
- background-color: #fff;
- border-radius: 16rpx 16rpx 0 0;
- .picker-address-top {
- height: 96rpx;
- @include flex-between;
- border-bottom: 1px solid $uni-border-color;
- .picker-address-action {
- font-size: $uni-font-size-xl;
- line-height: $uni-line-height-xl;
- @include flex;
- padding: 0 32rpx;
- &.cancel {
- color: $uni-text-color !important;
- }
- &.confirm {
- color: $uni-color-primary;
- }
- }
- }
- .addr-item {
- height: 96rpx !important;
- font-size: $uni-font-size-xl;
- line-height: $uni-line-height-xl;
- @include flex-center;
- &.selected {
- font-size: $uni-font-size-xxl;
- line-height: $uni-line-height-xxl;
- }
- }
- }
- :deep(uni-picker-view) {
- margin-top: 24rpx;
- }
- :deep(.is-selected) {
- height: 96rpx !important;
- color: $uni-text-color;
- font-size: $uni-font-size-xxl;
- line-height: $uni-line-height-xxl;
- }
- :deep(.uni-picker-view-wrapper) {
- overflow: visible;
- uni-picker-view-column {
- overflow: visible;
- &:first-child {
- .is-selected {
- &::before,
- &::after {
- left: -32rpx;
- }
- }
- }
- &:last-child {
- .is-selected {
- &::before,
- &::after {
- right: -32rpx;
- }
- }
- }
- }
- }
- :deep(.uni-picker-view-indicator:before) {
- border-top-color: $uni-border-color;
- }
- :deep(.uni-picker-view-indicator:after) {
- border-bottom-color: $uni-border-color;
- }
- }
- picker-view {
- width: 100%;
- height: 600rpx;
- padding: 0 32rpx;
- box-sizing: border-box;
- overflow: hidden;
- }
- </style>
|