dd
This commit is contained in:
110
src/components/SortableComponentSelector.vue
Normal file
110
src/components/SortableComponentSelector.vue
Normal file
@ -0,0 +1,110 @@
|
||||
<script setup lang="ts">
|
||||
import Sortable from 'sortablejs';
|
||||
|
||||
interface ComponentItem {
|
||||
id: number | string;
|
||||
name: string;
|
||||
}
|
||||
interface SelectorState {
|
||||
组件列表: ComponentItem[];
|
||||
已选流程ID: (number | string)[];
|
||||
}
|
||||
const props = defineProps<{
|
||||
state: SelectorState;
|
||||
}>();
|
||||
|
||||
const 流程起点列表 = ref<ComponentItem[]>([]);
|
||||
// const 流程终点列表 = ref<ComponentItem[]>([]);
|
||||
|
||||
const 源列表引用 = useTemplateRef<HTMLDivElement | null>('源列表引用');
|
||||
const 起点列表引用 = useTemplateRef<HTMLDivElement | null>('起点列表引用');
|
||||
// const 终点列表引用 = useTemplateRef<HTMLDivElement | null>('终点列表引用');
|
||||
|
||||
const 组件列表 = computed(() => props.state.组件列表);
|
||||
|
||||
onMounted(() => {
|
||||
if (!源列表引用.value || !起点列表引用.value /* || !终点列表引用.value */) {
|
||||
consola.error('未能获取到 SortableJS 容器元素');
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化源列表
|
||||
Sortable.create(源列表引用.value, {
|
||||
group: {
|
||||
name: 'components',
|
||||
pull: 'clone', // 允许克隆
|
||||
put: false, // 不允许拖入
|
||||
},
|
||||
sort: false, // 源列表内不允许排序
|
||||
// 将 data-id 附加到拖拽数据中,供目标列表识别
|
||||
setData: (dataTransfer, dragEl) => {
|
||||
if (!dragEl.dataset.id) {
|
||||
consola.error('拖拽元素未包含 data-id');
|
||||
return;
|
||||
}
|
||||
dataTransfer.setData('text/plain', dragEl.dataset.id);
|
||||
},
|
||||
});
|
||||
|
||||
// 初始化流程起点列表
|
||||
Sortable.create(起点列表引用.value, {
|
||||
group: {
|
||||
name: 'flowPoints', // 修改为新的组名,用于区分"流程点"和普通组件
|
||||
pull: true, // 允许拖出
|
||||
put: ['components'], // 允许接收的组
|
||||
},
|
||||
draggable: '.DRAG-ITEM', // 只有带 .DRAG-ITEM 的元素才能被拖动
|
||||
onAdd: (evt) => {
|
||||
const itemId = Number.parseInt(evt.item.dataset.id || '0', 10);
|
||||
consola.info(`从 [${evt.from.dataset.name}] 拖入到 [${evt.to.dataset.name}],itemId: ${itemId}`);
|
||||
},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex gap-5 p-5 bg-[#1a1a1a] text-[#e0e0e0] font-sans min-h-100">
|
||||
<!-- 组件选择区域 -->
|
||||
<div class="flex-1 p-4 rounded">
|
||||
<h3 class="text-center mb-5 text-white font-bold">组件选择</h3>
|
||||
<div ref="源列表引用" class="flex flex-col gap-2 bg-[#2a2a2a] p-4 rounded" data-name="组件选择区域">
|
||||
<div class="DRAG-ITEM" v-for="item in 组件列表" :key="item.id" :data-id="item.id">
|
||||
<AButton class="min-h-50px">
|
||||
{{ item.name }}
|
||||
</AButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 构建流程区域 -->
|
||||
<div class="flex-1 p-4 rounded">
|
||||
<h3 class="text-center mb-5 text-white font-bold">构建流程</h3>
|
||||
<div class="flex items-start mb-2.5">
|
||||
<div class="w-20 text-right mr-2.5 pt-2.5 text-[#ccc]">流程起点:</div>
|
||||
<div ref="起点列表引用" data-name="流程起点区域" class="TARGET-AREA">
|
||||
<div
|
||||
v-if="流程起点列表.length === 0"
|
||||
class="flex justify-center items-center h-full min-h-130px text-[#888] text-center placeholder"
|
||||
>
|
||||
请拖入组件构成流程起点
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.placeholder {
|
||||
/* 默认隐藏的 */
|
||||
display: none;
|
||||
}
|
||||
.TARGET-AREA {
|
||||
@apply flex-1 min-h-150px rounded p-2.5 border-2 border-dashed border-[#555] bg-[#2a2a2a] mt-1.25 mb-5;
|
||||
}
|
||||
/* target-area 的最后一个 .placeholder 元素 */
|
||||
.TARGET-AREA > .placeholder:last-child {
|
||||
/* 显示 */
|
||||
display: block;
|
||||
}
|
||||
</style>
|
18
src/pages/PkgsUsage/SortableJSComps.page.vue
Normal file
18
src/pages/PkgsUsage/SortableJSComps.page.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
const state = reactive({
|
||||
组件列表: [
|
||||
{ id: 1, name: '组件1' },
|
||||
{ id: 2, name: '组件2' },
|
||||
{ id: 3, name: '组件3' },
|
||||
],
|
||||
已选流程ID: [],
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<SortableComponentSelector :state="state" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
Reference in New Issue
Block a user