目录
在editor.jsx中使用useMenuDragger.js方法
大体介绍
我们要实现在组件区点击选中一个想要的组件,并拖动到预览区来进行渲染,松开鼠标就可以完成组件的位置的确定和渲染。
主要思路
首先我们在主页面中引入data.json中的数据,用于对data.json中的数据进行增删改查。然后我们可以给产生画布的div添加一个style属性,用于对画布的宽和高来进行渲染。再然后我们可以给产生画布的div添加一个{ref}表示,用于监听鼠标的点击和移动事件。最后我们再写一个js文件,传入data和ref数据,对鼠标事件进行监听和对div中画布进行渲染操作。
设置计算属性,实现与data.json中数据的双向绑定
在editor.jsx文件中
// 设置计算属性,以便于实现数据的双向绑定
const data = computed({
get() {
return props.modelValue
},
set(newValue) {
ctx.emit('update:modelValue', deepcopy(newValue))
}
})
设置计算属性,实现画布大小数据的绑定
在editor.jsx文件中
// 设置计算属性,用来改变和渲染画布的大小
const containerStyles = computed(() => ({
width: data.value.container.width + 'px',
height: data.value.container.height + 'px',
}))
给预览区绑定一个ref,用于绑定事件
const containerRef = ref(null)
实现组件区菜单拖拽功能
新建一个 useMenuDragger.js 文件,接收两个参数:data(JSON数据),containterRef(用于绑定事件)。
// 菜单拖拽功能
import {events} from "@/packages/events";
export function useMenuDragger(containerRef, data) {
let currentComponent = null;
const dragenter = (e) => {
e.dataTransfer.dropEffect = 'move';
}
const dragover = (e) => {
e.preventDefault();
}
const dragleave = (e) => {
e.dataTransfer.dropEffect = 'none';
}
const drop = (e) => {
// console.log(currentComponent);
let blocks = data.value.blocks; // 内部已经渲染的组件
data.value = {
...data.value, blocks: [
...blocks,
{
top: e.offsetY,
left: e.offsetX,
zIndex: 1,
key: currentComponent.key,
alignCenter: true, // 实现松手的时候鼠标可以居中
focus: false // 没有选定的状态
}
]
}
currentComponent = null;
}
const dragstart = (e, component) => {
containerRef.value.addEventListener('dragenter', dragenter)
containerRef.value.addEventListener('dragover', dragover)
containerRef.value.addEventListener('dragleave', dragleave)
containerRef.value.addEventListener('drop', drop)
currentComponent = component;
events.emit('start');
}
const dragend = (e) => {
containerRef.value.removeEventListener('dragenter', dragenter)
containerRef.value.removeEventListener('dragover', dragover)
containerRef.value.removeEventListener('dragleave', dragleave)
containerRef.value.removeEventListener('drop', drop)
events.emit('end');
}
return {
dragstart,
dragend
}
}
在其中:
dragenter进入元素中 添加一个移动的标识,就是在鼠标点击一个组件进行移动,移动到预览区的时候就可以触发一个移动标识。
dragover 在目标元素经过 必须阻止默认行为 否则不能触发drop,就是在鼠标点击一个组件进行移动,在预览区进行移动的时候,一定要阻止它的默认行为。就是在鼠标点击一个组件进行移动
dragleave 离开元素的时候 需要添加一个禁用标识,就是在鼠标点击一个组件进行移动,如果不在预览区进行移动的话,鼠标会变成一个禁用的标识,表明组件不能在这里进行放置。
drop 松手的时候 根据拖拽的组件 添加一个组件,就是在预览区放置,会渲染出一个新的组件。
在editor.jsx中使用useMenuDragger.js方法
import {useMenuDragger} from "@/packages/useMenuDragger";
<div class="editor-left">
{/*根据注册列表 渲染对应的内容*/}
{config.componentList.map(component => (
<div
class='editor-left-item'
draggable
onDragstart={e => dragstart(e, component)}
onDragend={dragend}
>
<span>{component.label}</span>
<div>{component.preview()}</div>
</div>
))}
</div>
大致实现结果