美文网首页Element UI
改造ElementUI穿梭框

改造ElementUI穿梭框

作者: GavinSir | 来源:发表于2018-02-08 16:58 被阅读2859次

最近,在做公司项目过程中,遇到了一个小需求,就是给客户选择套餐的某一种属性的时候,有些属性是有数值的,开始想用table去做但是太low,因为项目是用vuejs作为前端技术,element作为辅助ui,所以就想用element-ui的穿梭框来完成这样一件事情。

image

但是,穿梭框的功能有限,所以想到自己来改造一下他。先去github上看一下element的源码:https://github.com/ElemeFE/element

进入目录 element/packages/transfer/src,把里面的两个文件拷贝出来,先解读一下源码,其实穿梭框中可定制的地方可以很多,看你的脑洞有多大,我根据需求,给每一项添加一个计数器,首先什么样的数据需要计数器,

改造 transfer-panel

在transfer-panel.vue设定来几个属性:isNumber,Number,minNumber,maxNumber,tooltip,isShowInput,panelWidth。

Script

props: {
      data: {
        type: Array,
        default() {
          return [];
        }
      },
      isShowInput:false,
      panelWidth:{
          type:Number,
          default(){
              return 200
          }
      },
      renderContent: Function,
      placeholder: String,
      title: String,
      filterable: Boolean,
      format: Object,
      filterMethod: Function,
      defaultChecked: Array,
      props: Object
    }
computed:{

      isNumberProp(){

        return this.props.isNumber || 'isNumber';

      },

      NumberProp(){

        return this.props.Number || 'Number';

      },

      MinNumberProp(){

        return this.props.usedMin || 'usedMin'

      },

      MaxNumberProp(){

        return this.props.usedMax || 'usedMax'

      },

      tooltipProp(){

        return this.props.tooltip || 'tooltip';

      },

}

Template

<el-checkbox-group
        v-model="checked"
        v-show="!hasNoMatch && data.length > 0"
        :class="{ 'is-filterable': filterable }"
        class="el-transfer-panel__list">
        <el-checkbox
          class="el-transfer-panel__item"
          :label="item[keyProp]"
          :disabled="item[disabledProp]"
          :key="item[keyProp]"
          v-for="item in filteredData">
          <option-content :option="item"></option-content>
          <el-tooltip v-if="item[isNumberProp] && isShowInput"  class="item" effect="dark" :content="item[labelProp]+'('+item[tooltipProp]+')'" placement="top">
           <el-input-number class="fr m-r-5" v-model="item[NumberProp]" size="small" style="width:100px!important" controls-position="right" :min="item[MinNumberProp]" :max="item[MaxNumberProp]" :label="item[tooltipProp]"></el-input-number>
          </el-tooltip>
        </el-checkbox>
      </el-checkbox-group>

属性描述,其余属性继承ElmentUI的穿梭框

http://element-cn.eleme.io/#/zh-CN/component/transfer

属性 描述
isNumber 是否为数值类型
Number 数值,v-model绑定
minNumber 最小值
maxNumber 最大值
tooltip 提示框内容
isShowInput 是否显示计数器input
panelWidht 宽度

改造 Index.vue

Script

props:{
      panelWidth: Number,
      isShowLeftInput: Boolean,
      isShowRightInput: Boolean,
}

Template

<div class="el-transfer">
    <transfer-panel
      v-bind="$props"
      :data="sourceData"
      :title="titles[0]"
      :panelWidth="panelWidth"
      :isShowInput="isShowLeftInput"
      :default-checked="leftDefaultChecked"
      :placeholder="filterPlaceholder"
      @checked-change="onSourceCheckedChange">
      <slot name="left-footer"></slot>
    </transfer-panel>
    <div class="el-transfer__buttons">
      <el-button
        type="primary"
        :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
        @click.native="addToLeft"
        :disabled="rightChecked.length === 0">
        <i class="el-icon-arrow-left"></i>
        <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span>
      </el-button>
      <el-button
        type="primary"
        :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
        @click.native="addToRight"
        :disabled="leftChecked.length === 0">
        <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
        <i class="el-icon-arrow-right"></i>
      </el-button>
    </div>
    <transfer-panel
      v-bind="$props"
      :data="targetData"
      :title="titles[1]"
      :panelWidth="panelWidth"
      :isShowInput="isShowRightInput"
      :default-checked="rightDefaultChecked"
      :placeholder="filterPlaceholder"
      @checked-change="onTargetCheckedChange">
      <slot name="right-footer"></slot>
    </transfer-panel>

属性描述

属性 类型 描述
panelWidht Number 宽度
isShowLeftInput Boolean 是否显示左侧计数器
isShowRightInput Boolean 是否显示右侧计数器

使用

import CusTransfer from "@/components/customer/Transfer/index"
<cus-transfer 
        v-model="selectedElements" 
        :data="elements" 
        :titles="['备选', '已选']" 
        :panelWidth="300" 
        :isShowLeftInput="false" 
        :isShowRightInput="true">
</cus-transfer>

效果

image.png
image.png

好了,大概就这么一个思路,希望能帮到你们,第一次写博文,不喜勿喷啊

相关文章

网友评论

  • bccc9ae5070a:大佬 怎么修改这个穿梭框 成为左边是两个列表联动,右边是现在这样的呢?
  • 柚子胖鸡_:有个问题,就是点击加减数量的时候 ,那个复选框也会被触发 怎么解决啊
    GavinSir:@Console_Iog 这个我还没改,我也有这个问题,暂时还没有时间去改,思路就是改造list里面的item元素。你可以试试
    柚子胖鸡_:就是点击穿透了
  • 任建堃:大佬,关于transfer我有个问题想请教一下,怎么异步加载transfer里面的数据啊。比如我把table组件和transfer组件合并在一起然后点击table组件的时候会请求后台,然后把请求到的数据加载在transfer的列表里面
  • 之子于归a:大佬,我想设置transfer宽度,在源码中改无效,直接用.class覆盖也无效,怎么解决
    GavinSir:@之子于归a transfer其实是两个组件组成的,你得在源码中设置单个panelWidth的宽度。
    <transfer-panel
    v-bind="$props"
    :data="sourceData"
    :title="titles[0]"
    :panelWidth="panelWidth"
    :isShowInput="isShowLeftInput"
    :default-checked="leftDefaultChecked"
    :placeholder="filterPlaceholder"
    @checked-change="onSourceCheckedChange">
    <slot name="left-footer"></slot>
    </transfer-panel>
    而且还可以自定义其他属性

本文标题:改造ElementUI穿梭框

本文链接:https://www.haomeiwen.com/subject/iebttftx.html