work-order/work-order-uniapp/components/RegionPicker.vue

162 lines
3.5 KiB
Vue
Raw Normal View History

2025-07-27 20:34:15 +08:00
<template>
<view class="region-picker">
<view class="picker-header">
<text class="title">选择地区</text>
<text class="close" @click="close">×</text>
</view>
<view class="picker-content">
<scroll-view
v-for="(list, index) in regionLists"
:key="index"
class="region-list"
scroll-y
>
<view
v-for="item in list"
:key="item.id"
class="region-item"
:class="{ active: selectedIds[index] === item.id }"
@click="selectRegion(item, index)"
>
{{ item.name }}
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
name: 'RegionPicker',
props: {
value: {
type: Array,
default: () => []
},
regionData: {
type: Array,
default: () => []
}
},
data() {
return {
regionLists: [],
selectedIds: [],
selectedNames: []
}
},
watch: {
regionData: {
immediate: true,
handler(val) {
if (val.length) {
this.regionLists = [val.filter(item => item.pid === '0')]
if (this.value.length) {
this.initSelected(this.value)
}
}
}
}
},
methods: {
initSelected(ids) {
this.selectedIds = [...ids]
this.selectedNames = []
this.regionLists = [this.regionData.filter(item => item.pid === '0')]
let currentId = ids[0]
for (let i = 0; i < ids.length; i++) {
const item = this.regionData.find(item => item.id === currentId)
if (item) {
this.selectedNames.push(item.name)
const nextLevel = this.regionData.filter(item => item.pid === currentId)
if (nextLevel.length) {
this.regionLists.push(nextLevel)
currentId = ids[i + 1]
}
}
}
},
selectRegion(item, index) {
this.selectedIds = this.selectedIds.slice(0, index)
this.selectedNames = this.selectedNames.slice(0, index)
this.selectedIds.push(item.id)
this.selectedNames.push(item.name)
const nextLevel = this.regionData.filter(item => item.pid === this.selectedIds[index])
if (nextLevel.length) {
this.regionLists = this.regionLists.slice(0, index + 1)
this.regionLists.push(nextLevel)
} else {
this.regionLists = this.regionLists.slice(0, index + 1)
this.$emit('change', {
ids: this.selectedIds,
names: this.selectedNames
})
}
},
close() {
this.$emit('close')
}
}
}
</script>
<style lang="scss" scoped>
.region-picker {
width: 100%;
background: #fff;
border-radius: 24rpx 24rpx 0 0;
.picker-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.close {
font-size: 40rpx;
color: #999;
padding: 0 20rpx;
}
}
.picker-content {
display: flex;
height: 600rpx;
.region-list {
flex: 1;
min-width: 33.33%;
height: 100%;
border-right: 1rpx solid #eee;
&:last-child {
border-right: none;
}
.region-item {
padding: 20rpx 30rpx;
font-size: 28rpx;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&.active {
color: #6a8cff;
background: #f7f8fa;
}
}
}
}
}
</style>