vue实现级联菜单
实现级联菜单的基本思路
级联菜单通常指多级联动的下拉选择器,例如省市区选择。Vue 中可通过组件递归或动态数据绑定实现。
使用递归组件实现
递归组件适合处理不确定层级的级联数据。定义一个子组件,内部调用自身渲染下一级菜单。
<template>
<div>
<select v-model="selectedValue" @change="handleChange">
<option value="">请选择</option>
<option v-for="item in options" :key="item.value" :value="item.value">
{{ item.label }}
</option>
</select>
<Cascader
v-if="selectedValue && children"
:options="children"
@change="emitChange"
/>
</div>
</template>
<script>
export default {
name: 'Cascader',
props: {
options: Array
},
data() {
return {
selectedValue: '',
children: []
}
},
methods: {
handleChange() {
const selected = this.options.find(item => item.value === this.selectedValue)
this.children = selected?.children || []
this.emitChange()
},
emitChange() {
this.$emit('change', this.selectedValue)
}
}
}
</script>
使用动态数据绑定实现
通过监听选择变化动态加载下一级数据,适合层级固定的场景。
<template>
<div>
<select v-model="level1" @change="loadLevel2">
<option value="">请选择省份</option>
<option v-for="province in provinces" :key="province.id" :value="province.id">
{{ province.name }}
</option>
</select>
<select v-model="level2" @change="loadLevel3" :disabled="!level1">
<option value="">请选择城市</option>
<option v-for="city in cities" :key="city.id" :value="city.id">
{{ city.name }}
</option>
</select>
<select v-model="level3" :disabled="!level2">
<option value="">请选择区县</option>
<option v-for="district in districts" :key="district.id" :value="district.id">
{{ district.name }}
</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
level1: '',
level2: '',
level3: '',
provinces: [],
cities: [],
districts: []
}
},
methods: {
loadLevel2() {
this.cities = this.getCitiesByProvince(this.level1)
this.level2 = ''
this.level3 = ''
},
loadLevel3() {
this.districts = this.getDistrictsByCity(this.level2)
this.level3 = ''
}
}
}
</script>
使用第三方组件库
Element UI 和 Ant Design Vue 等库提供现成的级联选择器组件。
Element UI 示例
<template>
<el-cascader
v-model="selectedOptions"
:options="options"
@change="handleChange"
/>
</template>
<script>
export default {
data() {
return {
selectedOptions: [],
options: [
{
value: 'zhejiang',
label: '浙江',
children: [
{
value: 'hangzhou',
label: '杭州'
}
]
}
]
}
}
}
</script>
Ant Design Vue 示例
<template>
<a-cascader
v-model="value"
:options="options"
placeholder="请选择"
@change="onChange"
/>
</template>
关键注意事项
数据格式需保持一致,通常采用树形结构:
[
{
value: 'parent1',
label: 'Parent 1',
children: [
{ value: 'child1', label: 'Child 1' }
]
}
]
异步加载数据时需处理加载状态:

methods: {
loadData(selectedOptions) {
const targetOption = selectedOptions[selectedOptions.length - 1]
targetOption.loading = true
fetchData(targetOption.value).then(data => {
targetOption.loading = false
targetOption.children = data
})
}
}
通过以上方法可实现不同复杂度的级联菜单,根据项目需求选择合适方案。






