vue+iview 自定义实现穿梭框

因业务需求iview穿梭框不满足业务需求自己写了个穿梭框。因本人是后端,请各位大佬看到了也可帮忙优化下。只实现了基本功能

表格及模态框代码

<Modal v-model="applyModel" closable title="发起申请" width="1260px" @on-cancel="cancelAppModel"	>
      <Form :model="applyModelForm" label-position="right" ref='applyModelForm' :rules="RuleValidateApply" :label-width="120">
        <FormItem v-if="buttonNumber == 3 || buttonNumber == 4 && applyModelForm.planId != null" label="查询学员"  >
          <Input type="text" clearable v-model="searchCardNumber" placeholder="学员身份证查询" style="width: 300px" @on-clear="clearInput" @on-change="changeInput" >
          </Input>
          <Button type="primary" @click="searchLeftData" style="margin-left: 10px;margin-top: 2px">查询</Button>
        </FormItem>
        <FormItem label="选择缴费学员"  v-if="applyModelForm.licenseType == null || applyModelForm.planId != null">
          <div class="transfreDiv" >
            <!--左边表格-->
            <Table size="small" :columns="columnsLeft" :data="dataLeft" width="600" height="350" style="margin-top: 10px;" @on-selection-change="changeSelectTableLeft">
            </Table>
            <div class="spacingOk" >
              <Button icon="el-icon-d-arrow-right" type="primary"  @click="addToRightTable" :disabled="addToRightList=='' "  >
                <Icon type="md-arrow-round-forward" />
                添加
              </Button>
            </div>
            <div class="spacing">
              <Button icon="el-icon-d-arrow-left" type="error" @click="addToLeftTable" :disabled="addToLeftList=='' ">
                <Icon type="md-arrow-round-back" />
                移除
              </Button>
            </div>
            <!--右边表格-->
            <Table ref="selection" size="small"  :columns="columnsRight" :data="dataRight" width="600" height="350" style="margin-top: 10px;
"@on-selection-change="changeSelectTableRight" >
              <template  slot-scope="{ row, index }" slot="countSlot">
                <Select  placeholder="****"   filterable v-model="row.count" style="width:100px"  @on-change="changeCount(row,index)" transfer >
                  <Option v-for="item in countS" :value="item.value" :key="item.value" >{{item.label}}</Option>
                </Select>
              </template>
              <template  slot-scope="{ row, index }" slot="actions">
                <Select transfer placeholder="选择费用"   filterable v-model="row.type" style="width:100px"   @on-change="changeCost(row,index)"  >
                  <Option v-for="item in moneyTypes" :value="item.value" :key="item.value" >{{item.label}}</Option>
                </Select>
              </template>
              <template  slot-scope="{ row, index }" slot="card">
                <Select transfer placeholder="****"   filterable v-model="row.isContainCard" style="width:100px"   @on-change="changeIsContainCard(row,index)"  >
                  <Option v-for="item in isContainCardS" :value="item.value" :key="item.value" >{{item.label}}</Option>
                </Select>
              </template>
              <template  slot-scope="{ row, index }" slot="RjType">
                <Select transfer placeholder="选择入**类型"   filterable v-model="row.rjType" style="width:100px"   @on-change="changeRjCost(row,index)"  >
                  <Option v-for="item in RjTypes" :value="item.value" :key="item.value" >{{item.label}}</Option>
                </Select>
              </template>
            </Table>
          </div>
        </FormItem>
        <div class="monny">
          <FormItem  label="备注" prop="remarks">
            <Input v-model="applyModelForm.remarks" type="textarea" placeholder="请填写备注信息" :maxlength="255" style="width: 300px" />
          </FormItem>
          <span style="margin-top: -60px;margin-left: 600px;font-size: 20px" >总金额:</span>
          <span style="margin-top: -60px;color: red;font-size: 20px">¥{{this.totalCost||0}}</span>
        </div>
      </Form>
      <div slot="footer" class="apply">
        <Button type="primary" @click="submitApplication" :loading="submitLoading" :disabled="dataRight == ''" >提交申请</Button>
        <Button >导出</Button>
        <Button >线下清单</Button>
      </div>
    </Modal>
data(){
        return {
          RjTypes:[
            {
              value:1,
              label:'......'
            },
            {
              value:2,
              label:'......'
            },
            {
              value:3,
              label:'.......'
            },
            {
              value:4,
              label:'.........'
            },
            {
              value:5,
              label:'...........'
            },
            {
              value:6,
              label:'..............'
            }
          ],
          countS:[
            {
              value: 1,
              label: '1'
            },
            {
              value: 2,
              label: '2'
            },
            {
              value: 3,
              label: '3'
            },
            {
              value: 4,
              label: '4'
            },
            {
              value: 5,
              label: '5'
            }
          ],
          moneyTypes:[
            {
              value: 4,
              label: '.........................'
            },
            {
              value: 6,
              label: '........................'
            },
            {
              value: 8,
              label: '......'
            }
          ],
          //....
          isContainCardS:[
            {
              value: 1,
              label: '包含'
            },
            {
              value: 2,
              label: '不包含'
            }
          ],
  
          //驾照类型下拉选
          // licenseTypes: [
          //   {
          //     value: 1,
          //     label: 'C1'
          //   },
          //   {
          //     value: 2,
          //     label: 'C2'
          //   },
          //   {
          //     value: 3,
          //     label: 'B2'
          //   }
          // ],
          applyModel:false,
          //放款模态框验证
          RuleValidateMakeLoans:{
            // credentialUrl: [
            //   {required: true, message: '放款凭证不能为空', trigger: 'change'},
            // ],
            accountId:[
              { required: true, message: '银行账户必选', trigger: 'change' ,type:'number'},
            ]
          },
          //发起申请验证
          RuleValidateApply:{
            planId:[
              { required: true, message: '考试计划不能为空', trigger: 'change' ,type:'number'},
            ],
            licenseType:[
              {required: true, message: '驾照类型不能为空', trigger: 'change',type:'number'},
            ],
            remarks:[
              {required: true, max: 255, message: '备注不能为空',type:'string'},
            ]
          },
          RuleValidateApplyNoPass:{
            content:[
              {required: true, max: 255, message: '备注不能为空',type:'string'}
            ]
          },
          RuleValidateApplyPass:{
            financialUserId:[
               { required: true, message: '审核人员必选', trigger: 'change' ,type:'number'},
            ],
            content:[
              {required: true, max: 255, message: '备注不能为空',type:'string'}
              ]
          },
          searchCardNumber:'',
          //发起申请时表单提交数据
          applyModelForm:{
            planId:null,
            licenseType:null,
            buttonNumber:null,
            cardNumber:'',
            count:null,
            remarks:'',
          },
          buttonNumber:0,
          columnsLeft:[
            {
              type: 'selection',
              key: 'index',
              width: 40,
              align: 'center'
            },
            {
              ellipsis:'true',
              tooltip:true,
              title: '姓名',
              key: 'name',
              width: 80,
              align: 'center'
            }
            ,{
              ellipsis:'true',
              tooltip:true,
              title: '身份证',
              width: 116,
              key: 'cardNumber',
              align: 'center'
            },{
              title: '次数',
              width: 65,
              key: 'count',
              align: 'center'
            },{
              title: '驾照',
              width: 80,
              key:'licenseType',
              align: 'center',
              render: (h, params) => {
                let rt = '';
                let value = params.row.licenseType;
                if (value == 1) {
                  rt = 'C1';
                } else if (value == 2) {
                  rt = 'C2';
                } else if (value == 3) {
                  rt = 'B2';
                }
                return h('span', rt);
              },
            }
            ,{
              ellipsis:'true',
              tooltip:true,
              title: '金额',
              width: 80,
              key: 'cost',
              align: 'center'
            },{
              ellipsis:'true',
              tooltip:true,
              title: '备注',
              width: 120,
              key: 'reason',
              align: 'center'
            }
          ],
          columnsRight:[
            {
              type: 'selection',
              key: 'index',
              width: 40,
              align: 'center'
            },
            {
              ellipsis:'true',
              tooltip:true,
              title: '姓名',
              key: 'name',
              width: 80,
              align: 'center'
            }
            ,{
              ellipsis:'true',
              tooltip:true,
              title: '身份证',
              width: 116,
              key: 'cardNumber',
              align: 'center'
            },{
              title: '次数',
              width: 125,
              slot:'countSlot',
              align: 'center'
            },{
              title: '驾照',
              width: 80,
              key:'licenseType',
              align: 'center',
              render: (h, params) => {
                let rt = '';
                let value = params.row.licenseType;
                if (value == 1) {
                  rt = 'C1';
                } else if (value == 2) {
                  rt = 'C2';
                } else if (value == 3) {
                  rt = 'B2';
                }
                return h('span', rt);
              },
            },{
              title: '类型',
              width: 125,
              slot: 'actions',
              align: 'center'
            },{
              title: '制卡费',
              width: 125,
              slot: 'card',
              align: 'center'
            },
            {
              title: '入籍类型',
              width: 125,
              slot: 'RjType',
              align: 'center'
            },
            {
              title: '金额',
              width: 100,
              key: 'cost',
              align: 'center'
            },
          ],
          dataLeft:[],
          dataRight:[],
          //添加左边勾选数据到右边集合中
          addToRightList:[],
          //左边点击勾选框时存入的数据
          resultLeftList:[],
          //右边点击勾选框时存入的index
          resultRightList:[],
          //添加右边数据到左边
          addToLeftList:[],
          //无限滚动时每次滚动加载数据条数
          length:5,
          selectStudentId:0,
          uploadData:{
            buttonNumber:0
          },
          searchDataLeft:[],
          searchAfterDataLeft:[],
        }
      },

打开模态框时操作

//点击发起申请
 clickApply(){
          this.$refs['applyModelForm'].resetFields();
          this.applyModelForm.planId=null
          this.applyModelForm.licenseType=null
          this.applyModelForm.cardNumber=''
          this.dataLeft=[]
          // this.deleteDataLeftList=[]
          this.resultLeftList=[]
          //清空右边表格
          this.dataRight=[]
          this.totalCost = null
          let leftArr =[
              {
                type: 'selection',
                key: 'index',
                width: 40,
                align: 'center'
              },
              {
                ellipsis:'true',
                tooltip:true,
                title: '姓名',
                key: 'name',
                width: 80,
                align: 'center'
              }
              ,{
                ellipsis:'true',
                tooltip:true,
                title: '身份证',
                width: 116,
                key: 'cardNumber',
                align: 'center'
              },{
                title: '次数',
                width: 65,
                key: 'count',
                align: 'center'
              },{
                title: '驾照',
                width: 80,
                key:'licenseType',
                render: (h, params) => {
                  let rt = '';
                  let value = params.row.licenseType;
                  if (value == 1) {
                    rt = 'C1';
                  } else if (value == 2) {
                    rt = 'C2';
                  } else if (value == 3) {
                    rt = 'B2';
                  }
                  return h('span', rt);
                },
                align: 'center'
              }
              ,{
                ellipsis:'true',
                tooltip:true,
                title: '金额',
                width: 80,
                key: 'cost',
                align: 'center'
              },{
              ellipsis:'true',
              tooltip:true,
              title: '备注',
              width: 120,
              key: 'reason',
              align: 'center'
              }
            ]
          let rightArr=[
            {
              type: 'selection',
              key: 'index',
              width: 40,
              align: 'center'
            },
            {
              ellipsis:'true',
              tooltip:true,
              title: '姓名',
              key: 'name',
              width: 80,
              align: 'center'
            }
            ,{
              ellipsis:'true',
              tooltip:true,
              title: '身份证',
              width: 116,
              key: 'cardNumber',
              align: 'center'
            },{
              title: '次数',
              width: 125,
              slot:'countSlot',
              align: 'center'
            },{
              title: '驾照',
              width: 80,
              key:'licenseType',
              align: 'center',
              render: (h, params) => {
                let rt = '';
                let value = params.row.licenseType;
                if (value == 1) {
                  rt = 'C1';
                } else if (value == 2) {
                  rt = 'C2';
                } else if (value == 3) {
                  rt = 'B2';
                }
                return h('span', rt);
              },
            },{
              title: '制卡费',
              width: 120,
              slot: 'card',
              align: 'center'
            },{
              title: '类型',
              width: 120,
              slot: 'actions',
              align: 'center'
            },{
              title: '入籍类型',
              width: 120,
              slot: 'RjType',
              align: 'center'
            },
            {
              title: '金额',
              width: 100,
              key: 'cost',
              align: 'center'
            },
          ]
          this.applyModel =true
          //根据按钮选择查询考试计划
          if(this.buttonNumber == 3 || this.buttonNumber == 4){
            getCostExamFiledList({buttonNumber:this.buttonNumber}).then(res => {
              this.planS = res
            })
          }
          this.columnsLeft = leftArr
          this.columnsRight =rightArr
          //如果按钮不是点击的代培费列表则不显示驾照类型和下拉选
          if(this.buttonNumber == 2 || this.buttonNumber == 3 || this.buttonNumber == 4 || this.buttonNumber == 7){
            this.columnsLeft.splice(4,1)
            this.columnsRight.splice(4,1)
            this.columnsRight.splice(4,1)
            this.columnsRight.splice(4,1)
            this.columnsRight.splice(4,1)
          }else if(this.buttonNumber == 1){
            this.columnsLeft.splice(3,1)
            this.columnsRight.splice(3,1)
            this.columnsRight.splice(4,1)
            this.columnsRight.splice(4,1)
          } else{
            this.columnsLeft.splice(3,1)
            this.columnsLeft.splice(4,1)
            this.columnsRight.splice(3,1)
            this.columnsRight.splice(6,1)
          }
        },

关闭模态框时操作

cancelAppModel(){
          this.applyModelForm.planId=null
          this.applyModelForm.licenseType=null
          this.applyModelForm.cardNumber=''
          this.searchCardNumber=''
          this.dataLeft=[]
          this.resultLeftList=[]
          this.addToRightList=[]
          this.dataRight=[]
          this.resultRightList=[]
          this.addToLeftList=[]
          this.$refs['applyModelForm'].resetFields();
},

点击查询

//点击搜索时
        searchLeftData(){
          this.searchDataLeft=[]
          if(this.searchCardNumber==''){
            return this.$Message.error("请先输入学员身份证号")
          }
          this.dataLeft.forEach(item=>{
            //如果循环出来的某个对象的身份证号和输入的相同
            if(item.cardNumber==this.searchCardNumber){
             this.searchDataLeft.push(item)
            }
          })
          this.dataLeft=this.searchDataLeft
        },```

点击添加时处理

```javascript
//点击添加按钮
addToRightTable(){
  this.addToRightList.forEach((item,index)=>{
    this.dataRight.unshift(item)
  })
  this.dataLeft=this.resultLeftList
  //添加到右侧集合后计算总金额
  let int=0
  this.dataRight.forEach((item,index)=>{
    int += item.cost
  })
  this.totalCost=int
  //清空获取到的下标集合
  this.resultLeftList=[]
  //清空左侧集合中选中的需要添加到右侧集合的数据
  this.addToRightList=[]
},

左边表格出现改变时代码

//左侧表格多选框出现变化时处理
changeSelectTableLeft(selection){
  this.addToRightList=selection
  let a=this.addToRightList;
  let b=this.dataLeft
  let arr1 = [...b].filter(x => [...a].every(y => y.studentId !== x.studentId));//es6语法查询交集
  this.resultLeftList=arr1
},

将选中数据添加到左边表格移除按钮

 //添加到左边表格
addToLeftTable(){
 //添加数据到左侧集合中
 this.addToLeftList.forEach((item,index)=>{
   this.dataLeft.unshift(item)
 })
 this.dataRight=this.resultRightList
 //添加到右侧集合后计算总金额
 let int=0
 this.dataRight.forEach((item,index)=>{
   int += item.cost
 })
 this.totalCost=int
 //清空获取到的取出差集的集合
 this.resultRightList=[]
 //清空左侧集合中选中的需要添加到右侧集合的数据
 this.addToLeftList=[]
},

右边表格的多选框发生改变时操作

changeSelectTableRight(selection){
  this.addToLeftList=selection
  let a=this.addToLeftList;
  let b=this.dataRight
  let arr1 = [...b].filter(x => [...a].every(y => y.studentId !== x.studentId));
  this.resultRightList=arr1
},

在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完成后效果,代码删除较多只保留了基本的穿梭框功能。

Logo

前往低代码交流专区

更多推荐