vue3+elementPlus穿梭框单个拖拽和全选拖拽
安装 sortablejs
npm install sortablejs --save
<template><div class="transferBox"><el-transfer ref="transfer" v-model="inputForm.workingProcedure" :titles="titles"target-order="push" :props="transferProps" :data="transferData" @left-check-change="leftCheckChange"@right-check-change="rightCheckChange"><template #default="{ option }"><div class="pannel-content"><span :draggable="!option.disabled" @dragstart="drag($event, option)">{{ option.label}}</span></div></template></el-transfer><el-button @click="submit">确定</el-button></div>
</template><script setup lang="ts">
import { TransferDataItem } from 'element-plus';
import Sortable from 'sortablejs';
const props = withDefaults(defineProps<{data: TransferDataItem[],titles?: [string, string]
}>(), {data: () => [{ id: '1', label: '测试1', disabled: true },{ id: '2', label: '测试2', disabled: false },{ id: '3', label: '测试3', disabled: false },{ id: '4', label: '测试4', disabled: false }],titles: () => ['多个拖拽未选择', '已选择']
})
const transferData = computed(() => props.data);
const titles = computed(() => props.titles)
const transferLeftCheckData = ref<string[]>([]);
const transferRightCheckData = ref<string[]>([]);
const draggingKey = ref<string>('');
const inputForm = ref({ workingProcedure: [] });
const transferProps = ref({ key: 'id', label: 'label' });const transfer = ref(null);const drag = (ev: DragEvent, option: any) => {console.log(option);draggingKey.value = option.id;
};const leftCheckChange = (val: string[]) => {transferLeftCheckData.value = val;
};const rightCheckChange = (val: string[]) => {transferRightCheckData.value = val;
};
function submit() {console.log(inputForm.value.workingProcedure);
}
onMounted(() => {const transferEl = transfer.value?.$el;if (!transferEl) return;const leftPanel = transferEl.getElementsByClassName('el-transfer-panel')[0].getElementsByClassName('el-transfer-panel__body')[0];const rightPanel = transferEl.getElementsByClassName('el-transfer-panel')[1].getElementsByClassName('el-transfer-panel__body')[0];const rightEl = rightPanel.getElementsByClassName('el-transfer-panel__list')[0];Sortable.create(rightEl, {onEnd: (evt) => {const { oldIndex, newIndex } = evt;const temp = inputForm.value.workingProcedure[oldIndex];if (!temp || temp === 'undefined') return;inputForm.value.workingProcedure[oldIndex] = inputForm.value.workingProcedure[newIndex];inputForm.value.workingProcedure[newIndex] = temp;},});const leftEl = leftPanel.getElementsByClassName('el-transfer-panel__list')[0];Sortable.create(leftEl, {onEnd: (evt) => {const { oldIndex, newIndex } = evt;const temp = transferData.value[oldIndex];if (!temp || temp === 'undefined') return;transferData.value[oldIndex] = transferData.value[newIndex];transferData.value[newIndex] = temp;},});leftPanel.ondragover = (ev) => ev.preventDefault();leftPanel.ondrop = (ev) => {ev.preventDefault();const index = inputForm.value.workingProcedure.indexOf(draggingKey.value);if (index !== -1) {if (transferRightCheckData.value.indexOf(draggingKey.value) !== -1) {transferRightCheckData.value.reduce((arr, item) => {if (arr.indexOf(item) !== -1) {arr.splice(arr.indexOf(item), 1);}return arr;}, inputForm.value.workingProcedure)// 清除右侧选中的 不然下次向左拉取时会有缓存transferRightCheckData.value = [];} else {// 否则就只拉取当前一个inputForm.value.workingProcedure.splice(index, 1);}}};rightPanel.ondragover = (ev) => ev.preventDefault();rightPanel.ondrop = (ev) => {ev.preventDefault();if (inputForm.value.workingProcedure.indexOf(draggingKey.value) === -1) {if (transferLeftCheckData.value.indexOf(draggingKey.value) !== -1) {inputForm.value.workingProcedure = inputForm.value.workingProcedure.concat(transferLeftCheckData.value);transferLeftCheckData.value = [];} else {// 否则就只拉取当前一个inputForm.value.workingProcedure.push(draggingKey.value);}}};
});
</script>
<style scoped lang="scss">
:deep(.el-transfer__button) {width: 30px;
}
</style>