vue实现多选联动
实现多选联动的基本思路
在Vue中实现多选联动功能,通常需要利用v-model绑定数据、监听选项变化以及动态更新关联选项。以下是几种常见的实现方式:
基于v-model和计算属性
通过v-model绑定选中项,利用计算属性或watch监听变化,动态更新关联选项。

<template>
<div>
<select v-model="selectedParent" multiple>
<option v-for="option in parentOptions" :value="option.id">{{ option.name }}</option>
</select>
<select v-model="selectedChildren" multiple>
<option v-for="option in filteredChildren" :value="option.id">{{ option.name }}</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
parentOptions: [
{ id: 1, name: 'Parent 1' },
{ id: 2, name: 'Parent 2' }
],
childrenOptions: [
{ parentId: 1, id: 11, name: 'Child 1-1' },
{ parentId: 1, id: 12, name: 'Child 1-2' },
{ parentId: 2, id: 21, name: 'Child 2-1' }
],
selectedParent: [],
selectedChildren: []
}
},
computed: {
filteredChildren() {
return this.childrenOptions.filter(child =>
this.selectedParent.includes(child.parentId)
)
}
}
}
</script>
使用事件监听实现级联
通过@change事件监听父级选择变化,动态加载子级选项。
<template>
<div>
<select v-model="selectedCategories" multiple @change="updateProducts">
<option v-for="category in categories" :value="category.id">{{ category.name }}</option>
</select>
<select v-model="selectedProducts" multiple>
<option v-for="product in filteredProducts" :value="product.id">{{ product.name }}</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
categories: [
{ id: 1, name: 'Electronics' },
{ id: 2, name: 'Clothing' }
],
allProducts: [
{ categoryId: 1, id: 101, name: 'Laptop' },
{ categoryId: 1, id: 102, name: 'Phone' },
{ categoryId: 2, id: 201, name: 'Shirt' }
],
selectedCategories: [],
selectedProducts: [],
filteredProducts: []
}
},
methods: {
updateProducts() {
this.filteredProducts = this.allProducts.filter(product =>
this.selectedCategories.includes(product.categoryId)
)
}
}
}
</script>
使用第三方组件实现复杂联动
对于更复杂的多选联动需求,可以考虑使用成熟的UI组件库如Element UI或Ant Design Vue。

<template>
<el-cascader
:options="options"
:props="{ multiple: true }"
v-model="selectedValues"
clearable>
</el-cascader>
</template>
<script>
export default {
data() {
return {
options: [{
value: 'guide',
label: 'Guide',
children: [{
value: 'disciplines',
label: 'Disciplines'
}]
}],
selectedValues: []
}
}
}
</script>
实现全选/反选功能
在多选联动场景中,经常需要实现全选或反选功能。
<template>
<div>
<button @click="toggleAllParents">全选/反选父级</button>
<select v-model="selectedParents" multiple>
<option v-for="parent in parents" :value="parent.id">{{ parent.name }}</option>
</select>
<button @click="toggleAllChildren">全选/反选子级</button>
<select v-model="selectedChildren" multiple>
<option v-for="child in filteredChildren" :value="child.id">{{ child.name }}</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
parents: [
{ id: 1, name: 'Parent 1' },
{ id: 2, name: 'Parent 2' }
],
children: [
{ parentId: 1, id: 11, name: 'Child 1-1' },
{ parentId: 1, id: 12, name: 'Child 1-2' }
],
selectedParents: [],
selectedChildren: []
}
},
computed: {
filteredChildren() {
return this.children.filter(child =>
this.selectedParents.includes(child.parentId)
)
}
},
methods: {
toggleAllParents() {
if (this.selectedParents.length === this.parents.length) {
this.selectedParents = []
} else {
this.selectedParents = this.parents.map(parent => parent.id)
}
},
toggleAllChildren() {
const childIds = this.filteredChildren.map(child => child.id)
if (this.selectedChildren.length === childIds.length) {
this.selectedChildren = []
} else {
this.selectedChildren = [...childIds]
}
}
}
}
</script>
处理异步数据加载
当选项数据需要从API异步加载时,可以使用async/await处理。
<template>
<div>
<select v-model="selectedRegion" multiple @change="loadCities">
<option v-for="region in regions" :value="region.id">{{ region.name }}</option>
</select>
<select v-model="selectedCities" multiple>
<option v-for="city in cities" :value="city.id">{{ city.name }}</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
regions: [],
cities: [],
selectedRegion: [],
selectedCities: []
}
},
async created() {
this.regions = await this.fetchRegions()
},
methods: {
async fetchRegions() {
const response = await fetch('/api/regions')
return response.json()
},
async loadCities() {
if (this.selectedRegion.length === 0) {
this.cities = []
return
}
const cityPromises = this.selectedRegion.map(regionId =>
fetch(`/api/cities?regionId=${regionId}`).then(res => res.json())
)
const citiesArrays = await Promise.all(cityPromises)
this.cities = citiesArrays.flat()
}
}
}
</script>
以上方法涵盖了Vue中实现多选联动的主要场景,可以根据具体需求选择合适的方式或组合使用。






