vue实现级联菜单
Vue 实现级联菜单的方法
使用 Element UI 的 Cascader 组件
安装 Element UI:
npm install element-ui
在 Vue 项目中引入 Cascader 组件:
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
使用 Cascader 组件:
<template>
<el-cascader
v-model="selectedOptions"
:options="options"
@change="handleChange"
></el-cascader>
</template>
<script>
export default {
data() {
return {
selectedOptions: [],
options: [
{
value: 'zhejiang',
label: '浙江省',
children: [
{
value: 'hangzhou',
label: '杭州市',
children: [
{ value: 'xihu', label: '西湖区' },
{ value: 'xiasha', label: '下沙区' }
]
}
]
}
]
};
},
methods: {
handleChange(value) {
console.log(value);
}
}
};
</script>
自定义级联菜单
通过递归组件实现自定义级联菜单:
<template>
<div>
<select v-model="selectedProvince" @change="handleProvinceChange">
<option value="">请选择省份</option>
<option v-for="province in provinces" :value="province.id">
{{ province.name }}
</option>
</select>
<select v-model="selectedCity" @change="handleCityChange" v-if="cities.length">
<option value="">请选择城市</option>
<option v-for="city in cities" :value="city.id">
{{ city.name }}
</option>
</select>
<select v-model="selectedDistrict" v-if="districts.length">
<option value="">请选择区县</option>
<option v-for="district in districts" :value="district.id">
{{ district.name }}
</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
provinces: [
{ id: 1, name: '浙江省' },
{ id: 2, name: '江苏省' }
],
cities: [],
districts: [],
selectedProvince: '',
selectedCity: '',
selectedDistrict: ''
};
},
methods: {
handleProvinceChange() {
this.cities = this.getCitiesByProvince(this.selectedProvince);
this.selectedCity = '';
this.districts = [];
},
handleCityChange() {
this.districts = this.getDistrictsByCity(this.selectedCity);
this.selectedDistrict = '';
},
getCitiesByProvince(provinceId) {
// 模拟API请求
const data = {
1: [
{ id: 101, name: '杭州市' },
{ id: 102, name: '宁波市' }
],
2: [
{ id: 201, name: '南京市' },
{ id: 202, name: '苏州市' }
]
};
return data[provinceId] || [];
},
getDistrictsByCity(cityId) {
// 模拟API请求
const data = {
101: [
{ id: 10101, name: '西湖区' },
{ id: 10102, name: '余杭区' }
],
102: [
{ id: 10201, name: '海曙区' },
{ id: 10202, name: '鄞州区' }
]
};
return data[cityId] || [];
}
}
};
</script>
使用 Vue 动态加载数据
实现异步加载级联数据:
<template>
<el-cascader
v-model="selectedOptions"
:props="props"
></el-cascader>
</template>
<script>
export default {
data() {
return {
selectedOptions: [],
props: {
lazy: true,
lazyLoad(node, resolve) {
const { level } = node;
setTimeout(() => {
const nodes = Array.from({ length: level + 1 })
.map(item => ({
value: Math.random(),
label: `选项${Math.random().toString(36).substr(2, 5)}`,
leaf: level >= 2
}));
resolve(nodes);
}, 1000);
}
}
};
}
};
</script>
注意事项
- 数据格式要符合组件要求,通常需要包含 value、label 和 children 字段
- 对于大数据量考虑使用懒加载方式
- 多级联动时要注意数据清理,切换上级选项时应清空下级选项
- 移动端使用时要注意交互体验,可以考虑使用弹窗式选择器







