自己写的穿梭框

<template>
  <el-dialog
    title="匹配"
    :visible.sync="dialog.isShow"
    width="730px"
    top="70px"
    :close-on-click-modal="false"
    @open="openDialog"
  >
    <!-- <el-transfer
      v-model="value"
      class="department-match"
      filterable
      :filter-method="filterData"
      :titles="['未匹配数据', '已匹配数据']"
      filter-placeholder="请输入"
      :props="{
        key: 'lngdepartmentid',
        label: 'strdepartmentcodeandname'
      }"
      :data="data"
    /> -->
    <div class="transfer-panel">
      <div class="transfer-panel-tit">未匹配数据</div>
      <div class="transfer-panel-search">
        <el-input
          v-model="searchLeft"
          placeholder="请输入"
          @input="filterFn"
          @focus="focusEvent"
        />
        <span class="transfer-panel-search-icon"><i class="el-input__icon el-icon-search" /></span>
      </div>
      <div class="transfer-panel-list">
        <ul>
          <li v-for="(item,index) in data" :key="index" :class="{cur:index===currentIndex}" @click="currentDepartment(index,item)" @dblclick="dblcurrentDepartment(index,item)">{{ item.strdepartmentcodeandname }}</li>
        </ul>
      </div>
    </div>
    <div class="transfer__buttons">
      <el-button :disabled="!toLeftBtn" type="primary" @click="toLeftFn"><span><i class="el-icon-arrow-left" /></span></el-button><br>
      <el-button :disabled="!toRightBtn" type="primary" style="margin-top:10px" @click="toRightFn"><span><i class="el-icon-arrow-right" /></span></el-button>
    </div>
    <div class="transfer-panel" style="height:304px">
      <div class="transfer-panel-tit">已匹配数据</div>
      <div class="transfer-panel-search">
        <!-- <el-input
          v-model="searchRight"
          placeholder="请输入"
        />
        <span class="transfer-panel-search-icon"><i class="el-input__icon el-icon-search" /></span> -->
      </div>
      <div class="transfer-panel-list">
        <ul>
          <li :class="{cur:isRightListClick}" @click="rightListClick" @dblclick="dblrightListClick">{{ Matched.strdepartmentcodeandname }}</li>
        </ul>
      </div>
    </div>
    <div slot="footer">
      <el-button type="primary" @click="save">确 定</el-button>
      <el-button @click="dialog.isShow = false">取 消</el-button>
    </div>
  </el-dialog>
</template>
<script>
import { searchunmate, matching } from '@/api/financial-management/basic-settings/financial-department-match'
// import pinyinMatch from 'pinyin-match'
const PinyinEngine = require('pinyin-engine')
export default {
  name: 'MatchDialog',
  data() {
    return {
      data: [],
      searchLeft: '', // 搜索左侧
      searchRight: '', // 搜索右侧
      dialog: {
        isShow: false
      },
      lngdepartmentid: '',
      pinyinEngine: null,
      currentMatch: {}, // 临时存储单击选中的数据
      Matched: { // 右侧数据
        // 'lngdepartmentid': '',
        // 'strdepartmentcodeandname': ''
      },
      toLeftBtn: false,
      toRightBtn: false,
      currentIndex: '', // 当前点击的索引
      isRightListClick: false // 右侧列表是否点击
    }
  },
  methods: {
    show(row) {
      this.dialog.isShow = true
      this.lngdepartmentid = row.lngdepartmentid
      this.Matched = {}
      if (row.lngmatedepartmentid) {
        this.Matched.lngdepartmentid = row.lngmatedepartmentid
        this.Matched.strdepartmentcodeandname = row.strmatedepartmentcodeandname
      }
    },
    openDialog() {
      this.searchLeft = ''
      this.searchRight = ''
      this.currentIndex = ''
      this.currentMatch = {}
      this.toRightBtn = false
      this.toLeftBtn = false
    },
    // 单击选中的数据
    currentDepartment(index, item) {
      this.currentIndex = index
      this.currentMatch = item
      this.toRightBtn = true
    },
    // 左侧双击选中的数据
    dblcurrentDepartment(index, item) {
      this.data.splice(index, 1)
      if (this.Matched.lngdepartmentid) {
        this.data.push(this.Matched)
      }
      this.Matched = item
      this.toRightBtn = false
      this.toLeftBtn = false
      this.currentIndex = ''
      this.isRightListClick = false
    },
    // 右侧双击选中的数据
    dblrightListClick() {
      this.data.push(this.Matched)
      this.Matched = {}
      this.currentMatch = {}
      this.toRightBtn = false
      this.toLeftBtn = false
      this.currentIndex = ''
      this.isRightListClick = false
    },
    // 向右按钮
    toRightFn() {
      this.data.splice(this.currentIndex, 1)
      if (this.Matched.lngdepartmentid) {
        this.data.push(this.Matched)
      }
      this.Matched = this.currentMatch
      this.toRightBtn = false
      this.toLeftBtn = false
      this.currentIndex = ''
      this.isRightListClick = false
    },
    // 向左按钮
    toLeftFn() {
      this.data.push(this.Matched)
      this.Matched = {}
      this.currentMatch = {}
      this.toRightBtn = false
      this.toLeftBtn = false
      this.currentIndex = ''
      this.isRightListClick = false
    },
    // 右侧列表选中
    rightListClick() {
      this.isRightListClick = true
      this.toLeftBtn = true
    },
    save() {
      if (!this.Matched.lngdepartmentid) {
        this.$message.error('请选择一条数据')
        return false
      }
      matching({
        'lngdepartmentid': this.lngdepartmentid,
        'lngmatedepartmentid': this.Matched.lngdepartmentid
      }
      ).then(res => {
        if (res.code === 20000) {
          this.$message.success(res.message)
          this.$emit('refresh')
          this.dialog.isShow = false
        }
      })
    },
    // 未匹配数据
    searchunmateFn() {
      searchunmate({}).then(res => {
        if (res.code === 20000) {
          this.data = res.data
          this.pinyinEngine = new PinyinEngine(this.data, ['strdepartmentcodeandname'])
        }
      })
    },
    filterFn() {
      this.data = this.pinyinEngine.query(this.searchLeft)
    },
    focusEvent(e) {
      if (!e.target.value) {
        this.data = this.pinyinEngine.query('')
      }
    }
    // filterData(keyword, node) {
    //   return pinyinMatch.match(node.strdepartmentcodeandname, keyword)
    // }
  }
}
</script>
<style>
.department-match .el-transfer__button:first-child{margin-bottom:0px}
.department-match .el-transfer-panel{260px}
.department-match .el-transfer-panel__header .el-checkbox__input {display:none}
.transfer-panel {
    border: 1px solid #e6ebf5;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
    display: inline-block;
    vertical-align: middle;
     260px;
    max-height: 100%;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    position: relative;
}
.transfer-panel-tit {
    height: 40px;
    line-height: 40px;
    background: #F5F7FA;
    margin: 0;
    padding-left: 15px;
    border-bottom: 1px solid #e6ebf5;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    color: #000;
    font-size: 16px;
    color: #303133;
    font-weight: normal;
}
.transfer-panel-search{
    text-align: center;
    margin: 15px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    display: block;
     auto;
    position: relative;
}
.transfer-panel-search .el-input__inner {
    border: none;
    border-bottom: 1px solid #DCDFE6;
    border-radius: 0;
    height: 32px;
     100%;
    font-size: 12px;
    display: inline-block;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    border-radius: 16px;
    padding-right: 10px;
    padding-left: 30px;
}
.transfer-panel-search-icon {
    position: absolute;
    height: 100%;
    left: 5px;
    top: 0;
    text-align: center;
    color: #C0C4CC;
    -webkit-transition: all .3s;
    transition: all .3s;
    line-height:32px
}
.transfer-panel-search-icon .el-input__icon {
    line-height:32px
}
.transfer-panel-list {
     100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    padding-left: 24px;
    line-height: 30px;
}
.transfer-panel-list ul {height:200px; overflow:auto}
.transfer-panel-list ul li {cursor:pointer;}
.transfer-panel-list ul li.cur{color:#00A99D}
.transfer__buttons{display:inline-block;margin:0px 20px}
</style>
原文地址:https://www.cnblogs.com/hellofangfang/p/13895026.html