CC 咖啡猫的工作空间 Coding Space

低代码与无代码

低代码不是"不用写代码",而是"只写必要的代码"——把重复的、模板化的、可配置的部分交给平台,把独特的、复杂的、差异化的部分留给开发者。


1. 概念辨析

1.1 什么是低代码 / 无代码

概念 英文 目标用户 写代码量 典型场景
无代码 No-Code 业务人员(零技术背景) 0 表单收集、简单审批流、数据展示
低代码 Low-Code 专业开发者 + 技术型业务人员 少量(核心逻辑、复杂交互) 后台管理系统、CRM、ERP、中台

关键区别:无代码追求"可视化拖拽完成一切";低代码承认"有些场景必须写代码",但尽量减少代码量。

一句话总结:无代码是给业务人员用的 Excel 升级版;低代码是给开发者用的效率工具。

1.2 发展脉络

1990s          2000s          2014          2018+          2022+
│              │              │              │              │
RAD 工具       BPM 工作流     Forrester 提出 国内外平台爆发   AI + 低代码
(PowerBuilder  (流程引擎)     "Low-Code"    OutSystems      Copilot/通义
 Oracle Forms)                概念诞生       Mendix/宜搭     灵码集成

为什么现在火

  • 企业数字化转型需求井喷,但程序员供给远不足
  • 后台管理系统高度同质化(90% 是增删改查 + 审批流)
  • 前端框架成熟,为低代码引擎提供了基础设施

2. 核心原理:低代码平台是怎么跑起来的

2.1 整体架构

┌─────────────────────────────────────────────────────┐
│                    设计器(Designer)                 │
│  拖拽组件 → 配置属性 → 编排逻辑 → 实时预览            │
└────────────────────┬────────────────────────────────┘
                     │ 产出 Schema(JSON)
                     ▼
┌─────────────────────────────────────────────────────┐
│                   引擎(Engine)                      │
│  解析 Schema → 渲染组件 → 执行逻辑 → 管理状态         │
└────────────────────┬────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────┐
│                  物料(Materials)                    │
│  组件库(表格/表单/图表)+ 区块模板 + 页面模板         │
└─────────────────────────────────────────────────────┘

三个核心角色

角色 干什么 类比
设计器 可视化编辑界面,拖拽搭建页面 Figma / Photoshop
引擎 解析设计器产出的配置,渲染成真实页面 浏览器渲染引擎
物料 可被设计器使用的组件/模板/区块 设计组件库

2.2 协议:Schema(页面描述规范)

低代码平台的核心是 Schema——一份 JSON,完整描述一个页面长什么样、有哪些交互、数据从哪里来。

{
  "componentName": "Page",
  "props": { "title": "用户管理" },
  "children": [
    {
      "componentName": "SearchForm",
      "props": {
        "fields": [
          { "name": "keyword", "label": "关键词", "type": "input" },
          { "name": "status", "label": "状态", "type": "select",
            "options": [
              { "label": "启用", "value": 1 },
              { "label": "禁用", "value": 0 }
            ]
          }
        ],
        "onSearch": { "type": "ref", "target": "userTable.refresh" }
      }
    },
    {
      "componentName": "Table",
      "id": "userTable",
      "props": {
        "columns": [
          { "key": "name", "title": "姓名" },
          { "key": "email", "title": "邮箱" },
          { "key": "status", "title": "状态",
            "render": { "type": "tag", "map": { "1": "启用", "0": "禁用" } }
          }
        ],
        "dataSource": { "type": "api", "url": "/api/users", "method": "GET" },
        "pagination": { "pageSize": 20 }
      }
    }
  ]
}

Schema 的本质:用声明式数据结构替代命令式代码。相当于"用 JSON 写 React/Vue 组件"。

常见协议标准

  • 阿里巴巴 LowCodeEngine 规范:国内事实标准,组件可跨平台复用
  • App Router / Amis:百度开源的 JSON 渲染方案
  • 各厂家自研协议:宜搭、明道云、轻流各自定义了私有 Schema

2.3 引擎:如何把 Schema 变成真实页面

引擎是低代码平台的运行时核心,一个极简版引擎的实现:

// 引擎核心:递归渲染组件树
class LowCodeEngine {
  constructor(components) {
    // components: 注册的物料组件映射表
    // { "Button": ButtonComponent, "Table": TableComponent, ... }
    this.components = components;
  }

  // 解析并渲染 Schema
  render(schema, context) {
    const { componentName, props, children, id } = schema;

    // 1. 查找对应的 React/Vue 组件
    const Component = this.components[componentName];
    if (!Component) {
      console.warn(`未注册组件: ${componentName}`);
      return null;
    }

    // 2. 解析 props 中的表达式/数据源/事件绑定
    const resolvedProps = this.resolveProps(props, context);

    // 3. 处理事件绑定(onClick → 真实函数)
    const eventProps = this.resolveEvents(props, context);

    // 4. 递归渲染子组件
    const renderedChildren = children?.map(child =>
      this.render(child, context)
    );

    // 5. 返回真实 VNode
    return h(Component, {
      ...resolvedProps,
      ...eventProps,
      key: id,
    }, renderedChildren);
  }

  // 解析属性中的动态表达式
  resolveProps(props, context) {
    const result = {};
    for (const [key, value] of Object.entries(props)) {
      // 处理 JS 表达式: { "type": "expression", "code": "state.total * 100" }
      if (value?.type === 'expression') {
        // 在沙箱中执行表达式,注入 state/props/context
        result[key] = this.evaluateExpression(value.code, context);
      }
      // 处理数据源: { "type": "api", "url": "/api/users" }
      else if (value?.type === 'api') {
        result[key] = this.resolveDataSource(value, context);
      }
      // 普通值直接使用
      else {
        result[key] = value;
      }
    }
    return result;
  }

  // 在安全沙箱中执行表达式
  evaluateExpression(code, context) {
    const sandbox = { state: context.state, $ctx: context };
    const fn = new Function(...Object.keys(sandbox), `return (${code})`);
    return fn(...Object.values(sandbox));
  }

  // 解析数据源(API / 变量 / 引用)
  async resolveDataSource(ds, context) {
    if (ds.type === 'api') {
      const res = await fetch(ds.url, { method: ds.method || 'GET' });
      return res.json();
    }
    if (ds.type === 'variable') {
      return context.state[ds.key];
    }
  }

  // 事件绑定转换为真实函数
  resolveEvents(props, context) {
    const events = {};
    for (const [key, value] of Object.entries(props)) {
      if (key.startsWith('on') && typeof value === 'object') {
        // { "type": "action", "action": "openModal", "params": {...} }
        events[key] = () => context.actions[value.action]?.(value.params);
      }
    }
    return events;
  }
}

引擎要解决的核心问题

问题 解决方案
组件如何注册和发现 物料中心:组件元数据 + npm 包映射
Schema 到组件的映射 按 componentName 动态查找并渲染
动态表单/表格 通过配置驱动(columns/fields 数组 → 组件渲染)
组件间通信 全局状态 Store + 事件总线 + 数据源引用
表达式/逻辑 沙箱执行(new Function / eval),注入上下文
布局 内置布局组件(Row/Col/Tab/Card),嵌套渲染

2.4 设计器:可视化搭建怎么实现

设计器界面的三个核心区域:

┌──────────────┬──────────────────┬──────────────┐
│   物料面板    │                  │   属性面板    │
│              │                  │              │
│ 📦 基础组件   │   画布 Canvas     │ 组件名称      │
│  - Button    │                  │ 尺寸/颜色     │
│  - Input     │   [拖拽放置区域]   │ 数据绑定      │
│  - Table     │                  │ 事件配置      │
│              │   实时预览效果     │ 条件渲染      │
│ 📦 布局组件   │                  │              │
│  - Row/Col   │                  │              │
│  - Card      │                  │              │
│              │                  │              │
│ 📦 业务组件   │                  │              │
│  - UserSelect│                  │              │
└──────────────┴──────────────────┴──────────────┘

拖拽的实现(以 React DnD 为例):

// 拖拽的基本流程
// 1. 物料面板中的组件标记为 DragSource
// 2. 画布区域标记为 DropTarget
// 3. 放置时,往 Schema JSON 中插入新节点,引擎即时渲染

// 简化示意
function Canvas() {
  const [schema, setSchema] = useState(initialSchema);

  const handleDrop = (componentMeta, position) => {
    // 在 Schema 树中插入新节点
    const newNode = createNode(componentMeta);
    const newSchema = insertNode(schema, newNode, position);
    setSchema(newSchema);
    // 引擎立即根据新 Schema 重新渲染
  };

  return (
    <DropTarget onDrop={handleDrop}>
      <Engine schema={schema} />
    </DropTarget>
  );
}

属性面板的核心:根据组件元数据动态生成配置表单。

// 组件的元数据描述
const ButtonMeta = {
  componentName: 'Button',
  props: [
    { name: 'text', label: '按钮文字', type: 'string', default: '确定' },
    { name: 'type', label: '类型', type: 'select',
      options: ['primary', 'default', 'danger', 'link'] },
    { name: 'size', label: '尺寸', type: 'select',
      options: ['large', 'middle', 'small'] },
    { name: 'disabled', label: '是否禁用', type: 'boolean', default: false },
    // 高级配置
    { name: 'visible', label: '条件可见', type: 'expression',
      placeholder: "{{ state.status === 'active' }}" },
    { name: 'onClick', label: '点击事件', type: 'event' },
  ],
};

// 属性面板根据元数据动态渲染表单
function PropsEditor({ meta, value, onChange }) {
  return (
    <Form>
      {meta.props.map(prop => (
        <FormItem key={prop.name} label={prop.label}>
          {prop.type === 'string' && <Input value={value[prop.name]} />}
          {prop.type === 'select' && <Select options={prop.options} />}
          {prop.type === 'boolean' && <Switch checked={value[prop.name]} />}
          {prop.type === 'expression' && (
            <CodeEditor language="javascript" placeholder={prop.placeholder} />
          )}
          {prop.type === 'event' && <EventHandler config={value[prop.name]} />}
        </FormItem>
      ))}
    </Form>
  );
}

2.5 出码:Schema 如何变成真实代码

低代码平台的三种出码策略:

策略 做法 优点 缺点
运行时解析 Schema 保存到数据库,引擎运行时动态渲染 修改即时生效、无需构建 性能有损耗、SEO 不友好
编译出码 Schema → 源码(React/Vue 文件)→ 构建部署 性能最优、可独立部署 每次修改需要重新出码+构建
混合模式 核心页面出码部署,动态页面运行时渲染 灵活平衡 架构复杂度更高

编译出码的本质:Schema JSON → AST → 代码字符串。

// Schema 片段
const schema = {
  componentName: 'Page',
  children: [
    { componentName: 'Button', props: { text: '提交', type: 'primary' } }
  ]
};

// 出码结果
// import { Button } from 'antd';
// export default function Page() {
//   return <Button type="primary">提交</Button>;
// }

// 出码器的核心是一个递归的代码生成器
function generateCode(schema) {
  const { componentName, props, children } = schema;

  // 1. 属性转代码字符串
  const propsStr = generateProps(props);

  // 2. 子组件递归生成
  const childrenStr = children?.map(generateCode).join('\n') || '';

  // 3. 拼接 JSX
  return `<${componentName}${propsStr}>${childrenStr}</${componentName}>`;
}

3. 主流平台与方案

3.1 国内外平台全景

平台 类型 开源 特点 适用场景
OutSystems 低代码 企业级、强建模、全栈 大型企业核心系统
Mendix 低代码 云原生、模型驱动、协作能力强 中大型企业
Retool 低代码 面向开发者、组件丰富、快速搭建内部工具 内部工具/管理后台
Appsmith 低代码 Retool 开源替代、自部署 内部工具/数据面板
阿里 LowCodeEngine 低代码引擎 引擎级开源、可自建平台 二次开发/自建低代码平台
宜搭 低代码 阿里出品、钉钉深度集成 企业内部应用
简道云 无代码 帆软出品、表单流程强 数据收集/审批流
明道云 无代码 零代码 APaaS、工作表驱动 中小企业全套业务系统
飞书多维表格 无代码 表格界面、AirTable 竞品 轻量级协作管理
微搭 低代码 腾讯出品、微信生态集成 小程序/企业微信应用
轻流 无代码 BPM 流程引擎突出 审批流/业务流程
Zion 无代码 国内首个在线教育型无代码平台 小程序/H5 快速搭建

3.2 开源引擎方案对比

引擎 组织 技术栈 核心思路 是否支持出码
LowCodeEngine 阿里 React + Node 引擎 + 设计器分离,物料可插拔
Amis 百度 React JSON 配置渲染,零设计器依赖 否(纯运行时)
Formily 阿里 React/Vue 表单领域低代码,解决复杂表单场景
PagePlug 社区 Vue Appsmith 的 Vue 版
ToolJet 社区 React 开源低代码,自部署
NocoDB 社区 Vue AirTable 开源替代
Budibase 社区 Svelte 开源低代码,全栈

3.3 Amis:JSON 配置即页面

百度 Amis 是"运行时解析式"低代码的典型代表——不产出源码,JSON 直接即是运行中的页面。

{
  "type": "page",
  "title": "用户管理",
  "body": [
    {
      "type": "crud",
      "api": "/api/users",
      "columns": [
        { "name": "id", "label": "ID" },
        { "name": "name", "label": "姓名" },
        { "name": "email", "label": "邮箱" },
        {
          "name": "status",
          "label": "状态",
          "type": "mapping",
          "map": { "1": "<span class='text-success'>启用</span>", "0": "<span class='text-danger'>禁用</span>" }
        }
      ],
      "filter": {
        "body": [
          { "type": "input-text", "name": "keyword", "label": "关键词", "placeholder": "搜索姓名/邮箱" },
          { "type": "select", "name": "status", "label": "状态", "options": [{"label": "启用","value":1},{"label": "禁用","value":0}] }
        ]
      }
    }
  ]
}

核心设计思想

  • 一切皆组件:页面是组件、表单是组件、表格是组件、按钮也是组件
  • 每个组件有 type 字段声明自己的类型
  • 组件通过嵌套(body / columns / filter)形成树状结构
  • 引擎按 type 查找对应 React 组件并渲染

Amis 的适用边界

  • ✅ 标准后台 CRUD 页面 —— 极快,JSON 写完即上线
  • ✅ 表单密集型场景 —— 120+ 表单组件开箱即用
  • ❌ 高度定制 UI —— JSON 配置无法替代 CSS 像素级调整
  • ❌ 复杂交互逻辑 —— 联级联动超出 3 层时 JSON 配置痛苦

4. 后端低代码怎么工作

低代码不只是前端的事——后端逻辑同样需要"低代码化"。

4.1 数据模型驱动

传统开发流程:数据库建表 → 写后端代码 → 写接口 → 写前端页面

低代码流程:  在界面上定义数据模型 → 自动生成数据表 + CRUD 接口 + 默认页面
# 在一个低代码平台上定义"客户"数据模型
模型名称: Customer
字段:
  - name: string(50), 必填, 显示名="客户名称"
  - contact: string(20), 显示名="联系电话"
  - level: enum(普通/VIP/SVIP), 默认="普通"
  - source: string(100), 显示名="客户来源"
  - created_at: datetime, 自动填充=当前时间

平台根据这个模型自动生成:

  • 数据库表 customer
  • REST 接口:GET/POST/PUT/DELETE /api/customers
  • 默认列表页 + 详情页 + 表单页

4.2 流程引擎

审批流和业务流程是低代码的核心场景:

请假审批流程:

  员工提交 ──→ 部门主管审批 ──→ 人事审批 ──→ 归档
               │                 │
               └── 驳回 ─────────┘ (回到提交人)
# 低代码平台中的流程定义(BPMN 简化版)
流程名称: 请假审批
触发条件: 新增请假记录
节点:
  - 节点1: 部门主管审批
      审批人: ${当前用户.直属上级}
      审批方式: 或签(任意一人通过即可)
      超时: 48小时自动通过
      分支:
        - 通过 → 节点2
        - 驳回 → 结束(通知提交人)

  - 节点2: 人事审批
      审批人: HR部门所有人
      审批方式: 会签(所有人通过)
      分支:
        - 通过 → 节点3
        - 驳回 → 节点1(退回到上一步)

  - 节点3: 归档
      自动操作:
        - 更新请假记录状态 = 已通过
        - 扣减年假余额 -${请假天数}
        - 发送通知给提交人

流程引擎的核心机制

概念 说明
节点 流程中的一个步骤(审批/填写/分支/自动操作)
流转条件 决定从当前节点走向哪个节点的规则
审批人解析 支持固定人/角色/部门/上级/脚本动态计算
会签/或签 会签=所有人都要审批;或签=任一人审批即可
超时处理 超时后自动通过/驳回/转交
回退/取回 支持退回到任意已处理节点
流程版本 修改流程定义时,已运行的实例不受影响

4.3 逻辑编排

对于"获取数据 → 处理 → 写入"这类逻辑,低代码平台提供可视化函数编排

                    ┌─────────────┐
触发(HTTP 请求)──→ │ 查询用户信息  │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐       是
                    │ 是否为VIP?   │────────→ 计算折扣 20%
                    └──────┬──────┘
                           │ 否
                    ┌──────▼──────┐
                    │ 计算折扣 0%  │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │ 生成订单     │
                    └─────────────┘

本质上是把以下代码可视化:

async function createOrder(req) {
  const user = await db.user.findById(req.userId);
  const discount = user.level === 'VIP' ? 0.2 : 0;
  return db.order.create({ ...req.body, discount });
}

5. 低代码 vs 传统开发:什么时候该用

5.1 适用场景

场景 推荐度 原因
后台管理系统(CRUD) ⭐⭐⭐⭐⭐ 高度同质化,低代码效率提升 5-10 倍
表单审批流程 ⭐⭐⭐⭐⭐ 流程引擎开箱即用
数据看板/大屏 ⭐⭐⭐⭐ 图表组件拖拽即可,无需手写 ECharts
内部运营工具 ⭐⭐⭐⭐ 需求多变但不要求 UI 精致
活动落地页 ⭐⭐⭐ 模板化程度高,快速上线
原型验证/MVP ⭐⭐⭐⭐ 快速出可交互版本给老板/客户看
移动端简单应用 ⭐⭐⭐ 配合小程序容器可以快速出 App

5.2 不适用场景

场景 原因
C 端高交互产品(电商首页、社交App) UI 定制化极高,低代码无法做到像素级还原
复杂算法/数据处理 可视化编排效率反而不如直接写代码
已有复杂老系统 改造迁移成本远超收益
高性能场景(游戏、实时协同) 引擎运行时开销不可忽略
需要极致 SEO 运行时解析式低代码对 SEO 不友好
对稳定性要求极高的核心系统 低代码平台的 Bug 不在你掌控范围内

5.3 决策框架

这个功能/页面适合用低代码吗?

├─ 是不是增删改查 + 表格 + 表单?
│  └─ 是 → 用低代码(效率碾压手写)
│
├─ 是不是审批流 / 工作流?
│  └─ 是 → 用低代码的流程引擎
│
├─ UI 是否要求像素级定制?
│  └─ 是 → 必须手写(低代码做不到)
│
├─ 有没有复杂的、非标准的前端交互?
│  └─ 是 → 手写,或在低代码中嵌入自定义组件
│
├─ 是否频繁迭代、需求变化快?
│  └─ 是 → 低代码(改配置比重构代码快)
│
└─ 团队是否具备专业前端能力?
   ├─ 有 → 自建或基于开源引擎定制
   └─ 无 → 采购成熟低代码平台

6. 开发者视角:低代码改变了什么

6.1 开发者角色的转变

传统开发者:  手写每一行代码 → 你就是代码的唯一生产者

低代码开发者: 写物料组件 + 写引擎扩展 + 写复杂逻辑 + 解决平台无法覆盖的场景
              └── 你是低代码平台的"增强者",而不是被平台替代

6.2 使用低代码平台的三种姿势

姿势 说明 适合谁
纯用平台 完全在平台上搭建,不写任何代码 业务人员、初级开发者
平台 + 自定义组件 标准功能用平台,特殊需求自己开发组件嵌入 有前端能力的小团队
自建低代码平台 基于开源引擎(LowCodeEngine/Amis)搭建自己的低代码平台 有前端架构能力的大团队

6.3 前端开发者与低代码的关系

前端开发者的价值不会被低代码取代,但会重新分配:

  重复劳动(📉 被替代)          不可替代(📈 价值更高)
  ├─ 手写第 50 个表格页面        ├─ 设计低代码引擎架构
  ├─ 手写第 100 个表单校验       ├─ 开发高质量物料组件
  ├─ 手写标准 CRUD 接口         ├─ 解决低代码平台无法覆盖的复杂场景
  └─ 复制粘贴审批流代码          ├─ 低代码平台 + AI 结合的前沿探索
                                └─ 性能调优、安全加固、定制化改造

建议

  • 初级前端:掌握 1-2 个低代码平台使用,提升交付速度
  • 中高级前端:理解低代码引擎原理,能自建或深度定制
  • 架构师:能判断什么场景用低代码、什么场景手写,做正确的技术选型

7. 发展趋势

趋势 说明
AI + 低代码 自然语言描述需求 → AI 生成 Schema → 平台渲染。Copilot / 通义灵码已开始集成
垂直领域下沉 不再做"通用低代码",而是做"CRM 低代码""供应链低代码""政务低代码"
Pro-Code 打通 平台提供 VS Code 插件,专业开发者在 IDE 中直接编辑 Schema 或出码产物
协作能力增强 产品出原型 → 设计师出设计稿 → 开发者出组件 → 业务人员搭页面,全角色在同一平台协作
混合渲染 出码部署核心页面 + 运行时解析动态页面,兼顾性能和灵活性

8. 动手试一试

平台 上手方式 推荐理由
阿里 LowCodeEngine 官网 Demo 直接体验 + 源码 GitHub 理解引擎原理的最佳入口
Amis 在线编辑器直接写 JSON 看效果 感受 JSON 配置式开发
Appsmith 注册即用,免费 体验完整低代码开发流程
简道云 注册免费版 体验无代码表单+流程

建议学习路径

  1. 先用简道云搭一个请假审批应用(感受无代码)
  2. 再用 Appsmith 搭一个数据看板(感受低代码)
  3. 在 Amis 在线编辑器中写 JSON 配置生成页面(理解 Schema 驱动)
  4. 阅读 LowCodeEngine 源码的 enginedesigner 部分(理解内核)

参考资源