大体介绍
在上一篇文章中,我们实现了预览区中的组件的展示功能,接下来我们打算实现组件的获取焦点的功能,为之后预览区组件的拖拽功能做伏笔。
主要思路
我们可以首先获取data中的数值,遍历data中blocks数组,获取点击组件的下标,将该组件blocks中的属性focus改为true,同时为组件的容器添加一个css样式,当且仅当focus为true的时候可以显示,这样,我们就可以在进行鼠标点击的时候,显示出想要的css样式,从而获取预览区组件获取焦点的功能。
创建useFocus.js用来改变focus属性
// 实现获取焦点
import {computed, ref} from "vue";
export function useFocus(data,callback) {
const selectIndex = ref(-1);
const lastSelectBlock = computed(() => data.value.blocks[selectIndex.value])
const focusData = computed(() => {
let focus = [];
let unfocused = [];
data.value.blocks.forEach(block => (block.focus ? focus : unfocused).push(block));
return {focus, unfocused}
});
const clearBlockFocus = () => {
data.value.blocks.forEach(block => block.focus = false)
}
const containerMousedown = (e) => {
e.preventDefault();
e.stopPropagation();
if (e.button === 0) {
clearBlockFocus();
selectIndex.value = -1;
}
}
const blockMousedown = (e, block, index) => {
e.preventDefault();
e.stopPropagation();
// console.log(e)
if (e.button === 0) {
// block上规划一个属性 focus 获取焦点后就将focus变为true
if (e.shiftKey) {
if (focusData.value.focus.length <= 1) {
block.focus = true
} else {
block.focus = !block.focus;
}
} else {
if (!block.focus) {
clearBlockFocus();
block.focus = true;
}
}
selectIndex.value = index;
// console.log(typeof (data.value.blocks[selectIndex.value]))
callback(e)
}
}
// window.addEventListener("blockMousedown", blockMousedown, { passive: false});
return {
blockMousedown,
containerMousedown,
focusData,
lastSelectBlock,
}
}
其中返回值有四个变量。
? ? ? ? blockMousedown:鼠标点击一个组件或者是shift+鼠标点击多个组件,这个函数实现了将一个组件或多个组件的blocks中的focus变为true
? ? ? ? containerMousedown:鼠标点击非组件的画布区域,这个函数实现了将一个组件或多个组件的blocks中的focus变为false
? ? ? ? focusData:这个数组中保存了所有blocks中focus为true的所有组件。
? ? ? ? lastSelectBlock:这个数最后一个点击的组件,亦或是最有一个focus变为true的组件数据
在editor.js中进行引用
let {blockMousedown, focusData, containerMousedown, lastSelectBlock} = useFocus(data, (e) => {
mousedown(e)
// console.log(JSON.stringify(attrs_style.value.attribute))
// console.log(JSON.stringify(attrs_style.value.block))
});
<div class="editor-container-canvas">
{/*产生内容区域*/}
<div
class="editor-container-canvas_content"
style={containerStyles.value}
ref={containerRef}
onmousedown={containerMousedown}
oncontextmenu={containerRightClick}
>
<RightClick v-model={copyContent}/>
{/*网格线*/}
<Grid/>
{
(data.value.blocks.map((block, index) => {
// console.log(index)
return <EditorBlock
// class={"iconfont icon-suo"}
// cursor="move"
class={block.lock ? 'iconfont icon-suo' : ''}
class={block.focus ? 'editor-block-focus' : ''}
block={block}
data={data}
index={index}
onmousedown={(e) => e.target.className === 'editor-block' || e.target.className === 'editor-block editor-block-focus' || e.target.className === 'editor-block iconfont icon-suo' ? blockMousedown(e, block, index) : ''}
onmouseover={(e) => e.target.className === 'editor-block' || e.target.className === 'editor-block editor-block-focus' || e.target.className === 'editor-block iconfont icon-suo' ? e.target.style.cursor = block.moveSign : ''}
// onmouseover={(e) => e.target.children.length === 0 ? '' : e.target.children[0].style.cursor ='move'}
// onmouseover={(e) => console.log(e.target.className)}
oncontextmenu={(e) => blockRightClick(e, block)}
/>
}))
}
{markLine.x !== null && <div class='line-x' style={{left: markLine.x + 'px'}}/>}
{markLine.y !== null && <div class='line-y' style={{top: markLine.y + 'px'}}/>}
</div>
</div>
预期结果
单个组件获取焦点
多个组件获取焦点
?
?
|