vue实现级联面板
Vue 实现级联面板
级联面板(Cascader)通常用于多级分类选择,例如省市区选择。以下是实现级联面板的几种方法:

使用 Element UI 的 Cascader 组件
Element UI 提供了现成的 Cascader 组件,适合快速集成:

<template>
<el-cascader
v-model="selectedOptions"
:options="options"
@change="handleChange"
></el-cascader>
</template>
<script>
export default {
data() {
return {
selectedOptions: [],
options: [
{
value: 'province1',
label: 'Province 1',
children: [
{
value: 'city1',
label: 'City 1',
children: [
{
value: 'district1',
label: 'District 1'
}
]
}
]
}
]
};
},
methods: {
handleChange(value) {
console.log(value);
}
}
};
</script>
自定义级联面板
如果需要更灵活的定制,可以手动实现级联逻辑:
<template>
<div class="cascader">
<select v-model="selectedProvince" @change="loadCities">
<option v-for="province in provinces" :value="province.id">
{{ province.name }}
</option>
</select>
<select v-model="selectedCity" @change="loadDistricts" :disabled="!selectedProvince">
<option v-for="city in cities" :value="city.id">
{{ city.name }}
</option>
</select>
<select v-model="selectedDistrict" :disabled="!selectedCity">
<option v-for="district in districts" :value="district.id">
{{ district.name }}
</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
provinces: [],
cities: [],
districts: [],
selectedProvince: null,
selectedCity: null,
selectedDistrict: null
};
},
methods: {
loadCities() {
this.cities = this.getCitiesByProvince(this.selectedProvince);
this.selectedCity = null;
this.districts = [];
},
loadDistricts() {
this.districts = this.getDistrictsByCity(this.selectedCity);
this.selectedDistrict = null;
}
}
};
</script>
使用递归组件实现无限级联
对于不确定层级的级联需求,可以使用递归组件:
<template>
<div>
<cascader-item
v-for="item in items"
:key="item.value"
:item="item"
@select="handleSelect"
/>
</div>
</template>
<script>
import CascaderItem from './CascaderItem.vue';
export default {
components: { CascaderItem },
props: ['items'],
methods: {
handleSelect(item) {
this.$emit('select', item);
}
}
};
</script>
<!-- CascaderItem.vue -->
<template>
<div>
<div @click="toggle">
{{ item.label }}
</div>
<cascader
v-if="showChildren && item.children"
:items="item.children"
@select="$emit('select', $event)"
/>
</div>
</template>
<script>
export default {
name: 'CascaderItem',
props: ['item'],
data() {
return {
showChildren: false
};
},
methods: {
toggle() {
this.showChildren = !this.showChildren;
this.$emit('select', this.item);
}
}
};
</script>
注意事项
- 数据加载性能:对于大数据量,考虑懒加载或虚拟滚动。
- 样式定制:通过 CSS 可以自定义面板的外观和行为。
- 异步加载:可以通过 API 动态加载子级数据。
以上方法可以根据具体需求选择或组合使用,Element UI 的方案适合快速开发,自定义方案则提供更大的灵活性。





