hi, 大家好, 我是徐小夕.
之前一直在社区分享零代码&低代码的技术实践,也陆陆续续设计并开发了多款可视化搭建产品,比如:
最近终于设计出了橙子试卷商业模式的最终方案, 我会在接下来的内容中和大家介绍。
橙子试卷主要用于可视化的搭建表单, 试卷等场景, 让不懂技术的人也能拖拽式创建自己的表单和试卷.
上线测试了2个月,目前已经有500+用户使用,也做了很多使用的表单问卷模板:
为了让更多个体和中小企业能拥有自己的表单问卷搭建系统,我最近设计了私有化部署服务,提供源码授权 + 技术培训,价格定位在4999元,如果感兴趣可以在文章末尾联系交流。
接下来和大家分享一下橙子试卷的技术架构和技术实现, 如果你也在调研零代码
, 低代码
, 或者表单引擎
等技术, 那么这篇文章也许可以给你带来一些灵感.
体验地址: https://turntip.cn/form-engine
文末会附技术交流wx, 感兴趣的朋友可以加入交流讨论.
之前在开发 H5-dooring
零代码搭建平台时我采用的是React
技术栈, 因为用 react
写复杂逻辑会更顺手, 好在 vue3
也支持了函数式的写法, 也提供了 hooks
机制, 让我们写逻辑驱动的应用更加方便, 所以橙子试卷 采用了国内最流行的 vue3
作为前端框架. 具体技术栈如下:
当然还有一些第三方组件这里就不一一介绍了. 我们的核心在于从零完整设计一套 MVP
的零代码搭建引擎, 所以后端部分, 大家可以替换成自己熟悉的 java
, go
, python
等语言.
因为零代码表单引擎设计的核心是如何构造一套低成本且可扩展的组件库, 并快速应用到实际业务场景, 所以设计的核心就包括如下部分:
DSL
数据结构和数据规范接下来我会详细介绍这几块的技术实现, 当然实现思想和技术栈无关, 我们仍然可以把它应用到不同的技术体系中.
因为我们的搭建场景是问卷
, 试卷
, 微页面
, 所以组件库会围绕表单来扩展, 比如常用的:
等等, 这些组件当然不能满足所有客户的业务场景, 所以我们要设计一种可扩展组件库, 并且开发成本较低的方案.
我们可以参考常见的低代码平台的设计思路:
简言之就是把核心UI和逻辑作为组件的主文件, 同时暴露标准的
的 可配置属性和可配置逻辑.
之所以强调“标准”, 是为了让不同组件能共用一套属性配置引擎
, 从而让组件二开的成本大大降低(专注于组件的开发, 而不是配置的兼容).
其次为了尽可能让组件的配置更灵活, 我们需要提供一套标准的组件默认属性, 让用户可以根据默认属性来配置自己的个性化的样式, 那么我们的组件就需要这么来设计:
这里以橙子试卷的文本组件
给大家举个例子.
文本组件的主文件:
<template>
<div
:class="{
text: true,
justify: editorStore.data[index].align == 'justify',
[editorStore.data[index].animation]: true,
}"
:style="{
paddingTop: editorStore.data[index].padding[0] + 'px',
paddingRight: editorStore.data[index].padding[1] + 'px',
paddingBottom: editorStore.data[index].padding[2] + 'px',
paddingLeft: editorStore.data[index].padding[3] + 'px',
color: editorStore.data[index].titleColor,
fontSize: editorStore.data[index].titleSize + 'px',
fontWeight: editorStore.data[index].titleWeight,
textAlign: editorStore.data[index].align,
animationDelay: editorStore.data[index].delay,
animationIterationCount: editorStore.data[index].number,
cursor: 'pointer',
}"
@click="jump(editorStore.data[index].link)"
>
{{ editorStore.data[index].titleText }}
</div>
</template>
<script setup lang="ts">
import { useEditorStore } from "@/store";
const editorStore = useEditorStore();
const jump = (link: string) => {
window.location.href = link;
};
defineProps(["index"]);
</script>
文本组件的可配置属性:
export default class Text {
component: TextPropType;
constructor(id: string) {
this.component = {
component: 'text',
type:'editor.text',
id,
check: true,
titleText: 'https://turntip.cn/form-engine',
titleColor: 'black',
titleSize:16,
titleWeight:'500',
padding: [0, 0, 0, 0],
margin: [10, 10, 10, 10],
animation:'',
direction: 'center',
link:'https://turntip.cn/formManager',
delay:2,
attrbite: [
{
name: 'editor.titleText',
field: 'titleText',
component: 'textarea'
},
{
name: 'editor.padding',
field: 'padding',
component: "padding",
props: {
min: 0,
type:'padding'
}
},
{
name: 'editor.margin',
field: 'margin',
component: "padding",
props: {
min: 0,
type:'margin'
}
},
]
}
}
}
通过这种方式, 我们只需要根据业务需求实现自己的组件, 编写组件可配置的属性json
, 即可通过配置引擎来动态生成组件的可编辑面板, 从而让非技术人员轻松编辑组件.
通过以上的方式, 我们可以轻松开发各种自定义的组件, 提供给用户使用:
对于表单场景, 我们不需要特别复杂的布局交互, 所以这里我才用拖拽排序来实现页面的搭建, 同时支持组件快捷复制和删除.
目前 vue3
的比较成熟的拖拽组件有:
这里选择vuedraggable
来实现拖拽排序, 并对其进行上层封装, 实现体验更好的组件搭建排序效果.
当然还有很多优秀的拖拽库, 如果大家对vue3-draggable-resizable
感兴趣, 也可以试试, 它支持网格布局和自由布局, 可以实现更自由的布局搭建效果:
在组件库设计中我们为了统一管理和维护组件和组件的属性配置, 需要定义统一化的 DSL
结构, 这个结构包含了组件的如下信息:
后4个都好理解, 这里介绍一下组件元数据
, 它的价值在于定义组件的基本信息:
通过对 元信息
的定义, 我们可以很方便的建立更系统的组件库, 比如支持组件分类, 组件版本切换, 组件加载(通过路径元信息来加载远程组件
).
所以我们需要尽可能规范统一的定义组件的通用规则和自定义规范, 以便让不同组件都遵行统一的规则来实现零代码搭建引擎
的设计.
这里还是以橙子试卷为例子, 来介绍一下我们统一的DSL
:
首先我们看看文本的元信息:
{
name: 'editor.text', // 组件名称
component: IconLanguage, // 组件图标
type: 'text' // 组件类型
}
这是一个简单的元信息, 它可以帮我们快速识别组件, 并为画布提供组件更具体的渲染信息, 不同组件都通过统一的配置来定义, 可以让我们的渲染器更加高效的渲染组件, 并降低组件维护成本.
在介绍组件的内容中我已经介绍了组件接受的 json
配置结构, 这里分享一个由多个组件组成的完整页面的 DSL
结构和实际代码:
案例代码:
{
"id": "5137706621235472",
"title": "2024前端笔试题",
"author": "徐小夕",
"desc": "页面描述",
"icon": "",
"bgColor": "",
"bgImage": "",
"isLogin": false,
"data": [
{
"component": "sign",
"type": "editor.sign",
"id": "JelhSP",
"check": false,
"titleText": "请在此处签名",
"titleColor": "black",
"margin": [
10,
10,
10,
10
],
"limit": 1,
"btnColor": "#165DFF",
"titleSize": 15,
"titleWeight": "500",
"analysis": ""
},
{
"component": "math",
"type": "editor.math",
"id": "3-U9XA",
"check": true,
"titleText": "数学题目:5^9>\\pi",
"titleColor": "#D41C1C",
"options": [
{
"label": "A",
"value": "苹果"
},
{
"label": "B",
"value": "香蕉"
}
],
"symbol": "A,B,C...",
"direction": "horizontal",
"optionsColor": "black",
"analysis": "",
"auto": "",
"margin": [
10,
10,
10,
10
],
"scores": 0,
"required": false
},
]
}
有了以上的统一 DSL
结构, 我们就可以轻松通过 JSON
来渲染页面, 同时也有更多的想象空间, 比如:
一个可视化零代码解决方案一定包含完整的用户使用链路, 即从搭建到投放再到信息收集的完整分析链路.
当然不同的公司业务分析需求不同, 所以需要支持纯粹的数据收集和流转, 以便供不同业务使用.
目前橙子试卷提供了一套完整的数据收集能力, 对于试卷场景, 也提供了自动打分机制, 可以一键分析数据情况:
当然这都是可以基于自身规则自己二次开发的, 橙子试卷 只是提供了一套案例参考.
体验地址: https://turntip.cn/form-engine