fix: 优化组件列表多选键盘快捷键监听体验

This commit is contained in:
parisma 2022-11-10 17:46:38 +08:00
parent c7a8552d9b
commit b2702aaa9e
2 changed files with 96 additions and 84 deletions

View File

@ -1,72 +1,70 @@
<template> <template>
<TMagicScrollbar <div ref="layerPanel">
class="magic-editor-layer-panel" <TMagicScrollbar class="magic-editor-layer-panel">
@mouseenter="addSelectModeListener" <slot name="layer-panel-header"></slot>
@mouseleave="removeSelectModeListener"
>
<slot name="layer-panel-header"></slot>
<TMagicInput <TMagicInput
v-model="filterText" v-model="filterText"
class="search-input" class="search-input"
size="small" size="small"
placeholder="输入关键字进行过滤" placeholder="输入关键字进行过滤"
clearable clearable
:prefix-icon="Search" :prefix-icon="Search"
@change="filterTextChangeHandler" @change="filterTextChangeHandler"
></TMagicInput> ></TMagicInput>
<TMagicTree <TMagicTree
v-if="values.length" v-if="values.length"
class="magic-editor-layer-tree" class="magic-editor-layer-tree"
ref="tree" ref="tree"
node-key="id" node-key="id"
empty-text="页面空荡荡的" empty-text="页面空荡荡的"
draggable draggable
:default-expanded-keys="defaultExpandedKeys" :default-expanded-keys="defaultExpandedKeys"
:load="loadItems" :load="loadItems"
:data="values" :data="values"
:expand-on-click-node="false" :expand-on-click-node="false"
:highlight-current="true" :highlight-current="true"
:props="{ :props="{
children: 'items', children: 'items',
}" }"
:filter-node-method="filterNode" :filter-node-method="filterNode"
:allow-drop="allowDrop" :allow-drop="allowDrop"
:show-checkbox="isMultiSelectStatus || selectedIds.length > 1" :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" @check="multiClickHandler"
@mousedown="toggleClickFlag" @mousedown="toggleClickFlag"
@mouseup="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"
@mouseenter="highlightHandler(data)" @mouseenter="highlightHandler(data)"
:class="{ 'cus-tree-node-hover': canHighlight(data) }" :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>
{{ `${data.name} (${data.id})` }} {{ `${data.name} (${data.id})` }}
</span> </span>
</slot> </slot>
</div> </div>
</template> </template>
</TMagicTree> </TMagicTree>
<Teleport to="body"> <Teleport to="body">
<LayerMenu ref="menu" :layer-content-menu="layerContentMenu"></LayerMenu> <LayerMenu ref="menu" :layer-content-menu="layerContentMenu"></LayerMenu>
</Teleport> </Teleport>
</TMagicScrollbar> </TMagicScrollbar>
</div>
</template> </template>
<script lang="ts" setup name="MEditorLayerPanel"> <script lang="ts" setup name="MEditorLayerPanel">
import { computed, inject, nextTick, ref, watch } from 'vue'; import { computed, inject, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import { Search } from '@element-plus/icons-vue'; import { Search } from '@element-plus/icons-vue';
import KeyController from 'keycon'; import KeyController from 'keycon';
import { throttle } from 'lodash-es'; import { throttle } from 'lodash-es';
@ -264,32 +262,47 @@ watch([selectedIds, tree], async () => {
setTreeKeyStatus(); setTreeKeyStatus();
}); });
const keycon = ref<KeyController>(); const layerPanel = ref<HTMLDivElement>();
// const mouseenterHandler = () => {
const addSelectModeListener = () => { layerPanel.value?.focus();
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+tabfalse
keycon.value.on('blur', () => {
isMultiSelectStatus.value = false;
});
keycon.value.keyup(ctrl, (e) => {
e.inputEvent.preventDefault();
isMultiSelectStatus.value = false;
});
}; };
//
const removeSelectModeListener = () => { const mouseleaveHandler = () => {
keycon.value?.destroy(); layerPanel.value?.blur();
// (ctrl) // (ctrl)
if (selectedIds.value.length === 1) isMultiSelectStatus.value = false; if (selectedIds.value.length === 1) isMultiSelectStatus.value = false;
}; };
let keycon: KeyController;
onMounted(() => {
layerPanel.value?.addEventListener('mouseenter', mouseenterHandler);
layerPanel.value?.addEventListener('mouseleave', mouseleaveHandler);
keycon = new KeyController(layerPanel.value);
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
const ctrl = isMac ? 'meta' : 'ctrl';
keycon
.keydown(ctrl, (e) => {
e.inputEvent.preventDefault();
isMultiSelectStatus.value = true;
})
.on('blur', () => {
isMultiSelectStatus.value = false;
})
.keyup(ctrl, (e) => {
e.inputEvent.preventDefault();
isMultiSelectStatus.value = false;
});
});
onUnmounted(() => {
layerPanel.value?.removeEventListener('mouseenter', mouseenterHandler);
layerPanel.value?.removeEventListener('mouseleave', mouseleaveHandler);
keycon.destroy();
});
// //
const clicked = ref(false); const clicked = ref(false);
// //

View File

@ -461,7 +461,6 @@ class Editor extends BaseService {
newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => { newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue) => {
if (isObject(srcValue) && Array.isArray(objValue)) { if (isObject(srcValue) && Array.isArray(objValue)) {
// 原来的配置是数组,新的配置是对象,则直接使用新的值 // 原来的配置是数组,新的配置是对象,则直接使用新的值
console.log('--srcValue-', srcValue);
return srcValue; return srcValue;
} }
if (Array.isArray(srcValue)) { if (Array.isArray(srcValue)) {