前言

Corgi-ICode

制作起因:

在维护类似的管理后台时,总会做一些相似的页面,复制出来之后又要修改、删除等等,很是麻烦呢。

0

后来我写了一个脚本,通过写入一些配置数据,直接通过node编译成vue文件,使用起来倒也,但有缺点就是经常会忘记一些属性,导致经常要翻组件文档。因此打算做一个可视化的编辑器来生成模板。


Corgi-ICode

页面设计和常规的低代码平台类似,左侧是一些组件和模板,中间是拖拽面板,右边是配置面板可以配置选中组件的一些属性、数据。

但区别在于,这个项目只会生成对应的Vue SFC代码,把生成的代码当作页面的基础模板再做后续的业务开发。

涉及到的技术:Vue3ViteElement-plusmonaco-editorvuedraggable

源码地址

在线体验

项目结构
























































































拖拽功能







组件工具













导入组件库







编译







数据维护







历史记录







组件库







一个组件







组件实例







代码模板







配置列表










Packages









UI









Core









Component









DraggableArea









HandleComp









App









Import









Complie









widgetList









historyWidgetList









Element-plus









Input









InputVue









Templates









Options







首先,UI层与组件库并不关联,通过调用Core中的import功能去加载组件库的数据,加载出的数据都维护在Core中,UI引用这些数据进行页面渲染(组件列表、模板列表、组件配置表等),凡是会对主数据造成影响的功能都需要到Core中调用。

Core中维护了操作主要数据的方法以及公用组件,比如 DraggableArea 功能组件,除了UI中的操作区域需要拖拽外,组件库中的FormGridCard等组件也都需要有内部的拖拽功能。

最后组件库,由于UI与组件库并不关联,所以理论上可以兼容Vue3的各种组件库,但由于工作量太大,现在只做了Element-plus

拖拽功能

这里使用了vue.draggable.next来做拖拽功能。

由于是B端项目,没有复杂的页面排版,不需要定位之类的操作,所以只需要维护一个List,并编写一个用于渲染组件的高阶组件即可。

<!-- 组件菜单 -->
<el-collapse-itemv-for="item in menu":key="item.title":title="item.title":name="item.title"
><draggable:list="item.children"item-key="type":sort="false":clone="cloneNewWidget":group="{ name: 'dragGroup', pull: 'clone', put: false }"class="flex justify-between flex-wrap"><template #item="{ element }"><div>{{ element.title }}</div></template></draggable>
</el-collapse-item>

在菜单中调用clone钩子,为拖拽中的组件配置一个唯一的Key,方便之后的组件操作。

 <!-- 操作面板 -->
<draggable:list="list"handle=".moveArea"ghost-class="ghostClass"item-key="key"group="dragGroup"@add="addEnd"
><template v-if="!list.length" #footer><div class="text-center opacity-60 h-40 leading-40">{{ empty || '拖拽区域' }}</div></template><template #item="{ element }"><HandleComp :item="element"><slot :item="element" />b</HandleComp></template>
</draggable>

在拖拽结束后触发事件add,此时就可以拖拽更新后的组件列表全部打上父级的Key,建立父子关系也是方便后续的维护工作。同时也可以进行历史记录的操作,在拖拽完成后在历史记录的List中插入一条新的数据。

结构设计

类似于常规的低代码平台,拖拽、配置完成之后都需要导出一串JSON数据,用于渲染和编译。

// 单个
export interface IWidgetItem {title: string // 标题type: string // 组件类型icon?: FunctionalComponent<SVGAttributes, {}>component?: string // 调用组件名称key: string // 自动生成的keyform: IWidgetItemForm // 属性配置noForm?: boolean // 是否为form下组件children?: IWidgetItem[]parent?: stringvalidateFn?: Function // 表单组件校验方法updateDataFn?: () => void // 用来更新组件内的数据
}export type IWidgetItemForm = Record<string,{label: string // 名称type: keyof typeof IWidgetOptions // 输入组件value: anyisShow?: (options: any) => booleanchangeCb?: (options: any) => void}
>

组件方面定义了其自身的typekeychildren等字段,而对于属性的配置方面,在UI层中创建了如InputSelectCode等用于不同场景的属性配置的输入组件,在一个组件被拖入拖拽面板之后,右侧的配置栏会取得当前活跃组件的form属性配置表,根据每一条属性的type匹配到对应的输入组件,然后再进行每条属性的组件渲染。

组件库加载到的组件配置表

input的配置面板

右侧配置面板中每条属性的改动都需要记录到属性的value字段,同时会体现在拖拽面板中。

将每个必要属性配置完成后就会得到一条IWidgetItem[]形式的数据。

模板编译

IWidgetItem[]进行遍历,通过每一个组件的组件名找到预先在组件库中编写好的编译函数,传入配置的属性值、表单属性等信息,生成模板数据

/*** 编译函数* options:配置的属性* formDataName:父级form 的key*/
export type renderWidgetCode = (options: Record<string, any>, formDataName?: string) => {template: string | ((arg: string) => string)  // 代码模板formData?: Record<string, any>                // 该组件内用到的formData字段privateVar?: Record<string, any>              // 组件内的私有变量formDataName?: string                         // 父级form 的keyimportList?: Record<string, any>              // 组件内的引入列表componentName?: string                        // 子组件名称componentTemplate?: string                    // 子组件的模板endScript?: string                            // 其他代码 hooks等
}
const run: renderWidgetCode = (options, _formDataName) => {const attrs = ['type','placeholder','clearable','maxlength','minlength','showWordLimit',]const attrsStr = attrs.map(attr => formatArrt(attr, options[attr])).filter(Boolean).join(' ')return {formData: {[options._key]: options.value,},template: `<el-form-item label="${options.label}" prop="${options._key}"><el-input${_formDataName ? `v-model="${_formDataName}.${options._key}"` : ''}${attrsStr}/></el-form-item>`,}
}

之后就是将各个组件所生成的数据结果进行混合,最终都生成String拼装在一起。

const baseTemplate = `<template>${templateStr}</template><script setup>${importListStr + formDataStr + validateListStr + widgetVariableStr + endScript}</script>`

写在最后

本项目的初衷就是做一个简单的可视化的代码模板编辑器,所以最后生成的代码会比较简陋,还需要后续再进行弥补。

如果真要做成低代码的形式还需要后台的支持,编写更多更完整的组件。(但是我真的不喜欢低代码)

因为项目是用Vue3写的,所以最后生成的代码是Vue3 setup形式的,而作者本人在公司维护的一直是Vue2 Options形式的代码,所以这个工具也用不上

Corgi-ICode —— 帮你少写点代码相关推荐

  1. mybatisgenerator使用_MyBatis Generator,帮你少写50%代码的自动化工具,你用过吗?

    GitHub地址 https://github.com/erlieStar/mybatis-generator-demo 介绍 MyBatis Generator的作用就是根据数据库中的表结构,帮我们 ...

  2. 多些时间能少写些代码(转自酷壳 – CoolShell.cn)

    我在我的微博上说过这样一段话,我想在这里把我的这个观点阐述地更完整一些. @左耳朵耗子:聪明的程序员使用50%-70%的时间用来思考,尝试和权衡各种设计和实现,而用30% – 50%的时间是在忙碌着编 ...

  3. 多些时间能少写些代码

    我在我的微博上说过这样一段话,我想在这里把我的这个观点阐述地更完整一些. @左耳朵耗子: 聪明的程序员使用50%-70%的时间用来思考,尝试和权衡各种设计和实现,而用30% – 50%的时间是在忙碌着 ...

  4. 微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人

    微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人. 该工具类主要是对dozer进行了封装,使用过程代码量极少,废话少说,贴代码了 import j ...

  5. 微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人...

    微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人. 该工具类主要是对dozer进行了封装,使用过程代码量极少,废话少说,贴代码了 import j ...

  6. 用好idea这几款插件,可以帮你少写30%的代码!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | HeloWxl 来源 | jianshu.com/p/e ...

  7. 帮你少写一大半参数校验代码的小技巧

    介绍 几乎每个web网站都会对用户提交的参数进行校验,前端要做,后端也要做.防止用户直接通过接口调用的方式来请求或保存数据,从而导致产生脏数据等其他严重的后果. 因为有些校验的逻辑也很繁琐,为了减轻开 ...

  8. 这个IDEA插件可以帮你少写30%的代码

    Easycode是idea的一个插件,可以直接对数据的表生成entity,controller,service,dao,mapper,无需任何编码,简单而强大. * 1.安装(EasyCode) 建议 ...

  9. java加密解密代码_java加解密文件公用方法整合(多看一本书,少写三行代码)

    最近接到任务(文件的安全性)需要在文件上传到服务器上时将文件加密保存, 用户下载时将文件解密后返回给用户.翻了下方法最后决定用java中的Cipher类来完成(里面的实现方式挺全的). 上手实现.po ...

  10. 哈哈哈,这个教人写烂代码的项目在 GitHub 上火了...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 如果说到什么是好代码,我们肯定都能说出一堆规则,例如使用一致的格式 ...

最新文章

  1. buffersize越大越好吗_手机运行内存真的越大越好吗?看完长知识了
  2. 最新!中国天气网api接口调用,key获取方式,数据请求秘钥获取,城市id获取方法
  3. 【实战 Ids4】║ 给授权服务器加个锁——HTTPS配置
  4. HTTP协议&SOCKET协议
  5. ARTS打卡第14周
  6. C语言库函数的哈希表使用方法
  7. windows下完美的免费QT开发环境: QtCreator + VC2008Express
  8. python 定时任务 全局变量_APScheduler-Python定时任务
  9. 在线预览word接口
  10. health: HEALTH_WARN
  11. vb中的print方法
  12. MFC 利用小型数据库Access 少步惆 教你用VC开发
  13. Swagger UI 与 Spring Boot 的集成
  14. IBM小型机系统启动顺序
  15. 用Excel制作抽奖软件
  16. vue 移动端点击延迟_vue移动端项目-click事件在浏览器中延迟300ms的解决方法
  17. 扇贝python课程免费_欣赏“旱扇”
  18. 深度摄像头测距原理简介
  19. 作一个执著的人是幸福和难得的
  20. Mybatis-Plugs手册

热门文章

  1. PicSizer-将图片压缩到指定大小(KB)的软件
  2. 魔方怎么更改计算机名,软媒魔方怎么通过设置向导进行设置
  3. 《Qt图形界面编程入门》实验
  4. MySql查询之单表查询 --附练习素材
  5. java分布式包含的技术_Java分布式架构核心技术[SSM组合+ springmvc+mybatis+shiro+restful+bootstrap]...
  6. AMOS分析技术:结构方程模型的拟合度评价指标
  7. 学信网如何通过证件编码查学历
  8. 实验四|Python 企业偿债能力分析
  9. 一只Quant菜鸟的修行之路
  10. Mate30安装谷歌全家桶(20200215,成功)