162 lines
3.5 KiB
Vue
162 lines
3.5 KiB
Vue
<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> |