当前位置:首页 > VUE

vue 实现多选功能

2026-03-28 23:39:24VUE

Vue 多选功能实现方法

基础实现(v-model 绑定数组)

通过 v-model 绑定数组实现多选,适用于原生 <select multiple> 或复选框组:

<template>
  <!-- 原生多选下拉框 -->
  <select v-model="selectedItems" multiple>
    <option v-for="item in options" :value="item.value">{{ item.label }}</option>
  </select>

  <!-- 复选框组 -->
  <div v-for="item in options" :key="item.value">
    <input 
      type="checkbox" 
      :id="item.value" 
      :value="item.value" 
      v-model="selectedItems"
    >
    <label :for="item.value">{{ item.label }}</label>
  </div>
</template>

<script>
export default {
  data() {
    return {
      selectedItems: [],
      options: [
        { value: 'opt1', label: 'Option 1' },
        { value: 'opt2', label: 'Option 2' }
      ]
    }
  }
}
</script>

自定义组件实现

封装可复用的多选组件,支持搜索、标签展示等功能:

<template>
  <div class="multi-select">
    <div class="selected-tags">
      <span v-for="(item, index) in selected" :key="index">
        {{ getLabel(item) }}
        <button @click="removeItem(index)">×</button>
      </span>
    </div>
    <input 
      type="text" 
      v-model="searchText" 
      @keydown.enter="addItem"
      placeholder="Type and press Enter"
    >
    <ul v-if="filteredOptions.length">
      <li 
        v-for="item in filteredOptions" 
        :key="item.value" 
        @click="toggleItem(item.value)"
      >
        {{ item.label }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: {
    options: Array,
    value: Array
  },
  data() {
    return {
      searchText: '',
      selected: this.value || []
    }
  },
  computed: {
    filteredOptions() {
      return this.options.filter(opt => 
        !this.selected.includes(opt.value) &&
        opt.label.toLowerCase().includes(this.searchText.toLowerCase())
      )
    }
  },
  methods: {
    toggleItem(value) {
      const index = this.selected.indexOf(value)
      if (index > -1) {
        this.selected.splice(index, 1)
      } else {
        this.selected.push(value)
      }
      this.$emit('input', [...this.selected])
    },
    getLabel(value) {
      const item = this.options.find(opt => opt.value === value)
      return item ? item.label : value
    },
    removeItem(index) {
      this.selected.splice(index, 1)
      this.$emit('input', [...this.selected])
    }
  }
}
</script>

第三方库方案

使用现成的多选组件库(如 vue-multiselect):

vue 实现多选功能

  1. 安装依赖:

    npm install vue-multiselect
  2. 基础用法:

    vue 实现多选功能

    
    <template>
    <multiselect
     v-model="selected"
     :options="options"
     :multiple="true"
     :close-on-select="false"
     label="label"
     track-by="value"
    ></multiselect>
    </template>
import Multiselect from 'vue-multiselect' export default { components: { Multiselect }, data() { return { selected: [], options: [ { label: 'Option 1', value: 'opt1' }, { label: 'Option 2', value: 'opt2' } ] } } } ```

高级功能扩展

实现全选/反选、分组显示等高级功能:

<template>
  <div>
    <button @click="toggleAll">Toggle All</button>
    <div v-for="group in groupedOptions" :key="group.name">
      <h4>{{ group.name }}</h4>
      <label v-for="item in group.items" :key="item.value">
        <input
          type="checkbox"
          :value="item.value"
          v-model="selectedItems"
        >
        {{ item.label }}
      </label>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      selectedItems: [],
      groupedOptions: [
        {
          name: 'Group A',
          items: [
            { value: 'a1', label: 'Item A1' },
            { value: 'a2', label: 'Item A2' }
          ]
        },
        {
          name: 'Group B',
          items: [
            { value: 'b1', label: 'Item B1' },
            { value: 'b2', label: 'Item B2' }
          ]
        }
      ]
    }
  },
  methods: {
    toggleAll() {
      const allValues = this.groupedOptions.flatMap(g => g.items.map(i => i.value))
      this.selectedItems = this.selectedItems.length === allValues.length 
        ? [] 
        : [...allValues]
    }
  }
}
</script>

性能优化建议

对于大型数据集(1000+项),建议:

  • 添加虚拟滚动(使用 vue-virtual-scroller
  • 实现分页加载
  • 添加防抖搜索(使用 Lodash 的 debounce
  • 避免在模板中使用复杂计算

标签: 多选功能
分享给朋友:

相关文章

vue实现按钮实现点击功能

vue实现按钮实现点击功能

实现按钮点击功能 在Vue中实现按钮点击功能可以通过v-on指令或@缩写来绑定事件。以下是几种常见的实现方式: 使用v-on指令 通过v-on:click绑定点击事件,触发定义在methods中的方…

vue电影功能实现

vue电影功能实现

Vue 电影功能实现 数据获取与展示 使用 Axios 或 Fetch API 从电影 API(如 TMDb、豆瓣 API)获取数据。在 Vue 的 created 或 mounted 生命周期钩子中…

vue实现拨号功能

vue实现拨号功能

Vue 实现拨号功能 使用 tel: 协议实现基础拨号 在 Vue 中可以通过 HTML 的 <a> 标签结合 tel: 协议实现拨号功能。这种方式适用于移动端浏览器,点击后会直接调用系统…

vue实现注册功能

vue实现注册功能

前端实现注册功能 在Vue中实现注册功能通常需要结合表单验证、HTTP请求和状态管理。以下是一个基于Vue 3和Element Plus的完整实现方案: 模板部分 <template>…

vue实现筛选功能

vue实现筛选功能

实现筛选功能的基本思路 在Vue中实现筛选功能通常涉及数据绑定、计算属性和方法的使用。通过监听用户输入或选择,动态过滤数据列表。 基础筛选实现 创建一个输入框绑定到Vue实例的data属性,使用计算…

vue打印功能实现

vue打印功能实现

使用Vue实现打印功能 Vue中实现打印功能可以通过浏览器原生的window.print()方法或借助第三方库如vue-print-nb来实现。以下是两种常见方法: 方法一:使用原生JavaScri…