npm install vuedraggable --save
vue
<template> <a-form layout="vertical"> <a-form-item label="模板" > <a-transfer show-search :data-source="tableFieldSource" :target-keys="targetKeys" :list-style="{ width: 'calc(50% - 30px)', height: '300px' }" :titles="['未导出的字段','导出的字段']" :render="item => item.title || ''" :filter-option="(str, {description})=>{ return description.indexOf(str)>-1 }" @change="handleFieldKeyChange" > <template slot="children" slot-scope="{ props: { direction, filteredItems, selectedKeys, disabled: listDisabled }, on: { itemSelectAll, itemSelect }, }" > <div class="container"> <draggable class="list-group" :list="filteredItems" group="people" dragClass="list-group-select" @update="draggableUpdate($event,direction)" @remove="draggableRemove($event,direction)" @add="draggableAdd($event,direction,filteredItems)"> <div class="list-group-item" v-for="(element, index) in filteredItems" :key="element.key" > <span :style="{ pointerEvents: listDisabled ? 'none' : null }"> <a-checkbox :checked="checkTag(element,selectedKeys)" v-model="element.check" @change="tableFieldSourceChange(element.check,element.key,selectedKeys)"/> <span class="list-group-item-span">{{ element.title }}</span> <a-icon v-if="direction ==='right' && index!==0" type="vertical-align-top" style="color: #666;float: right;margin-right: 15px" title="置顶" @click="()=>{draggableTop(index,direction)}" /> </span> </div> </draggable> </div> </template> </a-transfer> </a-form> </template> <script> import {RESULT_SUCCESS_CODE} from "@/utils/gobalConstants"; import draggable from 'vuedraggable' export default { name: 'ExportView', components: { draggable }, props: { fields: { type: Array, default() { return [] } }, viewList: { type: Array, default() { return [] } }, moduleName: { type: String, default: "" } }, data() { return { targetKeys: [], tableFieldSource: [], conditionFields: [], //过滤字段 filterListHeight: window.innerHeight - 760, // 过滤条件区域高度 viewName: '', viewId: null, dataSourceFields: this.fields, cutExportBtn: true, delExist: false, optionDataSource: [], } }, computed: {}, watch: {}, mounted() { this.init(); }, methods: { async init() { this.tableFieldSource = this.tableFieldSourceGet(); this.customExportChange(); await this.fetchExportViewList(); }, tableFieldSourceGet() { const {dataSourceFields} = this if (dataSourceFields && dataSourceFields.length) { return dataSourceFields.map(i => { return { key: i.field, title: i.title, description: `${i.field}${i.title}`, } }) } return [] }, refreshValue() { this.targetKeys = []; }, filterOption(inputValue, option) { return option.description.indexOf(inputValue) > -1; }, handleChange(targetKeys, direction, moveKeys) { this.targetKeys = targetKeys; }, handleSearch(dir, value) { }, // 筛选值变化 handleFieldKeyChange(targetKeys) { this.targetKeys = targetKeys; }, //自定义导出 customExportChange() { if (this.cutExportBtn) { const {dataSourceFields} = this; this.targetKeys = dataSourceFields.filter(m => m.visible == true).map(i => { return i.field }); } else { this.targetKeys = []; } }, tableFieldSourceChange(e, key, selectedKeys) { if (e) { selectedKeys.push(key); } else { selectedKeys.splice(key, 1); } }, checkTag(el, keyArr) { el.check = keyArr.includes(el.key); return keyArr.includes(el.key) }, draggableUpdate(e, t) { if (t === "left") { const l = this.targetKeys.length; this.swapArrayElements(this.tableFieldSource, e.oldIndex + l, e.newIndex + l); } else { this.swapArrayElements(this.targetKeys, e.oldIndex, e.newIndex); } }, //移动到另外的元素 draggableRemove(e, t) { if (t === "right") { this.targetKeys.splice(e.oldIndex, 1); } }, draggableAdd(e, t) { const targetKeys = _.cloneDeep(this.targetKeys); if (t === "right") { const element = this.removeRightArr()[e.oldIndex]; targetKeys.push(element.key); this.swapArrayElements(targetKeys, targetKeys.length - 1, e.newIndex); this.targetKeys = targetKeys; } }, draggableTop(index) { this.swapArrayElements(this.targetKeys, index, 0) }, swapArrayElements(arr, indexA, indexB) { arr.splice(indexB, 0, arr.splice(indexA, 1)[0]); }, removeRightArr() { const source = _.cloneDeep(this.tableFieldSource); const targetKeys = this.targetKeys; for (let targetKey of targetKeys) { const number = source.findIndex(m => m.key === targetKey); if (number !== -1) { source.splice(number, 1); } } return source; } } } </script> <style lang="less" scoped> .ghost { opacity: 0.5; background: #c8ebfb; } .list-group { display: flex; flex-direction: column; padding-left: 0; margin-bottom: 0; width: 300px; .list-group-item { cursor: move; position: relative; display: block; background-color: #fff; line-height: 24px } .list-group-item-span { padding-left: 12px } } .list-group-select { } .container { height: 200px; overflow: auto; overflow-x: hidden; } </style>
标签:vue,return,title,transfer,dataSourceFields,ant,key,targetKeys,const From: https://www.cnblogs.com/keenonwt/p/18027421