方案一:动态绑定选项(推荐)

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<template>
<el-form :model="form">
<!-- 疏散点类型选择 -->
<el-form-item label="疏散点类型">
<el-select
v-model="form.disperePointType"
placeholder="请选择疏散点类型"
@change="handleDisperePointTypeChange"
>
<el-option
v-for="(item, index) in disperePointTypeOptions"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>

<!-- 建筑类型选择(动态显示) -->
<el-form-item label="建筑类型" v-if="showPlaceSelect">
<el-select v-model="form.buildingType" placeholder="请选择建筑类型">
<el-option
v-for="(item, index) in buildingTypeOptions"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
</template>

<script setup>
import { ref, onMounted } from 'vue'

// 表单数据
const form = ref({
disperePointType: '',
buildingType: ''
})

// 显示控制
const showPlaceSelect = ref(false)

// 疏散点类型选项
const disperePointTypeOptions = ref([
{ value: 'government', label: '党政机关疏散点' },
{ value: 'resident', label: '城镇居民常设疏散安置点' },
{ value: 'temporary', label: '城镇居民临时疏散点' }
])

// 建筑类型选项数据(按疏散点类型分类)
const buildingTypeData = {
government: [
{ value: 'gov_hotel', label: '酒店(党政机关)' },
{ value: 'state_guesthouse', label: '国宾馆' },
{ value: 'training_base', label: '培训基地' }
],
resident: [
{ value: 'stadium', label: '体育场' },
{ value: 'school', label: '学校' },
{ value: 'resident_hotel', label: '酒店(居民)' }
],
temporary: [
{ value: 'open_space', label: '空地' }
]
}

// 动态计算的建筑类型选项
const buildingTypeOptions = ref([])

// 初始化默认选中第一项
onMounted(() => {
if (disperePointTypeOptions.value.length > 0) {
form.value.disperePointType = disperePointTypeOptions.value[0].value
handleDisperePointTypeChange(form.value.disperePointType)
}
})

// 疏散点类型变化处理
const handleDisperePointTypeChange = (type) => {
if (type && buildingTypeData[type]) {
buildingTypeOptions.value = buildingTypeData[type]
// 默认选中建筑类型第一项
if (buildingTypeOptions.value.length > 0) {
form.value.buildingType = buildingTypeOptions.value[0].value
}
showPlaceSelect.value = true
} else {
showPlaceSelect.value = false
form.value.buildingType = ''
}
}
</script>

关键实现说明

  1. 默认选中第一项

    • onMounted 生命周期钩子中设置默认值
    • 疏散点类型默认选中第一个选项
    • 自动触发 handleDisperePointTypeChange 设置对应的建筑类型第一项
  2. 动态选项更新

    • 使用 buildingTypeData 对象存储不同疏散点类型对应的建筑类型
    • 当疏散点类型变化时,更新 buildingTypeOptions 数组使用 v-if 控制第二级选择框的显示
  3. 显示控制

    • 使用 v-if="showPlaceSelect" 控制建筑类型选择框的显示
    • 只有选择了有效的疏散点类型时才显示建筑类型选择
  4. 数据重置

    • 当疏散点类型变化时,自动重置建筑类型选择
    • 确保选项和值的同步更新

方案二:条件渲染(适合选项结构差异大的场景)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<template>
<el-form>
<!-- 第一级:疏散点类型 -->
<el-select v-model="evacuationType" placeholder="请选择类型">
<el-option value="government" label="党政机关疏散点" />
<el-option value="resident" label="城镇居民常设疏散安置点" />
<el-option value="temporary" label="城镇居民临时疏散点" />
</el-select>

<!-- 党政机关选项 -->
<el-select
v-if="evacuationType === 'government'"
v-model="govPlace"
placeholder="请选择党政机关场所"
>
<el-option value="hotel_gov" label="酒店(党政机关)" />
<el-option value="state_guesthouse" label="国宾馆" />
</el-select>

<!-- 居民常设选项 -->
<el-select
v-if="evacuationType === 'resident'"
v-model="residentPlace"
placeholder="请选择居民安置点"
>
<el-option value="school" label="学校" />
<el-option value="stadium" label="体育场" />
</el-select>
</el-form>
</template>

关键实现要点

  1. 数据结构设计

    1
    2
    3
    4
    5
    // 使用对象存储层级关系
    const allPlaces = {
    类型1: [选项1, 选项2],
    类型2: [选项3, 选项4]
    }
  2. 动态计算属性

    1
    2
    3
    const filteredPlaces = computed(() => {
    return currentType.value ? allPlaces[currentType.value] : []
    })
  3. 重置二级选择(当一级变化时)

    1
    2
    3
    watch(evacuationType, (newVal) => {
    specificPlace.value = '' // 清空之前的选择
    })

效果增强建议

  1. 添加禁用状态

    1
    2
    3
    4
    <el-select 
    :disabled="!evacuationType"
    placeholder="请先选择类型"
    >
  2. 添加分组显示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <el-option-group
    v-for="group in filteredGroups"
    :key="group.label"
    :label="group.label"
    >
    <el-option
    v-for="item in group.options"
    :key="item.value"
    :label="item.label"
    :value="item.value"
    />
    </el-option-group>

完整数据参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const allPlaces = {
government: [
{ value: 'hotel_gov', label: '酒店(党政机关)' },
{ value: 'state_guesthouse', label: '国宾馆' },
{ value: 'conference_center', label: '党政会议中心' }
],
resident: [
{ value: 'village', label: '村庄' },
{ value: 'stadium', label: '体育场' },
{ value: 'school', label: '学校' }
],
temporary: [
{ value: 'open_field', label: '空地' }
]
}