这是我参与「第四届青训营 」笔记创作活动的第十天
最近一直在研究低代码平台,于是想写篇文章记录一下。
我所使用的技术栈是vue、node.js和mysql
低代码作为目前较为流行的一种新型的实现前端页面的方式,很多公司已经开始投入开发使用自己的低代码平台了,作为一个前端人员,我也想尝试开发一个自己的低代码平台。
市面上常见的低代码平台一般都是由编辑区、组件栏、属性栏和工具栏四部分组成的。下面我们从编辑区开始介绍:
编辑区
编辑区本质上的作用是将从组件栏中拖拽出的组件渲染出来。因此,我最先想采用的方法便是用数组将拖拽出的组件用push方法存储到数组components中并使用v-for逐个遍历渲染。
<component
v-for="item in componentData"
:key="item.id"
:is="item.component"
:style="item.style"
:propValue="item.propValue"
/>
其中组件的数据采用json的形式来存储
{
component: 'v-text', // 组件名称,需要提前注册到 Vue
label: '文字', // 左侧组件列表中显示的名字
propValue: '文字', // 组件所使用的值
icon: 'el-icon-edit', // 左侧组件列表中显示的名字
animations: [], // 动画列表
events: {}, // 事件列表
style: { // 组件样式
width: 200,
height: 33,
fontSize: 14,
fontWeight: 500,
lineHeight: '',
letterSpacing: 0,
textAlign: '',
color: '',
},
}
在遍历 componentData 组件数据时,主要靠 is 属性来识别出真正要渲染的是哪个组件。
例如要渲染的组件数据是 { component: 'v-text' },则 <component :is="item.component" /> 会被转换为 <v-text />。当然,这个组件也要提前注册到 Vue 中。
自定义组件
即将组件封装并暴露一个属性propValue来接收相关的参数,封住组件可以使后续渲染组件时使代码简洁清晰。
<template>
<button class="v-button">{{ propValue }}</button>
</template>
<script>
export default {
props: {
propValue: {
type: String,
default: '',
},
element: {
type: Object,
default: () => {},
},
},
}
</script>
组件栏
顾名思义,就是存放自定义组件的区域。简单来讲就是将存储组件数据的数组componentList渲染出来即可。
<div class="component-list" @dragstart="handleDragStart">
<div
v-for="(item, index) in componentList"
:key="index"
class="list"
draggable
:data-index="index"
>
<span class="iconfont" :class="'icon-' + item.icon"></span>
</div>
</div>
实现拖拽
你已经实现了编辑区和组件了,现在可以考虑如何将他们组合在一起了
一个元素如果要设为可拖拽,必须给它添加一个 draggable 属性。另外,在将组件列表中的组件拖拽到画布中,还有两个事件是起到关键作用的:
dragstart事件,在拖拽刚开始时触发。它主要用于将拖拽的组件信息传递给画布。drop事件,在拖拽结束时触发。主要用于接收拖拽的组件信息。 这里使用dataTransfer.setData()传输数据
<div @dragstart="handleDragStart" class="component-list">
<div v-for="(item, index) in componentList" :key="index" class="list" draggable :data-index="index">
<i :class="item.icon"></i>
<span>{{ item.label }}</span>
</div>
</div>
handleDragStart(e) {
e.dataTransfer.setData('index', e.target.dataset.index)
}
使用 dataTransfer.getData() 接收传输过来的索引数据
<div class="content" @drop="handleDrop" @dragover="handleDragOver" @click="deselectCurComponent">
<Editor />
</div>
handleDrop(e) {
e.preventDefault()
e.stopPropagation()
const component = deepCopy(componentList[e.dataTransfer.getData('index')])
this.$store.commit('addComponent', component)
}
总结
本文简单介绍了如何实现将组件从组件栏拖拽到编辑区并渲染出来,由于本人技术水平有待提升,可能本文所描述的方法不是最好的或高效的,如果有更好的实现方式希望大家能分享一下。