新建穿梭组件 bTransfer.vue
1 <template> 2 <div class="bpo-table-transfer"> 3 <div class="bpo-table-transfer-panel"> 4 <p class="transfer-panel-header"> 5 <span>{{ titleTexts && titleTexts[0] }}</span> 6 <span>{{ leftSelection.length }}/{{ slicedData.length }}</span> 7 </p> 8 <div class="bpo-table-transfer-left-header"> 9 <slot name="left-header" /> 10 </div> 11 <el-table ref="leftTable" size="small" :max-height="maxHeight" :height="minHeight" :data="slicedData" 12 :row-key="rowKey" @selection-change="handleLeftSelectionChange" border stripe> 13 <el-table-column width="40px" type="selection" /> 14 <slot name="left-table-columns" /> 15 </el-table> 16 <slot name="left-footer" /> 17 </div> 18 <div class="bpo-table-transfer-button-tray"> 19 <el-button type="primary" :class="buttonClasses" :disabled="disabledLeftButton" @click="addToRight"> 20 <span v-if="buttonTexts[0] !== undefined" class="button-text">{{ buttonTexts[0] }}</span> 21 <i class="el-icon-arrow-right"></i> 22 </el-button> 23 <el-button type="primary" :class="buttonClasses" :disabled="rightSelection.length === 0" @click="addToLeft"> 24 <i class="el-icon-arrow-left"></i> 25 <span v-if="buttonTexts[1] !== undefined" class="button-text">{{ buttonTexts[1] }}</span> 26 </el-button> 27 </div> 28 <div class="bpo-table-transfer-panel"> 29 <p class="transfer-panel-header"> 30 <span>{{ titleTexts && titleTexts[1] }}</span> 31 <span>{{ rightSelection.length }}/{{ valueCopy.length }}</span> 32 </p> 33 <div class="bpo-table-transfer-right-header"> 34 <slot name="right-header" /> 35 </div> 36 37 <el-table ref="rightTable" size="small" :max-height="maxHeight" :height="minHeight" :data="valueCopy" 38 :row-key="rowKey" @selection-change="handleRightSelectionChange" border stripe> 39 <el-table-column width="40px" type="selection" /> 40 <slot name="right-table-columns" /> 41 </el-table> 42 <slot name="right-footer"> 43 <el-pagination style="float: right;margin: 5px;" :total="valueCopy.length" layout="total"> 44 </el-pagination> 45 </slot> 46 </div> 47 </div> 48 </template> 49 50 <script> 51 import _ from "lodash"; //引用 loadsh 52 export default { 53 name: 'BpoEltTransfer', 54 props: { 55 value: { 56 type: Array, 57 required: true 58 }, 59 data: { 60 type: Array, 61 default() { 62 return [] 63 } 64 }, 65 rowKey: { 66 type: String, 67 default: 'id' 68 }, 69 // 标题文本 70 //TODO: i18n 71 titleTexts: { 72 type: Array, 73 default() { 74 return ['待选项', '已选项'] 75 } 76 }, 77 // 按钮文本 78 buttonTexts: { 79 type: Array, 80 default() { 81 return [] 82 } 83 }, 84 // 表格最小高度 85 minHeight: { 86 type: String, 87 default: '300px' 88 }, 89 // 表格最大高度 90 maxHeight: { 91 type: String, 92 default: '500px' 93 } 94 }, 95 data() { 96 return { 97 valueCopy: [...this.value], 98 totalSize: 0, 99 leftSelection: [], 100 rightSelection: [] 101 } 102 }, 103 computed: { 104 hasButtonTexts() { 105 return this.buttonTexts.length === 2 106 }, 107 buttonClasses() { 108 return ['transfer-button', { 'is-with-texts': this.hasButtonTexts }] 109 }, 110 disabledLeftButton() { 111 return !this.leftSelection.some(leftRow => !this.value.some(rightRow => leftRow[this.rowKey] === rightRow[this.rowKey])) 112 }, 113 slicedData() { 114 return this.data.filter(item => !this.valueCopy.some(o => o[this.rowKey] === item[this.rowKey])) 115 } 116 }, 117 methods: { 118 handleLeftSelectionChange(selection) { 119 this.leftSelection = selection 120 }, 121 handleRightSelectionChange(selection) { 122 this.rightSelection = selection 123 }, 124 addToRight() { 125 this.valueCopy.push(...this.leftSelection) 126 this.$emit('input', this.valueCopy) 127 128 }, 129 addToLeft() { 130 //差集 _.xorWith 需要npm install lodash
131 this.valueCopy = _.xorWith(this.rightSelection, this.valueCopy) 132 this.$emit('input', this.valueCopy) 133 console.log(this.valueCopy) 134 } 135 } 136 } 137 </script> 138 139 <style scoped> 140 .bpo-table-transfer { 141 font-size: 14px; 142 display: flex; 143 justify-content: center; 144 align-items: center; 145 } 146 147 .el-icon-arrow-right, 148 .el-icon-arrow-left { 149 font-size: 40px; 150 cursor: pointer; 151 } 152 153 .bpo-table-transfer-panel { 154 border: 1px solid #EBEEF5; 155 border-radius: 4px; 156 overflow: hidden; 157 background: #FFF; 158 display: inline-block; 159 width: calc((100% - 100px) / 2); 160 max-height: 100%; 161 box-sizing: border-box; 162 position: relative 163 } 164 165 .bpo-table-transfer-panel .transfer-panel-header { 166 height: 40px; 167 line-height: 40px; 168 background: #F5F7FA; 169 margin: 0; 170 padding-left: 15px; 171 border-bottom: 1px solid #EBEEF5; 172 -webkit-box-sizing: border-box; 173 box-sizing: border-box; 174 color: #000; 175 } 176 177 .transfer-panel-header span:last-child { 178 position: absolute; 179 right: 15px; 180 } 181 182 .bpo-table-transfer-button-tray { 183 display: inline-block; 184 vertical-align: middle; 185 width: 100px; 186 } 187 188 .transfer-button { 189 display: block; 190 margin: 0 auto; 191 padding: 10px; 192 border-radius: 4px; 193 color: #FFF; 194 background-color: #409EFF; 195 font-size: 0; 196 } 197 198 .transfer-button .button-text { 199 margin-left: 2px; 200 margin-right: 5px; 201 } 202 203 .transfer-button.is-with-texts { 204 border-radius: 4px; 205 } 206 207 .transfer-button.is-disabled, 208 .transfer-button.is-disabled:hover { 209 border: 1px solid #DCDFE6; 210 background-color: #F5F7FA; 211 color: #C0C4CC; 212 } 213 214 .transfer-button:first-child { 215 margin-bottom: 10px; 216 } 217 218 .transfer-button:nth-child(2) { 219 margin: 0 auto; 220 } 221 222 .transfer-button i, 223 .transfer-button span { 224 font-size: 14px; 225 } 226 227 .bpo-table-transfer-left-header { 228 padding: 10px; 229 } 230 .bpo-table-transfer-right-header { 231 padding: 10px; 232 } 233 </style>
使用穿梭组件
1 <template> 2 <bpo-elt-transfer 3 :title-texts="['待选择','已选择']" 4 min-height="300" 5 max-height="600" 6 row-key="userId" 7 :data="pageInfo.list" 8 v-model="selectedUsers" 9 > 10 <template #left-header> 11 <el-row :gutter="20"> 12 <el-col :span="8"><span>姓名:</span></el-col> 13 <el-col :span="8"><span>通讯:</span></el-col> 14 15 </el-row> 16 <el-row :gutter="20"> 17 <el-col :span="8"> 18 <el-input v-model="searchForm.userName" size="mini" clearable/> 19 </el-col> 20 <el-col :span="8"> 21 <el-input v-model="searchForm.email" size="mini" clearable/> 22 </el-col> 23 <el-col :span="5"> 24 <el-button style="width: 100px" type="primary" size="mini" @click="handleSearch()"><span>检索</span> 25 </el-button> 26 </el-col> 27 </el-row> 28 </template> 29 <template #left-table-columns> 30 <el-table-column 31 label="id" 32 align="left" 33 prop="userId" 34 header-align="center" 35 show-overflow-tooltip 36 :min-width="100" 37 /> 38 <el-table-column 39 :resizable="false" 40 align="left" 41 header-align="center" 42 label="姓名" 43 prop="userName" 44 show-overflow-tooltip 45 min-width="100"> 46 </el-table-column> 47 <el-table-column 48 label="通讯" 49 align="left" 50 prop="email" 51 header-align="center" 52 show-overflow-tooltip 53 :min-width="100" 54 /> 55 </template> 56 <template #left-footer> 57 <el-pagination style="float: right;margin: 5px;" 58 @current-change="handleCurrentChange" 59 :current-page="pageInfo.pageNum" 60 :page-size="pageInfo.pageSize" 61 layout="total, prev, pager, next, jumper" 62 :total="pageInfo.total"> 63 </el-pagination> 64 </template> 65 <template #right-table-columns> 66 <el-table-column 67 label="id" 68 align="left" 69 prop="userId" 70 header-align="center" 71 show-overflow-tooltip 72 :min-width="100" 73 /> 74 <el-table-column 75 :resizable="false" 76 align="left" 77 header-align="center" 78 label="姓名" 79 prop="userName" 80 show-overflow-tooltip 81 min-width="100"> 82 </el-table-column> 83 <el-table-column 84 label="通讯" 85 align="left" 86 prop="email" 87 header-align="center" 88 show-overflow-tooltip 89 :min-width="100" 90 /> 91 </template> 92 </bpo-elt-transfer> 93 </template> 94 95 <script> 96 export default { 97 name: 'TransferExample', 98 data() { 99 return { 100 searchForm: { 101 userName: '', 102 email: '' 103 }, 104 selectedUsers: [], 105 pageInfo: { 106 list: [ 107 { 108 "userId": "00R43K", 109 "userName": "test4", 110 "email": "[email protected]" 111 }, 112 { 113 "userId": "1B5BQY", 114 "userName": "test2", 115 "email": "[email protected]" 116 }, 117 { 118 "userId": "4K091Y", 119 "userName": "test3", 120 "email": "[email protected]" 121 }, 122 { 123 "userId": "admin", 124 "userName": "Admin", 125 "email": "[email protected]" 126 }, 127 { 128 "userId": "demo01", 129 "userName": "Demo01", 130 "email": "[email protected]" 131 }, 132 { 133 "userId": "SO1351", 134 "userName": "qwqwq", 135 "email": "[email protected]" 136 } 137 ], 138 pageNum: this.$PAGE_NUM, 139 pageSize: this.$PAGE_SIZE, 140 total: 0 141 } 142 } 143 }, 144 methods: { 145 handleSearch(searchCondition) { 146 this.axios.post('/api/available-user', { 147 pageNum: this.$PAGE_NUM, 148 pageSize: this.$PAGE_SIZE, 149 organizationCode: this.userMapping.organizationCode, 150 ...this.searchForm, 151 ...searchCondition 152 }) 153 .then(({data}) => { 154 this.pageInfo = data.retResult 155 }) 156 }, 157 handleCurrentChange(val) { 158 this.handleSearch({ 159 pageNum: val, 160 pageSize: this.pageInfo.pageSize 161 }) 162 } 163 } 164 } 165 </script>
Attributes
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
value / v-model | 绑定值 | array | — |
data | 候选池(左表)的数据源 | array | [] |
button-texts | 自定义标题文案 | array | ['待选项', '已选项'] |
title-texts | 自定义按钮文案 | array | ['',''] |
min-height | 表格最小高度 | string | 300px |
max-height | 表格最大高度 | string | 500px |
row-key | 表格行数据的Key | string | id |
Slot
名称 | 说明 |
---|---|
left-header | 自定义左表header |
left-footer | 自定义左表footer |
left-table-columns | 左表的列,参照原生el-table-colum 使用 |
left-header | 自定义右表header |
left-footer | 自定义右表footer, 默认内容为一个右格行数统计 |
left-table-columns | 右表的列,参照原生el-table-colum 使用 |
转自:https://github.com/SonicMiso/bpo-elt-transfer
标签:vue,return,表格,transfer,button,穿梭,table,border,left From: https://www.cnblogs.com/L-hailong/p/17381187.html