当前位置:首页 > VUE

vue实现多选联动

2026-01-11 23:11:06VUE

实现多选联动的基本思路

在Vue中实现多选联动功能,通常需要利用v-model绑定数据、监听选项变化以及动态更新关联选项。以下是几种常见的实现方式:

基于v-model和计算属性

通过v-model绑定选中项,利用计算属性或watch监听变化,动态更新关联选项。

vue实现多选联动

<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。

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中实现多选联动的主要场景,可以根据具体需求选择合适的方式或组合使用。

标签: 多选vue
分享给朋友:

相关文章

vue实现选择季度

vue实现选择季度

Vue 实现选择季度的几种方法 使用下拉选择框(Select) 在 Vue 中可以通过 v-model 绑定一个下拉选择框来实现季度选择。数据可以预先定义为一个包含季度选项的数组。 <tem…

vue实现压缩上传文件

vue实现压缩上传文件

压缩上传文件的实现方法 在Vue中实现文件压缩和上传功能,可以通过以下步骤完成。该方法结合了前端文件压缩库和HTTP请求,确保文件在上传前被有效压缩。 安装必要的依赖 需要使用compressor…

vue实现横向导航

vue实现横向导航

vue实现横向导航的方法 使用Flex布局实现横向导航 在Vue中可以通过Flex布局快速实现横向导航。创建一个组件,使用display: flex和flex-direction: row属性使导航项…

vue实现表格多行修改

vue实现表格多行修改

实现多行编辑表格 在Vue中实现表格的多行编辑功能,可以通过以下方法完成。这里以Element UI的表格组件为例,但思路适用于其他UI库或原生实现。 数据准备 定义表格数据和编辑状态管理变量:…

vue设计与实现 书

vue设计与实现 书

vue设计与实现 书 《Vue.js设计与实现》是一本深入探讨Vue.js框架内部原理和设计思想的书籍,适合希望深入理解Vue.js的开发者。以下是关于这本书的详细信息: 书籍内容 《Vue…

vue实现视频会议

vue实现视频会议

使用 Vue 实现视频会议 技术选型 Vue.js 作为前端框架,结合 WebRTC 技术实现实时音视频通信。常用的库包括: peerjs:简化 WebRTC 的点对点连接。 socket.io:用…