好家伙,
0.代码已开源
Fattiger4399/lowcode-demo: 一个简单的低代码编辑器 技术栈:Vue3 element-plus jsx (github.com)
本篇实现效果如下:
1.分析
这玩意的思路很好理解
本质上就是给组件绑个拖拽方法
拽到哪里,就把位置更新给组件就好了,简单粗暴
当然,需要做选中判定,知道我选中了哪些组件
2.选中判定实现
import { useFocus } from "./useFocus";
let { blockMousedown, focusData } = useFocus(data, (e) => {
mousedown(e)
});
import {computed} from 'vue'
//useFocus用于处理画布中组件元素的选中
export function useFocus(data,callback){ //获取哪些元素被选中了
const focusData = computed(() => {
let focus = [];
let unfocused = [];
data.value.blocks.forEach(block => (block.focus ? focus : unfocused).push(block))
return {focus,unfocused}
})
return{
blockMousedown,
focusData
}
}
此处,我们做一次选中判定,将选中的组件,和未被选中的组件,分开放,并返回
const blockMousedown = (e, block) =\> {
//block上我们规划一个属性focus 获取焦点后就将focus变为true
e.preventDefault();
e.stopPropagation();
if (e.shiftKey) {
block.focus = !block.focus
} else {
if (!block.focus) {
clearBlockFocus();
block.focus = true;//清空其他组件的focus属性
} else {
block.focus = false;
}
}
callback(e)
}
判断是否按下了shift键
3.点击触发事件
<div class="editor-container-canvas__content"
style={containerStyles.value}
ref={containerRef}
onMousedown={containerMousedown}>
{
(data.value.blocks.map(block => (
<EditorBlock
class={block.focus ? 'editor-block-focus' : ''}
block={block}
onMousedown={(e) => blockMousedown(e, block)}
></EditorBlock>
)))
}
</div>
let { blockMousedown, focusData } = useFocus(data, (e) => {
mousedown(e)
});
const mousemove = (e) => {
let { clientX: moveX, clientY: moveY } = e;
let endX = moveX - dragState.startX;
let endY = moveY - dragState.startY;
focusData.value.focus.forEach((block, idx) => {
// console.log(dragState)
block.top = dragState.startPos[idx].top + endY;
block.left = dragState.startPos[idx].top + endX;
})
}
const mouseup = (e) => {
console.log(document)
document.removeEventListener('mousemove', mousemove)
document.removeEventListener('mouseup', mouseup)
}
const mousedown = (e) => {
dragState = {
startX: e.clientX,
startY: e.clientY,
startPos: focusData.value.focus.map(({ top, left }) => ({ top, left }))
}
console.log(dragState)
document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup)
}
const blockMousedown = (e, block) => {
//block上我们规划一个属性focus 获取焦点后就将focus变为true
e.preventDefault();
e.stopPropagation();
if (e.shiftKey) {
block.focus = !block.focus
} else {
if (!block.focus) {
clearBlockFocus();
block.focus = true;//清空其他组件的focus属性
} else {
block.focus = false;
}
}
callback(e)
}
判断是否按下了shift键
focusData.value.focus.forEach((block, idx) => {
// console.log(dragState)
block.top = dragState.startPos[idx].top + endY;
block.left = dragState.startPos[idx].top + endX;
})
最后更改数据
搞定!