当前位置:首页 > VUE

vue实现左右多选框

2026-02-21 11:13:25VUE

Vue 实现左右多选框组件

左右多选框(Transfer)是常见的表单组件,用于在两个列表之间移动选项。以下是基于 Vue 2/3 的实现方法:

基础组件结构

<template>
  <div class="transfer-container">
    <div class="transfer-panel">
      <h3>可选列表</h3>
      <ul>
        <li v-for="item in leftItems" :key="item.value">
          <input type="checkbox" v-model="selectedLeft" :value="item.value">
          {{ item.label }}
        </li>
      </ul>
    </div>

    <div class="transfer-actions">
      <button @click="moveToRight">→</button>
      <button @click="moveToLeft">←</button>
    </div>

    <div class="transfer-panel">
      <h3>已选列表</h3>
      <ul>
        <li v-for="item in rightItems" :key="item.value">
          <input type="checkbox" v-model="selectedRight" :value="item.value">
          {{ item.label }}
        </li>
      </ul>
    </div>
  </div>
</template>

核心逻辑实现

<script>
export default {
  data() {
    return {
      leftItems: [
        { value: 1, label: '选项1' },
        { value: 2, label: '选项2' },
        { value: 3, label: '选项3' }
      ],
      rightItems: [],
      selectedLeft: [],
      selectedRight: []
    }
  },
  methods: {
    moveToRight() {
      const movedItems = this.leftItems.filter(item => 
        this.selectedLeft.includes(item.value)
      )
      this.rightItems = [...this.rightItems, ...movedItems]
      this.leftItems = this.leftItems.filter(item => 
        !this.selectedLeft.includes(item.value)
      )
      this.selectedLeft = []
    },
    moveToLeft() {
      const movedItems = this.rightItems.filter(item => 
        this.selectedRight.includes(item.value)
      )
      this.leftItems = [...this.leftItems, ...movedItems]
      this.rightItems = this.rightItems.filter(item => 
        !this.selectedRight.includes(item.value)
      )
      this.selectedRight = []
    }
  }
}
</script>

样式优化

<style scoped>
.transfer-container {
  display: flex;
  align-items: center;
  gap: 20px;
}
.transfer-panel {
  border: 1px solid #ddd;
  width: 200px;
  height: 300px;
  overflow-y: auto;
}
.transfer-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
ul {
  list-style: none;
  padding: 0;
}
li {
  padding: 8px;
  border-bottom: 1px solid #eee;
}
</style>

进阶功能实现

双向绑定支持

vue实现左右多选框

props: {
  value: {
    type: Array,
    default: () => []
  }
},
watch: {
  value(newVal) {
    this.rightItems = newVal
    this.leftItems = this.allItems.filter(item => 
      !newVal.some(v => v.value === item.value)
    )
  },
  rightItems: {
    handler(newVal) {
      this.$emit('input', newVal)
    },
    deep: true
  }
}

全选功能

methods: {
  selectAllLeft() {
    this.selectedLeft = this.leftItems.map(item => item.value)
  },
  selectAllRight() {
    this.selectedRight = this.rightItems.map(item => item.value)
  }
}

搜索过滤

vue实现左右多选框

<input v-model="leftFilter" placeholder="搜索">
<ul>
  <li v-for="item in filteredLeftItems" :key="item.value">
    <!-- 选项内容 -->
  </li>
</ul>
computed: {
  filteredLeftItems() {
    return this.leftItems.filter(item => 
      item.label.includes(this.leftFilter)
    )
  }
}

使用第三方库

对于生产环境,推荐使用成熟的组件库:

  • Element UI 的 el-transfer
  • Ant Design Vue 的 a-transfer
  • Vuetify 的 v-combobox 配合多选模式

这些库提供了更完善的API和样式,例如:

<el-transfer
  v-model="value"
  :data="data"
  :titles="['Source', 'Target']"
></el-transfer>

实现时需注意性能优化,特别是大数据量场景下应考虑虚拟滚动、分页加载等技术方案。

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

相关文章

vue实现滑块

vue实现滑块

Vue 实现滑块组件的方法 使用原生 HTML 和 Vue 指令 通过 Vue 的 v-model 和事件监听实现基础滑块功能。创建一个包含 input 元素的组件,类型设置为 range,并绑定到…

vue实现返回

vue实现返回

返回按钮功能实现 在Vue中实现返回功能通常有两种方式:使用浏览器历史记录的history.back()或结合Vue Router进行编程式导航。以下是具体实现方法: 使用浏览器API metho…

vue实现曲线

vue实现曲线

Vue 实现曲线的方法 在 Vue 中实现曲线可以通过多种方式,包括使用 SVG、Canvas 或第三方库如 D3.js、ECharts 等。以下是几种常见的方法: 使用 SVG 绘制曲线 SVG…

vue 实现脚本

vue 实现脚本

Vue 实现脚本的方法 Vue.js 提供了多种方式来实现脚本功能,包括组件内脚本、混入(Mixins)、插件(Plugins)以及自定义指令等。以下是常见的实现方式: 组件内脚本 在 Vue 单文…

vue底层实现

vue底层实现

Vue.js 的底层实现原理 Vue.js 是一个渐进式 JavaScript 框架,其核心实现主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。以下是其关键实现细节: 响应式系统 Vue 2…

vue实现数据联动

vue实现数据联动

Vue 数据联动实现方法 数据联动在 Vue 中通常指多个组件或数据项之间的动态关联更新。以下是几种常见实现方式: 使用 v-model 和计算属性 <template> <…