Elpis系列之基于DSL快速建站

42 阅读6分钟

引入

看到下面这两张图,是不是异常的熟悉。没错,这就是前端入门必备的中后台管理系统。但对于从事前端开发的你,除了熟悉感以外,是不是还带着一丝丝焦虑:长期从事这种 CRUD 的工作,对前端技术的提升有限。每次新建页面都把原来的代码复制过来修修改改。虽然也沉淀了一些组件,但随着需求迭代,发现也不那么通用。页面虽然相似,但每个页面却又有一些它独立的、不一样的点。

PixPin_2025-12-09_21-45-46.png

图一

PixPin_2025-12-10_10-04-19.png

图二

DSL

简介

DSL - domain specific language -领域特定语言 是一种具有有限的范围的计算机语言,旨在解决应用领域内的特定问题。而我们则是想通过 DSL 快速搭建中后台页面,解决重复性建设问题

架构说明

image.png

图三

如图,使用 DSL,同时借用面向对象的思想,从领域模型A基类(中后台系统的通用性)出发,结合不同项目的特性,拓展出不同的项目配置A-1、A-2...也就是面向对象中的基类与子类的关系。再通过前面文章一文章二 所讲的BFF层和elpis-core,SSR渲染出来不同项目的首页。而首页中的菜单切换,是我们熟能生巧的CSR单页面切换。

图中蓝色、黄色、白色背景块是页面的通用性部分,只需配置,无需开发,可快速搭建,对应领域模型A基类。同时,对于项目中一些独特的需求,我们支持自定义组件,自定义页面,甚至也可以内嵌其他的页面,即图中的绿色背景部分。

详细说明

整个页面的搭建是从一份满足 json-schema 的 json 配置开始的。

以电商系统作为领域模型基类,拼多多电商系统项目作为基类衍生出来的子类为例。看如下这两份 json 配置。左边的为基类,右边为子类。

PixPin_2025-12-10_14-43-35.png

图四

电商系统的操作后台不可避免的会有商品管理、订单管理、客户管理等功能。而拼多多电商管理系统除了这些通用功能外,还有自己特有的数据分析、信息查询功能。

结合图一和图四可以看到,拼多多这份配置,不仅继承了基类,还重载了基类的部分配置,如“商品管理(拼多多)”,如“客户管理(拼多多)”的 customConfig 变为了 schemaConfig。对于完全继承的,如“订单管理”则无需在配置中体现,在代码中会有 merge 操作。

菜单

头部菜单的功能一般是一个菜单组(subMenu)、展示一个完整页面(customConfig、schemaConfig)、展示一个内嵌页面(iframeConfig)、展示侧边菜单,由侧边菜单栏的路由再渲染不同页面(siderConfig),侧边菜单栏的具体菜单又可以重复以上。

menu: [
    // 可递归的 menuItem
    {
      key: "", // 菜单唯一标识
      name: "", // 菜单名称
      menuType: "", // 枚举值:group / module

      // 当 menuType 为 group 时,需要配置 subMenu,可选
      subMenu: [
        {
          // 可递归的 menuItem
        },
      ],

      // 当 menuType 为 module 时,需要配置 moduleType,可选
      moduleType: "", // 枚举值:sider / iframe / custom / schema

      // 当 moduleType 为 sider 时
      siderConfig: {
        menu: [{}],
      },

      // 当 moduleType 为 iframe 时
      iframeConfig: {
        path: "", // iframe 路径
      },

      // 当 moduleType 为 custom 时
      customConfig: {
        path: "", // 自定义路由路径
      },

      // 当 moduleType 为 schema 时
      schemaConfig: {
      }
    },
  ],

通过以上这份配置,就可以很好地把菜单渲染出来,具体的代码逻辑在这就不展示了。其中,customConfig 是用来编写项目的特有页面,需要独自开发。而要搭建通用的页面,需要使用到schemaConfig

页面与组件

管理系统中,上边的搜索表单、下边的展示表格、右边弹出的新增或详情抽屉,其实来来回回都是操作的同一些字段、同一份数据源,同一张数据库表(这儿不涉及连表查询),因此我们可以在一份 schemaConfig 配置中抽象出来。 schemaConfig + 对应的解析器就可以搭建一个页面。 image.png

图五

schemaConfig 中的配置,大概有以下几个部分。详见这里

  • 数据源API
    • 管理系统中的 CRUD 对应post、get、put、delete 请求,因此只需要一个遵循 RESTFUL 规范 api 路径即可满足操作
  • 一份拓展的 schema 配置
    • 满足 json-schema 规范,可以用来做表单校验
    • 除了标准的 json-schema 配置后,还进行了一些扩展。因为如上所说,操作的是同一份数据源。所以,以商品名称为例
      • 如果需要在搜索表单中展示,配置 searchOption
      • 如果需要在展示表格中展示,配置 tableOption
      • 如果需要在新增商品的表单(右侧弹出抽屉)中展示,配置 createFormOption
      • 如果需要在修改商品的表单(右侧弹出抽屉)中展示,配置 editFormOption
      • 如果需要在商品详情的抽屉中展示,配置 detailPanelOption
      • 在这些 option 中,
        • 首先需要定义使用哪种组件,常见的如input、inputNumber、select、dynamicSelect等
        • 其次可以使用 element-plus 的相关配置。无需一一实现,通过 v-bind 绑定
        • 可以扩展配置,如用 visible 设置某个字段不可见;用 enumList 表示使用 select 时的下拉枚举

除了这份数据的配置外,还需要满足组件本身的一些配置

  • 如展示表格上有些按钮,表格中行数据也有按钮,点击按钮会触发相应的事件。因此需要在 tableConfig 配置 headerButtons 和 rowButtons
  • 如动态组件 createForm 和 editForm 中要展示标题和按钮文案。因此需要在 componentConfig 进行配置 createForm 和 editForm 的 title 和 saveBtnText。editForm 还需要一个请求数据的唯一标识 mainKey

有了 schemaConfig 配置和对应的解析器(图五),这个页面也就搭建出来了。后续,除非有新增的组件,需要对解析器进行拓展而修改代码。否则,只需要这么一份配置,就可以渲染出来一个页面,各字段都可以配置。

不止于此

但这份配置的功能可远远不至于搭建一个前端页面。配置中,有字段有了,有字段类型,有对应的校验,服务端完全可以通过这份配置进行接口定义和数据库表建立。这也是为什么不使用用 element-plus 的表单校验功能,通过这份配置,前后端的校验可保持一致。

总结

至此,算是了解了 “哲玄前端”-《大前端全栈实践课》的核心思想。

  1. 80%配置减少CRUD体力活
    • 这不仅仅是一份配置,是一整个板块。前端、后端、数据库都可从中受益
  2. 20%定制化增加系统的拓展性
    • 基类到具体项目的拓展
    • 菜单功能的拓展
    • 动态组件的拓展
  3. 可推动整个团队基于 Elpis 的思想进行规范设计与开发