前端笔记 -- 开发低代码平台 (一) | 青训营笔记

83 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第十天
最近一直在研究低代码平台,于是想写篇文章记录一下。
我所使用的技术栈是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 属性。另外,在将组件列表中的组件拖拽到画布中,还有两个事件是起到关键作用的:

  1. dragstart 事件,在拖拽刚开始时触发。它主要用于将拖拽的组件信息传递给画布。
  2. 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)
}

总结

本文简单介绍了如何实现将组件从组件栏拖拽到编辑区并渲染出来,由于本人技术水平有待提升,可能本文所描述的方法不是最好的或高效的,如果有更好的实现方式希望大家能分享一下。