jiuyiUniapp/jiuyi2/components/public/regionSelection/regionSelection.vue

231 lines
5.1 KiB
Vue
Raw Normal View History

2025-01-10 10:51:21 +08:00
<script setup>
import {
ref,
getCurrentInstance,
reactive,
computed,
defineEmits,
defineExpose,
} from 'vue'
// 工具
import util from '@/common/js/util.js';
import {
onLoad
} from '@dcloudio/uni-app'
// api
import api from '@/api/index.js';
// 代理
const {
proxy
} = getCurrentInstance()
const emit = defineEmits(['change'])
// 传参
const props = defineProps({
province: {
type: [String,Number],
},
city: {
type: [String,Number],
},
area: {
type: [String,Number],
},
})
// 地区
const region = reactive([])
// 地区下标
const regionIndex = reactive([0, 0, 0])
// 上次选择的地区下标
const regionIndexLast = reactive([0, 0, 0])
// 省份
const province = computed(() => {
return region[regionIndex[0]]
})
// 区县
const city = computed(() => {
return province.value && province.value.children[regionIndex[1]]
})
// 地区
const area = computed(() => {
return city.value && city.value.children[regionIndex[2]]
})
// 加载状态
const loading = ref(false);
onLoad(() => {
// 获取数据
getRegion()
})
// 初始化地区下标
function initRegionIndex() {
console.log('props', props)
if (props.province) {
const provinceIndex = region.findIndex(item => item.id == props.province);
regionIndex[0] = provinceIndex;
if (props.city) {
const cityIndex = region[provinceIndex].children.findIndex(item => item.id == props.city);
regionIndex[1] = cityIndex;
if (props.area) {
const areaIndex = region[provinceIndex].children[cityIndex].children.findIndex(item => item.id ==
props.area);
regionIndex[2] = areaIndex;
}
}
}
}
// 获取数据
function getRegion() {
loading.value = true;
try {
//
api.getRegion().then(res => {
if (res.code === 200) {
region.length = 0
region.push(...res.data)
loading.value = false;
// 初始化下标
initRegionIndex()
return
}
util.alert({
content: res.msg,
showCancel: false,
})
loading.value = false;
})
} catch (error) {
console.error('Error occurred while fetching region data:', error);
loading.value = false;
}
}
/**
* 切换
* @param {Object} value 具体的值
* @param {Object} index 下标
*/
function handleIndex(value, index) {
if (index >= 0 && index < regionIndex.length) {
regionIndex[index] = value;
}
}
// 开启弹窗
function open() {
console.log('open', proxy.$refs)
proxy.$refs.selection.open()
}
// 关闭弹窗
function close() {
proxy.$refs.selection.close()
setTimeout(() => {
// 恢复上一次选择的值
Object.assign(regionIndex, regionIndexLast.slice());
// 恢复上一次选择的值
regionIndexLast = regionIndex.slice();
}, 500)
}
// 取消
function handleCancel() {
close();
}
// 选择
function handleSubmit() {
Object.assign(regionIndexLast, regionIndex.slice());
if (province.value && city.value && area.value) {
emit('change', {
province: province.value,
city: city.value,
area: area.value,
});
}
proxy.$refs.selection.close()
}
//
defineExpose({
open,
close,
initRegionIndex,
})
</script>
<template>
<template v-if="province">
<text>{{province.regionName}}</text>
<text>{{city.regionName}}</text>
<text>{{area.regionName}}</text>
</template>
<template v-else>
<text class="placeholderStyle">请选择产品所在地</text>
</template>
<uni-popup ref="selection" type="bottom">
<view class="selectionAlt popBot bfff">
<view class="header rows plr30">
<view class="option ptb30 f28" @click="handleCancel">取消</view>
<view class="title f32">选择省市区</view>
<view class="option ptb30 f28" @click="handleSubmit">确认</view>
</view>
<view class="main df plr10 plr10">
<scroll-view scroll-y="true" class="scroll province">
<view class="list">
<view class="item ptb20 tac" v-for="(item, index) in region" :key="index"
:class="{'active': index == regionIndex[0]}" @click="handleIndex(index,0)">
{{ item.regionName }}
</view>
</view>
</scroll-view>
<scroll-view scroll-y="true" class="scroll city" v-if="province">
<view class="list">
<view class="item ptb20 tac" v-for="(item, index) in province.children" :key="index"
:class="{'active': index == regionIndex[1]}" @click="handleIndex(index,1)">
{{ item.regionName }}
</view>
</view>
</scroll-view>
<scroll-view scroll-y="true" class="scroll area" v-if="city">
<view class="list">
<view class="item ptb20 tac" v-for="(item, index) in city.children" :key="index"
:class="{'active': index == regionIndex[2]}" @click="handleIndex(index,2)">
{{ item.regionName }}
</view>
</view>
</scroll-view>
<view v-if="loading" class="loading">Loading...</view>
</view>
</view>
</uni-popup>
</template>
<style lang="scss" scoped>
// 选择器弹窗
.selectionAlt {
//
.main {
height: 500rpx;
background-color: #f8f8f8;
.item {
color: #999;
&.active {
color: #333;
}
}
}
}
.loading {
text-align: center;
padding: 20rpx;
}
</style>