20260729231854
This commit is contained in:
1 parent
1c839b707a
commit
84673b3d3d
39 files changed
+4683
-281
No files matched your search
@@ -1,22 +1,93 @@
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
import { computed, ref, useAttrs, watch } from "vue";
|
||||
|
||||
defineOptions({ inheritAttrs: false });
|
||||
|
||||
const attrs = useAttrs();
|
||||
const handledEventAttrs = new Set([
|
||||
"onDrop",
|
||||
"onDragStart",
|
||||
"onDragstart",
|
||||
"onDragEnter",
|
||||
"onDragenter",
|
||||
"onDragLeave",
|
||||
"onDragleave",
|
||||
"onDragOver",
|
||||
"onDragover",
|
||||
"onDragEnd",
|
||||
"onDragend",
|
||||
"onRightClick",
|
||||
"onUpdate:expandedKeys",
|
||||
]);
|
||||
|
||||
const treeAttrs = computed(() => {
|
||||
const result = {};
|
||||
for (const key in attrs) {
|
||||
if (!handledEventAttrs.has(key)) result[key] = attrs[key];
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
treeData: { type: Array, default: () => [] },
|
||||
expandedKeys: { type: Array, default: undefined },
|
||||
blockNode: { type: Boolean, default: true },
|
||||
virtual: { type: Boolean, default: true },
|
||||
draggable: { type: [Boolean, Function, Object], default: false },
|
||||
allowDrop: { type: Function, default: null },
|
||||
rootKey: { type: [String, Number], default: "__fms_tree_root__" },
|
||||
rootTitle: { type: String, default: "全部分类" },
|
||||
// 右键菜单生成函数:(node) => { items: [...] }
|
||||
contextMenu: { type: Function, default: null },
|
||||
contextMenuDisabled: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const emit = defineEmits(["menuClick"]);
|
||||
// 虚拟滚动与拖拽冲突:draggable 开启时强制关闭 virtual
|
||||
const effectiveVirtual = computed(() => {
|
||||
if (props.draggable) return false;
|
||||
return props.virtual;
|
||||
});
|
||||
|
||||
const effectiveTreeData = computed(() => {
|
||||
return [
|
||||
{
|
||||
key: props.rootKey,
|
||||
title: props.rootTitle,
|
||||
isFmsRoot: true,
|
||||
children: props.treeData,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
"menuClick",
|
||||
"drop",
|
||||
"dragStart",
|
||||
"dragEnter",
|
||||
"dragLeave",
|
||||
"dragOver",
|
||||
"dragEnd",
|
||||
"rightClick",
|
||||
"update:expandedKeys",
|
||||
]);
|
||||
|
||||
let rootExpansionInitialized = false;
|
||||
watch(
|
||||
() => props.expandedKeys,
|
||||
(keys) => {
|
||||
if (rootExpansionInitialized || !Array.isArray(keys)) return;
|
||||
rootExpansionInitialized = true;
|
||||
const hasRoot = keys.some((key) => String(key) === String(props.rootKey));
|
||||
if (!hasRoot) emit("update:expandedKeys", [props.rootKey, ...keys]);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const contextNode = ref(null);
|
||||
|
||||
function onTreeRightClick({ node }) {
|
||||
contextNode.value = node;
|
||||
function onTreeRightClick(info) {
|
||||
contextNode.value = info.node;
|
||||
emit("rightClick", info);
|
||||
}
|
||||
|
||||
const contextMenuItems = computed(() => {
|
||||
@@ -31,6 +102,10 @@ function onMenuClick({ key }) {
|
||||
contextNode.value = null;
|
||||
if (node) emit("menuClick", { key, node });
|
||||
}
|
||||
|
||||
function onExpandedKeysChange(keys) {
|
||||
emit("update:expandedKeys", keys);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -42,10 +117,23 @@ function onMenuClick({ key }) {
|
||||
>
|
||||
<div class="fms-tree-wrapper">
|
||||
<a-tree
|
||||
v-bind="$attrs"
|
||||
v-bind="treeAttrs"
|
||||
:tree-data="effectiveTreeData"
|
||||
:expanded-keys="expandedKeys"
|
||||
:default-expanded-keys="[rootKey]"
|
||||
:block-node="blockNode"
|
||||
:virtual="virtual"
|
||||
:virtual="effectiveVirtual"
|
||||
show-line
|
||||
:draggable="draggable"
|
||||
:allow-drop="allowDrop"
|
||||
@right-click="onTreeRightClick"
|
||||
@drop="$emit('drop', $event)"
|
||||
@dragstart="$emit('dragStart', $event)"
|
||||
@dragenter="$emit('dragEnter', $event)"
|
||||
@dragleave="$emit('dragLeave', $event)"
|
||||
@dragover="$emit('dragOver', $event)"
|
||||
@dragend="$emit('dragEnd', $event)"
|
||||
@update:expanded-keys="onExpandedKeysChange"
|
||||
>
|
||||
<template v-for="(_, name) in $slots" :key="name" #[name]="slotProps">
|
||||
<slot :name="name" v-bind="slotProps || {}" />
|
||||
@@ -53,7 +141,25 @@ function onMenuClick({ key }) {
|
||||
</a-tree>
|
||||
</div>
|
||||
</a-dropdown>
|
||||
<a-tree v-else v-bind="$attrs" :block-node="blockNode" :virtual="virtual">
|
||||
<a-tree
|
||||
v-else
|
||||
v-bind="treeAttrs"
|
||||
:tree-data="effectiveTreeData"
|
||||
:expanded-keys="expandedKeys"
|
||||
:default-expanded-keys="[rootKey]"
|
||||
:block-node="blockNode"
|
||||
:virtual="effectiveVirtual"
|
||||
show-line
|
||||
:draggable="draggable"
|
||||
:allow-drop="allowDrop"
|
||||
@drop="$emit('drop', $event)"
|
||||
@dragstart="$emit('dragStart', $event)"
|
||||
@dragenter="$emit('dragEnter', $event)"
|
||||
@dragleave="$emit('dragLeave', $event)"
|
||||
@dragover="$emit('dragOver', $event)"
|
||||
@dragend="$emit('dragEnd', $event)"
|
||||
@update:expanded-keys="onExpandedKeysChange"
|
||||
>
|
||||
<template v-for="(_, name) in $slots" :key="name" #[name]="slotProps">
|
||||
<slot :name="name" v-bind="slotProps || {}" />
|
||||
</template>
|
||||
|
||||
@@ -322,7 +322,6 @@ watch(() => props.queryItems, initializeDrafts, { immediate: true });
|
||||
grid-template-columns: minmax(0, 1fr) 172px;
|
||||
gap: 14px;
|
||||
padding: 10px 12px 12px;
|
||||
border-left: 1px solid var(--fms-border, #e5e7eb);
|
||||
border-bottom: 1px solid var(--fms-border, #e5e7eb);
|
||||
background: var(--fms-surface, #fff);
|
||||
|
||||
|
||||
Reference in new issue
Block a user