vue 实现级联
Vue 实现级联选择器
级联选择器(Cascader)常用于省市区选择、分类选择等场景。Vue 中可以通过 Element UI、Ant Design Vue 等 UI 库实现,也可以手动封装。
使用 Element UI 实现
Element UI 提供了 el-cascader 组件,支持动态加载、多选等功能。
安装 Element UI:
npm install element-ui
基础用法:
<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: '西湖区' }
]
}
]
}
]
}
},
methods: {
handleChange(value) {
console.log(value)
}
}
}
</script>
使用 Ant Design Vue 实现
Ant Design Vue 的 a-cascader 组件同样支持级联选择。

安装 Ant Design Vue:
npm install ant-design-vue
基础用法:
<template>
<a-cascader
v-model="selectedOptions"
:options="options"
placeholder="请选择"
@change="handleChange"
/>
</template>
<script>
export default {
data() {
return {
selectedOptions: [],
options: [
{
value: 'zhejiang',
label: '浙江省',
children: [
{
value: 'hangzhou',
label: '杭州市',
children: [
{ value: 'xihu', label: '西湖区' }
]
}
]
}
]
}
},
methods: {
handleChange(value) {
console.log(value)
}
}
}
</script>
手动封装级联选择器
如果需要自定义级联选择器,可以通过递归组件实现。

定义递归组件:
<template>
<div>
<select v-model="selectedValue" @change="handleSelectChange">
<option v-for="item in options" :key="item.value" :value="item.value">
{{ item.label }}
</option>
</select>
<Cascader
v-if="selectedValue && hasChildren"
:options="childrenOptions"
@change="handleChildChange"
/>
</div>
</template>
<script>
export default {
name: 'Cascader',
props: {
options: Array
},
data() {
return {
selectedValue: ''
}
},
computed: {
hasChildren() {
const selected = this.options.find(item => item.value === this.selectedValue)
return selected && selected.children
},
childrenOptions() {
const selected = this.options.find(item => item.value === this.selectedValue)
return selected ? selected.children : []
}
},
methods: {
handleSelectChange() {
this.$emit('change', [this.selectedValue])
},
handleChildChange(childValues) {
this.$emit('change', [this.selectedValue, ...childValues])
}
}
}
</script>
调用自定义组件:
<template>
<Cascader :options="options" @change="handleChange" />
</template>
<script>
import Cascader from './Cascader.vue'
export default {
components: { Cascader },
data() {
return {
options: [
{
value: 'zhejiang',
label: '浙江省',
children: [
{
value: 'hangzhou',
label: '杭州市',
children: [
{ value: 'xihu', label: '西湖区' }
]
}
]
}
]
}
},
methods: {
handleChange(values) {
console.log(values)
}
}
}
</script>
动态加载数据
对于数据量大的场景,可以动态加载子选项。
Element UI 动态加载示例:
<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(() => ({
value: Math.random(),
label: `选项 ${level + 1}`,
leaf: level >= 2
}))
resolve(nodes)
}, 1000)
}
}
}
}
}
</script>
注意事项
- 数据结构需要包含
value和label字段,子选项放在children中 - 动态加载时注意性能优化,避免频繁请求
- 多选场景需要特殊处理选中状态
- 移动端适配可能需要额外样式调整






