最近,在做公司项目过程中,遇到了一个小需求,就是给客户选择套餐的某一种属性的时候,有些属性是有数值的,开始想用table去做但是太low,因为项目是用vuejs作为前端技术,element作为辅助ui,所以就想用element-ui的穿梭框来完成这样一件事情。
但是,穿梭框的功能有限,所以想到自己来改造一下他。先去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>
效果
好了,大概就这么一个思路,希望能帮到你们,第一次写博文,不喜勿喷啊。