mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-05-07 19:06:40 +08:00
feat(editor): 支持通过左侧组件树进行组件多选
* feat(layerpanel): 支持通过组件树对组件进行多选 * feat(editor): 重构LayerPanel为ts setup语法形式 * feat(editor): 组件列表选中节点与高亮节点时的逻辑优化,两种形态互斥处理 * fix(editor): 修复按住ctrl不放但鼠标移出的layerpanel时选择模式无法复原的问题,修复点击组件树index多选框可进行选择的问题 * fix(editor): 修复多选场景点击组件树节点取消多选时,节点高亮样式冲突的问题 close #404 Co-authored-by: parisma <parisma@tencent.com>
This commit is contained in:
parent
6ec67438d2
commit
e3b7f587ee
@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-scrollbar class="magic-editor-layer-panel">
|
<el-scrollbar
|
||||||
|
class="magic-editor-layer-panel"
|
||||||
|
@mouseenter="addSelectModeListener"
|
||||||
|
@mouseleave="removeSelectModeListener"
|
||||||
|
>
|
||||||
<slot name="layer-panel-header"></slot>
|
<slot name="layer-panel-header"></slot>
|
||||||
|
|
||||||
<el-input
|
<el-input
|
||||||
@ -17,7 +21,7 @@
|
|||||||
node-key="id"
|
node-key="id"
|
||||||
empty-text="页面空荡荡的"
|
empty-text="页面空荡荡的"
|
||||||
draggable
|
draggable
|
||||||
:default-expanded-keys="expandedKeys"
|
:default-expanded-keys="defaultExpandedKeys"
|
||||||
:load="loadItems"
|
:load="loadItems"
|
||||||
:data="values"
|
:data="values"
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
@ -27,20 +31,22 @@
|
|||||||
}"
|
}"
|
||||||
:filter-node-method="filterNode"
|
:filter-node-method="filterNode"
|
||||||
:allow-drop="allowDrop"
|
:allow-drop="allowDrop"
|
||||||
|
:show-checkbox="isMultiSelectStatus || selectedIds.length > 1"
|
||||||
@node-click="clickHandler"
|
@node-click="clickHandler"
|
||||||
@node-contextmenu="contextmenu"
|
@node-contextmenu="contextmenu"
|
||||||
@node-drag-end="handleDragEnd"
|
@node-drag-end="handleDragEnd"
|
||||||
@node-collapse="handleCollapse"
|
@node-collapse="handleCollapse"
|
||||||
@node-expand="handleExpand"
|
@node-expand="handleExpand"
|
||||||
|
@check="multiClickHandler"
|
||||||
|
@mousedown="toggleClickFlag"
|
||||||
|
@mouseup="toggleClickFlag"
|
||||||
>
|
>
|
||||||
<template #default="{ node, data }">
|
<template #default="{ node, data }">
|
||||||
<div
|
<div
|
||||||
:id="data.id"
|
:id="data.id"
|
||||||
class="cus-tree-node"
|
class="cus-tree-node"
|
||||||
@mousedown="toggleClickFlag"
|
|
||||||
@mouseup="toggleClickFlag"
|
|
||||||
@mouseenter="highlightHandler(data)"
|
@mouseenter="highlightHandler(data)"
|
||||||
:class="{ 'cus-tree-node-hover': canHighlight && data.id === highlightNode?.id }"
|
:class="{ 'cus-tree-node-hover': canHighlight(data) }"
|
||||||
>
|
>
|
||||||
<slot name="layer-node-content" :node="node" :data="data">
|
<slot name="layer-node-content" :node="node" :data="data">
|
||||||
<span>
|
<span>
|
||||||
@ -57,24 +63,48 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { computed, defineComponent, inject, Ref, ref, watchEffect } from 'vue';
|
import { computed, inject, ref, watch } from 'vue';
|
||||||
import type { ElTree } from 'element-plus';
|
import type { ElTree } from 'element-plus';
|
||||||
|
import KeyController from 'keycon';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
|
|
||||||
import type { Id, MNode, MPage } from '@tmagic/schema';
|
import type { Id, MNode, MPage } from '@tmagic/schema';
|
||||||
import { MContainer, NodeType } from '@tmagic/schema';
|
import { MContainer, NodeType } from '@tmagic/schema';
|
||||||
import StageCore from '@tmagic/stage';
|
import StageCore from '@tmagic/stage';
|
||||||
|
|
||||||
import type { EditorService } from '../../services/editor';
|
|
||||||
import type { Services } from '../../type';
|
import type { Services } from '../../type';
|
||||||
import { Layout } from '../../type';
|
import { Layout } from '../../type';
|
||||||
|
|
||||||
import LayerMenu from './LayerMenu.vue';
|
import LayerMenu from './LayerMenu.vue';
|
||||||
|
|
||||||
const throttleTime = 150;
|
const throttleTime = 150;
|
||||||
|
const services = inject<Services>('services');
|
||||||
|
const tree = ref<InstanceType<typeof ElTree>>();
|
||||||
|
const menu = ref<InstanceType<typeof LayerMenu>>();
|
||||||
|
const editorService = services?.editorService;
|
||||||
|
const page = computed(() => editorService?.get('page'));
|
||||||
|
const values = computed(() => (page.value ? [page.value] : []));
|
||||||
|
// 多选选中的节点数组
|
||||||
|
const selectedNodes = ref<MNode[]>([]);
|
||||||
|
// 多选选中的组件id数组
|
||||||
|
const selectedIds = computed(() => selectedNodes.value.map((node: MNode) => node.id));
|
||||||
|
// 是否多选
|
||||||
|
const isMultiSelectStatus = ref(false);
|
||||||
|
// 多选场景 取消选中的那个节点id
|
||||||
|
const spliceNodeKey = ref<Id>();
|
||||||
|
const filterText = ref('');
|
||||||
|
// 默认展开节点
|
||||||
|
const defaultExpandedKeys = computed(() => (selectedIds.value.length > 0 ? selectedIds.value : []));
|
||||||
|
|
||||||
const select = async (data: MNode, editorService?: EditorService) => {
|
editorService?.on('remove', () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
tree.value?.getNode(editorService.get('node').id)?.updateChildren();
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 触发画布单选
|
||||||
|
const select = async (data: MNode) => {
|
||||||
if (!data.id) {
|
if (!data.id) {
|
||||||
throw new Error('没有id');
|
throw new Error('没有id');
|
||||||
}
|
}
|
||||||
@ -83,7 +113,14 @@ const select = async (data: MNode, editorService?: EditorService) => {
|
|||||||
editorService?.get<StageCore>('stage')?.select(data.id);
|
editorService?.get<StageCore>('stage')?.select(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const highlight = (data: MNode, editorService?: EditorService) => {
|
// 触发画布多选
|
||||||
|
const multiSelect = async (data: Id[]) => {
|
||||||
|
await editorService?.multiSelect(data);
|
||||||
|
editorService?.get<StageCore>('stage')?.multiSelect(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 触发画布高亮
|
||||||
|
const highlight = (data: MNode) => {
|
||||||
if (!data?.id) {
|
if (!data?.id) {
|
||||||
throw new Error('没有id');
|
throw new Error('没有id');
|
||||||
}
|
}
|
||||||
@ -91,58 +128,97 @@ const highlight = (data: MNode, editorService?: EditorService) => {
|
|||||||
editorService?.get<StageCore>('stage')?.highlight(data.id);
|
editorService?.get<StageCore>('stage')?.highlight(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const useDrop = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorService?: EditorService) => ({
|
const expandedKeys = new Map<Id, Id>();
|
||||||
allowDrop: (draggingNode: any, dropNode: any, type: string): boolean => {
|
|
||||||
const { data } = dropNode || {};
|
|
||||||
const { data: ingData } = draggingNode;
|
|
||||||
|
|
||||||
const { type: ingType } = ingData;
|
// tree方法:拖拽时判定目标节点能否成为拖动目标位置
|
||||||
|
const allowDrop = (draggingNode: any, dropNode: any, type: string): boolean => {
|
||||||
|
const { data } = dropNode || {};
|
||||||
|
const { data: ingData } = draggingNode;
|
||||||
|
|
||||||
if (ingType !== NodeType.PAGE && data.type === NodeType.PAGE) return false;
|
const { type: ingType } = ingData;
|
||||||
if (ingType === NodeType.PAGE && data.type !== NodeType.PAGE) return false;
|
|
||||||
if (!data || !data.type) return false;
|
|
||||||
if (['prev', 'next'].includes(type)) return true;
|
|
||||||
if (data.items || data.type === 'container') return true;
|
|
||||||
|
|
||||||
return false;
|
if (ingType !== NodeType.PAGE && data.type === NodeType.PAGE) return false;
|
||||||
},
|
if (ingType === NodeType.PAGE && data.type !== NodeType.PAGE) return false;
|
||||||
|
if (!data || !data.type) return false;
|
||||||
|
if (['prev', 'next'].includes(type)) return true;
|
||||||
|
if (data.items || data.type === 'container') return true;
|
||||||
|
|
||||||
async handleDragEnd(e: any) {
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// tree事件:拖拽结束时(可能未成功)触发的事件
|
||||||
|
const handleDragEnd = async (e: any) => {
|
||||||
|
if (!tree.value) return;
|
||||||
|
const { data: node } = e;
|
||||||
|
const parent = editorService?.getParentById(node.id, false) as MContainer;
|
||||||
|
const layout = await editorService?.getLayout(parent);
|
||||||
|
node.style.position = layout;
|
||||||
|
if (layout === Layout.RELATIVE) {
|
||||||
|
node.style.top = 0;
|
||||||
|
node.style.left = 0;
|
||||||
|
}
|
||||||
|
const { data } = tree.value;
|
||||||
|
const [page] = data as [MPage];
|
||||||
|
editorService?.update(page);
|
||||||
|
};
|
||||||
|
|
||||||
|
// tree方法: 加载子树数据的方法
|
||||||
|
const loadItems = (node: any, resolve: Function) => {
|
||||||
|
if (Array.isArray(node.data)) {
|
||||||
|
return resolve(node.data);
|
||||||
|
}
|
||||||
|
if (Array.isArray(node.data?.items)) {
|
||||||
|
return resolve(node.data?.items);
|
||||||
|
}
|
||||||
|
resolve([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// tree事件:节点被关闭时触发的事件
|
||||||
|
const handleCollapse = (data: MNode) => {
|
||||||
|
expandedKeys.delete(data.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
// tree事件:节点被展开时触发的事件
|
||||||
|
const handleExpand = (data: MNode) => {
|
||||||
|
const parent = editorService?.getParentById(data.id);
|
||||||
|
if (!parent?.id) return;
|
||||||
|
expandedKeys.set(parent.id, parent.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
// tree方法:对树节点进行筛选时执行的方法
|
||||||
|
const filterNode = (value: string, data: MNode): boolean => {
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let name = '';
|
||||||
|
if (data.name) {
|
||||||
|
name = data.name;
|
||||||
|
} else if (data.items) {
|
||||||
|
name = 'container';
|
||||||
|
}
|
||||||
|
return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 过滤关键字
|
||||||
|
const filterTextChangeHandler = (val: string) => {
|
||||||
|
tree.value?.filter(val);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 展开树节点
|
||||||
|
const expandNodes = () => {
|
||||||
|
expandedKeys.forEach((key) => {
|
||||||
if (!tree.value) return;
|
if (!tree.value) return;
|
||||||
const { data: node } = e;
|
tree.value.getNode(key)?.expand();
|
||||||
const parent = editorService?.getParentById(node.id, false) as MContainer;
|
});
|
||||||
const layout = await editorService?.getLayout(parent);
|
};
|
||||||
node.style.position = layout;
|
|
||||||
if (layout === Layout.RELATIVE) {
|
|
||||||
node.style.top = 0;
|
|
||||||
node.style.left = 0;
|
|
||||||
}
|
|
||||||
const { data } = tree.value;
|
|
||||||
const [page] = data as [MPage];
|
|
||||||
editorService?.update(page);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const useStatus = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorService?: EditorService) => {
|
watch(
|
||||||
const node = ref<MNode>();
|
() => editorService?.get('nodes'),
|
||||||
const page = computed(() => editorService?.get('page'));
|
(nodes) => {
|
||||||
const expandedKeys = new Map<Id, Id>();
|
|
||||||
|
|
||||||
const expandNodes = () => {
|
|
||||||
expandedKeys.forEach((key) => {
|
|
||||||
if (!tree.value) return;
|
|
||||||
tree.value.getNode(key)?.expand();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
watchEffect(() => {
|
|
||||||
if (!tree.value) return;
|
if (!tree.value) return;
|
||||||
if (!editorService) return;
|
if (!editorService) return;
|
||||||
node.value = editorService.get('node');
|
if (!nodes) return;
|
||||||
|
selectedNodes.value = nodes as unknown as MNode[];
|
||||||
if (!node.value) return;
|
|
||||||
|
|
||||||
tree.value.setCurrentKey(node.value.id, true);
|
|
||||||
|
|
||||||
const parent = editorService.get('parent');
|
const parent = editorService.get('parent');
|
||||||
if (!parent?.id) return;
|
if (!parent?.id) return;
|
||||||
@ -159,114 +235,128 @@ const useStatus = (tree: Ref<InstanceType<typeof ElTree> | undefined>, editorSer
|
|||||||
});
|
});
|
||||||
expandNodes();
|
expandNodes();
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
// 设置树节点选中状态
|
||||||
values: computed(() => (page.value ? [page.value] : [])),
|
const setTreeKeyStatus = () => {
|
||||||
|
if (!tree.value) return;
|
||||||
loadItems: (node: any, resolve: Function) => {
|
if (selectedIds.value.length === 0) {
|
||||||
if (Array.isArray(node.data)) {
|
tree.value.setCheckedKeys([]);
|
||||||
return resolve(node.data);
|
tree.value.setCurrentKey();
|
||||||
}
|
} else if (selectedIds.value.length === 1 && !isMultiSelectStatus.value) {
|
||||||
if (Array.isArray(node.data?.items)) {
|
// 选中1个
|
||||||
return resolve(node.data?.items);
|
tree.value.setCurrentKey(selectedIds.value[0], true);
|
||||||
}
|
tree.value.setCheckedKeys([]);
|
||||||
resolve([]);
|
} else {
|
||||||
},
|
// 多选框选中多个
|
||||||
|
tree.value.setCheckedKeys(selectedIds.value);
|
||||||
highlightNode: computed(() => editorService?.get('highlightNode')),
|
tree.value.setCurrentKey();
|
||||||
clickNode: node,
|
}
|
||||||
expandedKeys: computed(() => (node.value ? [node.value.id] : [])),
|
|
||||||
|
|
||||||
handleCollapse: (data: MNode) => {
|
|
||||||
expandedKeys.delete(data.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleExpand: (data: MNode) => {
|
|
||||||
const parent = editorService?.getParentById(data.id);
|
|
||||||
if (!parent?.id) return;
|
|
||||||
expandedKeys.set(parent.id, parent.id);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const useFilter = (tree: Ref<InstanceType<typeof ElTree> | undefined>) => ({
|
watch(selectedIds, () => {
|
||||||
filterText: ref(''),
|
setTreeKeyStatus();
|
||||||
|
|
||||||
filterNode: (value: string, data: MNode): boolean => {
|
|
||||||
if (!value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let name = '';
|
|
||||||
if (data.name) {
|
|
||||||
name = data.name;
|
|
||||||
} else if (data.items) {
|
|
||||||
name = 'container';
|
|
||||||
}
|
|
||||||
return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
|
|
||||||
},
|
|
||||||
|
|
||||||
filterTextChangeHandler(val: string) {
|
|
||||||
tree.value?.filter(val);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default defineComponent({
|
const keycon = ref<KeyController>();
|
||||||
name: 'magic-editor-layer-panel',
|
// 监听模式选择
|
||||||
|
const addSelectModeListener = () => {
|
||||||
|
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
|
||||||
|
const ctrl = isMac ? 'meta' : 'ctrl';
|
||||||
|
keycon.value = new KeyController();
|
||||||
|
keycon.value.keydown(ctrl, (e) => {
|
||||||
|
e.inputEvent.preventDefault();
|
||||||
|
isMultiSelectStatus.value = true;
|
||||||
|
});
|
||||||
|
// ctrl+tab切到其他窗口,需要将多选状态置为false
|
||||||
|
keycon.value.on('blur', () => {
|
||||||
|
isMultiSelectStatus.value = false;
|
||||||
|
});
|
||||||
|
keycon.value.keyup(ctrl, (e) => {
|
||||||
|
e.inputEvent.preventDefault();
|
||||||
|
isMultiSelectStatus.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 移除监听
|
||||||
|
const removeSelectModeListener = () => {
|
||||||
|
keycon.value?.destroy();
|
||||||
|
// 如果鼠标移出监听范围,且当前只选中了一个,置为单选模式(修复按住ctrl不放但鼠标移出的情况)
|
||||||
|
if (selectedIds.value.length === 1) isMultiSelectStatus.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
components: { LayerMenu },
|
// 鼠标是否按下标志,用于高亮状态互斥
|
||||||
|
const clicked = ref(false);
|
||||||
|
// 高亮的节点
|
||||||
|
const highlightNode = computed(() => editorService?.get('highlightNode'));
|
||||||
|
|
||||||
setup() {
|
// 鼠标在组件树移动触发高亮
|
||||||
const services = inject<Services>('services');
|
const highlightHandler = throttle((data: MNode) => {
|
||||||
const tree = ref<InstanceType<typeof ElTree>>();
|
highlight(data);
|
||||||
const menu = ref<InstanceType<typeof LayerMenu>>();
|
}, throttleTime);
|
||||||
const clicked = ref(false);
|
|
||||||
const editorService = services?.editorService;
|
|
||||||
const highlightHandler = throttle((data: MNode) => {
|
|
||||||
highlight(data, editorService);
|
|
||||||
}, throttleTime);
|
|
||||||
|
|
||||||
const toggleClickFlag = () => {
|
const toggleClickFlag = () => {
|
||||||
clicked.value = !clicked.value;
|
clicked.value = !clicked.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusData = useStatus(tree, editorService);
|
// 是否满足展示高亮
|
||||||
const canHighlight = computed(
|
const canHighlight = (data: MNode) => {
|
||||||
() => statusData.highlightNode.value?.id !== statusData.clickNode.value?.id && !clicked.value,
|
if (clicked.value) return false;
|
||||||
);
|
return (
|
||||||
|
data.id === highlightNode?.value?.id && !selectedIds.value.includes(data.id) && spliceNodeKey.value !== data.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
editorService?.on('remove', () => {
|
// 监听选择模式,针对多选情况做一些处理
|
||||||
setTimeout(() => {
|
watch(isMultiSelectStatus, () => {
|
||||||
tree.value?.getNode(editorService.get('node').id)?.updateChildren();
|
// 多选模式如果已存在第一个选中的元素是页面(magic-ui-page) 剔除页面选中状态
|
||||||
}, 0);
|
if (isMultiSelectStatus.value && selectedNodes.value.length === 1 && selectedNodes.value[0].type === NodeType.PAGE) {
|
||||||
});
|
selectedNodes.value = [];
|
||||||
|
}
|
||||||
return {
|
|
||||||
tree,
|
|
||||||
menu,
|
|
||||||
...statusData,
|
|
||||||
...useDrop(tree, editorService),
|
|
||||||
...useFilter(tree),
|
|
||||||
|
|
||||||
highlightHandler,
|
|
||||||
toggleClickFlag,
|
|
||||||
canHighlight,
|
|
||||||
|
|
||||||
clickHandler(data: MNode): void {
|
|
||||||
if (services?.uiService.get<boolean>('uiSelectMode')) {
|
|
||||||
document.dispatchEvent(new CustomEvent('ui-select', { detail: data }));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tree.value?.setCurrentKey(data.id);
|
|
||||||
select(data, editorService);
|
|
||||||
},
|
|
||||||
|
|
||||||
async contextmenu(event: MouseEvent, data: MNode) {
|
|
||||||
event.preventDefault();
|
|
||||||
await select(data, editorService);
|
|
||||||
menu.value?.show(event);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 选择节点多选框
|
||||||
|
const multiClickHandler = (data: MNode): void => {
|
||||||
|
if (!data?.id) {
|
||||||
|
throw new Error('没有id');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面(magic-ui-page)不可选中
|
||||||
|
if (data.type === NodeType.PAGE) {
|
||||||
|
tree.value?.setCheckedKeys([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = selectedNodes.value.findIndex((node) => node.id === data.id);
|
||||||
|
if (index !== -1) {
|
||||||
|
// 已经包含就移除掉
|
||||||
|
selectedNodes.value.splice(index, 1);
|
||||||
|
spliceNodeKey.value = data.id;
|
||||||
|
} else {
|
||||||
|
selectedNodes.value = [...selectedNodes.value, data];
|
||||||
|
}
|
||||||
|
tree.value?.setCheckedKeys(selectedIds.value);
|
||||||
|
multiSelect(selectedIds.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 点击节点
|
||||||
|
const clickHandler = (data: MNode): void => {
|
||||||
|
if (!isMultiSelectStatus.value) {
|
||||||
|
if (services?.uiService.get<boolean>('uiSelectMode')) {
|
||||||
|
document.dispatchEvent(new CustomEvent('ui-select', { detail: data }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tree.value?.setCurrentKey(data.id);
|
||||||
|
select(data);
|
||||||
|
} else {
|
||||||
|
multiClickHandler(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 右键菜单
|
||||||
|
const contextmenu = async (event: MouseEvent, data: MNode): Promise<void> => {
|
||||||
|
event.preventDefault();
|
||||||
|
await select(data);
|
||||||
|
menu.value?.show(event);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -134,6 +134,7 @@ export default class StageCore extends EventEmitter {
|
|||||||
this.selectedDomList.push(el);
|
this.selectedDomList.push(el);
|
||||||
}
|
}
|
||||||
this.multiSelect(this.selectedDomList);
|
this.multiSelect(this.selectedDomList);
|
||||||
|
this.emit('multiSelect', this.selectedDomList);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 要先触发select,在触发update
|
// 要先触发select,在触发update
|
||||||
@ -238,9 +239,8 @@ export default class StageCore extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
public async multiSelect(idOrElList: HTMLElement[] | Id[]): Promise<void> {
|
public async multiSelect(idOrElList: HTMLElement[] | Id[]): Promise<void> {
|
||||||
this.clearSelectStatus('select');
|
this.clearSelectStatus('select');
|
||||||
const elList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
|
this.selectedDomList = await Promise.all(idOrElList.map(async (idOrEl) => await this.getTargetElement(idOrEl)));
|
||||||
this.multiDr.multiSelect(elList);
|
this.multiDr.multiSelect(this.selectedDomList);
|
||||||
this.emit('multiSelect', elList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user