前端架构
前端架构笔记:整体架构思考,低代码引擎(lowcode-engine)与组件物料化。
前端架构
学技术不能过于专精,需要横向理解,向广度挖掘。
原则
设计原则:架构服务于业务,以提升业务开发效率和体验为目标,配合业务发展齐头并进。 业务原则:稳定性、组织架构配合和成本控制等因素。
业务与架构契合:架构演进能给让业务开发更内聚、协作更顺畅,最终带来业务开发效率和体验带来提升。 成本可控:架构设计不建议憋大招,而应该是一定时间跨度内可落地、可完成的。架构设计应该是可以拆分为多次小的架构演进,然后通过配合业务持续迭代,最终达成设计目标。
架构搭建关注方向
- 模块 / 组件划分、分层的策略和维度;
- 模块 / 组件间通信方案;
- 架构演进中遇到的问题;
- 架构演进过程中使用的工具;
- 防劣化机制;
- 架构演进和业务迭代的合作模式;
- 架构演进的方向
设计考虑
虽然像高并发、负载均衡和容灾等架构设计的核心点在移动端上不存在,但是移动端还是有它自身的重点:
- 组件化:移动端往往是多个团队合力完成同一个 App 的开发工作,为了实现多团队协作,会将 App 拆分为不同的模块,由不同的团队负责不同模块的开发维护工作。同时模块会被构建为中间产物,以组件的形式进行集成,从而加速整体工程的编译速度。使得整体架构方向都在以组件化为承载形式,同时不断缩小业务所需要关心的范围、不断扩大代码复用范围;
- 插件化:随着业务的持续迭代,App 中聚合的功能越来越多,包体积也越变越大,导致用户下载安装体验变差。所以业界也衍生了插件化方案,可以将安装包拆分为宿主和若干插件。用户在应用商店下载时只下载安装宿主部分,其他插件在用户使用到相关功能时再通过网络进行下载,从而解决包大小问题;
- 多 App 复用:业界很多产品在原有 App 的基础上都有衍生出极速版、特价版、或者专业版,通过不同的 App 来服务不同的用户群体。而这些不同的新衍生的 App 和原 App 在很多功能上都是重合的,如果分开开发维护的话,显然需要投入更多的人力资源。所以往往都会考虑实现多 App 复用,使得相同的部分只用进行一次开发,从而提升研发效率;
- 动态化:大多数业务中都会有一些业务层级较深、使用用户较少,或者一些周期较短、时效性很强的业务功能(比如节假日活动等)。这些业务功能如果使用原生的开发方式,需要重新发版,时间点和覆盖率可能无法保障,同时也会导致包 size 增大。所以往往会采用动态化的方式进行开发:比如 H5 网页、Hybrid、RN、小程序等,这样可以实现相应功能的快速迭代,而不需要重新发版
- 多端复用:前面提到了在 Android 或者 iOS 某一平台上的多 App 复用,也提到了动态化能力,往往动态化就是具备同一套代码在 Android 和 iOS 双端实现复用,这样可以极大的提升研发效率。当然除了动态化方案,一些原生方案也可以实现在 Android 和 iOS 双端复用,同时 Flutter 等自建渲染方案可以实现在更多端复用,这也是业界在重点关注的一个方向。
完善与优化
架构优化还是性能优化,都是长周期、持续推进的过程,所以我们也会围绕业务环境去做完善。
- 多端复用:字节内部的信息流产品有今日头条和今日头条极速版两个产品,现在两个产品的代码复用率还可以做进一步的提升,这是后续架构优化的一个重要发力点。这样可以实现更高的开发效率,使得这两个产品可以更加快速的给用户提供更多优质服务。
- 架构优化闭环:头条架构一直在持续优化和演进,解决了大量的业务和技术问题。但现阶段的业务和技术问题发现到架构优化还没有完全形成闭环,还有很多问题没有被挖掘出来,问题的解决程度也无法全面评估。后续会从架构度量指标、架构分析工具建设和防劣化机制 3 个方向着力实现架构优化闭环。
- 架构度量指标:有了架构度量指标后,就可以主动对现有业务和架构进行分析,快速去发现和定位问题,从而进行相应的优化。同时也可以对优化后的结果进行度量,判断问题是否得到了有效解决;
- 架构分析工具:头条在进行架构优化的过程中,往往需要进行大量的分析来发现问题、定位问题和解决问题,而相应的工具能够极大的提高效率。后续会针对性的建设更多的架构分析工具,更好的服务架构演进和业务发展;
- 防劣化机制:由于业务的高速迭代和新同学的加入等原因,头条日常开发过程中也遇到了很多不符合架构设计的代码,这些代码会导致架构出现劣化,缩短架构生命周期。后续会建立更多的防劣化机制,及时发现并拦截这些不合理代码,保障架构能持续正向演进。
- 技术输出:对外输出了大量的技术方案,这一块将会继续加大投入,沉淀和输出更多更优的技术方案,为业界前端技术生态的发展做出贡献。
架构设计注意
技术人还是应该多看看业务,不能只在技术的象牙塔里,同时还要多看看业界的动向,接触业界的专家和经验。
- 全局视角和思维:以全局的视角和思维去发现和审视业务的需求和问题,从而设计出最适合业务的架构;
- 架构配合业务同步发展:
- 架构演进是为了解决业务问题、提升研发质量。因而需要深入业务,了解业务痛点;
- 好的架构是要不断演变去适应业务的发展,其源于不停地衍变而非一成不变的设计;
- 架构演进过程中,要做好架构演进和业务迭代的协同工作;
- 做好防劣化机制: 任何架构都有生命周期,所以会有源源不断的新的架构被设计和演进出来; 没有防劣化机制的话,填坑速度可能永远赶不上挖坑速度。而恰当的防劣化机制,能够延长架构的生命周期,使得架构师可以更关注于新增问题。

lowcode-engine / vue
🚀 Projects
Since the lowcode-engine official website is built on the React ecosystem, it has been refactored to the Vue ecosystem.
Below, the package usage is provided:
Lowcode
- git: https://github.com/cdLab996/lowcode-engine-demo-vue
- online
- Vue 3: https://lowcode-engine-demo-vue.vercel.app/
- Vue 2.7: https://lowcode-engine-demo-vue2-7.vercel.app/
- Vue 2.7 Examples: https://lowcode-engine-demo-vue2-7-examples.vercel.app/
🏗️ Main
| Package | Description | Latest |
|---|---|---|
| @cdlab996/lowcode-hooks2.7 | 🏗️ Hooks for renderer/simulator | |
| @cdlab996/lowcode-utils2.7 | 🏗️ Utility methods for renderer/simulator | |
| @cdlab996/lowcode-vue-renderer2.7 | 🏗️ Lowcode renderer using Vue2.7 framework | |
| @cdlab996/lowcode-vue-simulator-renderer2.7 | 🏗️ Lowcode simulator renderer using Vue2.7 engine |
🧩 Plugins & Extensions
| Package | Description | Latest |
|---|---|---|
| @cdlab996/lowcode-engine-ext-vue | 🕹️ Adapt lowcode-engine-ext to the Vue version. | |
| @cdlab996/plugin-directive-loading | 🧩 Vue directive v-loading | |
| @cdlab996/lowcode-plugin-manual | 🧩 lowcode product user manual | |
| @cdlab996/lowcode-plugin-set-doc-url | 🧩 Component material new documentation address | |
| @cdlab996/lowcode-plugin-vue-code-editor2.7 | 🧩 lowcode CodeEditor for Vue 2.7 (Not available yet) |
🔨 Tools
| Package | Description | Latest |
|---|---|---|
| @cdlab996/vite-plugin-lib-types2.7 | 🔨 Generate typescript declarations, Supports Vue2.7 Files | |
| @cdlab996/create-lowcode2.7 | 🔨 Scaffold tool for initializing Lowcode projects | |
| @cdlab996/vue-cli-plugin-lowcode2.7 | 🔨 Development and build tool plugin for Lowcode engine |
🎨 Materials
| Package | Description | Latest |
|---|---|---|
| @cdlab996/element-plus-lowcode-materials | 🎨 Element Plus(2.6.3) Materials for Vue3 | |
| @cdlab996/antd-lowcode-materials | 🎨 Ant Design Vue(4.1.2) Materials for Vue3 | |
| @cdlab996/vant-lowcode-materials | 🎨 Vant(4.8.10) Materials for Vue3 | |
| @cdlab996/element-lowcode-materials2.7 | 🎨 Element(2.15.13) Materials for Vue2.7 | |
| @cdlab996/antd-lowcode-materials2.7 | 🎨 Ant Design Vue(1.7.8) Materials for Vue2.7 | |
| @cdlab996/vant-lowcode-materials2.7 | 🎨 Vant(2.12.54) Materials for Vue2.7 |
lowcode-engine / 组件转物料
基础组件转物料信息整理说明
背景说明
为了能够在低代码平台运行使用我们的基础组件,需要把基础组件转换成低代码平台可识别的组件,也就是物料。物料需要进行一定的配置和处理,这个过程中,需要一份配置文件,也就是资产包(就是一份json)。资产包文件中,针对每个物料定义了它们在低代码编辑器中的使用描述。
如何引入组件
我们需要在资产包里定义这个包的获取方式,如果不定义,就不会被低代码引擎动态加载并对应上组件实例。定义方式是 UMD 的包,低代码引擎会尝试在 window 上寻找对应 library 的实例;
定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等;
| 字段 | 字段描述 | 字段类型 | 规范等级 | 备注 |
|---|---|---|---|---|
| packages[].id? | 资源唯一标识 | String | A | 资源唯一标识,如果为空,则以 package 为唯一标识 |
| packages[].title? | 资源标题 | String | A | 资源标题 |
| packages[].package | npm 包名 | String | A | 组件资源唯一标识 |
| packages[].version | npm 包版本号 | String | A | 组件资源版本号 |
| packages[].type | 资源包类型 | String | AA | 取值为: proCode(源码)、lowCode(低代码,默认为 proCode |
| packages[].schema | 低代码组件 schema 内容 | object | AA | 取值为: proCode(源码)、lowCode(低代码) |
| packages[].deps | 当前资源包的依赖资源的唯一标识列表 | Array | A | 唯一标识为 id 或者 package 对应的值 |
| packages[].library | 作为全局变量引用时的名称,用来定义全局变量名 | String | A | 低代码引擎通过该字段获取组件实例 |
| packages[].editUrls | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array | A | 低代码引擎编辑器会加载这些 url |
| packages[].urls | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array | AA | 低代码引擎渲染模块会加载这些 url |
| packages[].advancedEditUrls | 组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls |
| packages[].advancedUrls | 组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls |
| packages[].external | 当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念) | Boolean | AAA | 某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源 |
| packages[].loadEnv | 指定当前资源加载的环境 | Array | AAA | 主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态)中的一个或多个 |
| packages[].exportSourceId | 标识当前 package 内容是从哪个 package 导出来的 | String | AAA | 此时 urls 无效 |
| packages[].exportSourceLibrary | 标识当前 package 是从 window 上的哪个属性导出来的 | String | AAA | exportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效 |
| packages[].async | 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 | Boolean | A | async 为 true 时,需要通过 await 才能拿到真正内容 |
| packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 "functionCall", exportMode等于 "functionCall" 时,当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any |
示例:
"packages": [
{
"package": "element-ui",
"version": "2.5.12",
"urls": [
"https://unpkg.com/element-ui/lib/index.js",
"https://unpkg.com/element-ui/lib/theme-chalk/index.css"
],
"library": "ELEMENT"
},
{
"package": "vant",
"version": "2.12.53",
"urls": [
"https://unpkg.com/vant@2.12/lib/vant.min.js",
"https://unpkg.com/vant@2.12/lib/index.css"
],
"library": "vant"
}
],
如何定义组件
单个组件描述内容为 json 结构,主要包含以下三部分内容,分别为:
- 基础信息 (A): 描述组件的基础信息,通常包含包信息、组件名称、标题、描述等。
- 组件属性信息 (A): 描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。
- 能力配置/体验增强: 推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。
整体结构概览:http://lowcode-engine.cn/doc?url=sde3wf
基础信息 ElRow示例:
{
"category": "基础组件",
"componentName": "ElRow",
"npm": {
"package": "element-ui",
"version": "2.30.6",
"exportName": "Row",
"destructuring": true
}
}基础信息 字段说明
| 字段 | 字段描述 | 字段类型 | 允许空 |
|---|---|---|---|
| componentName | 组件名称 | String | 否 |
| title | 组件中文名称 | String | 否 |
| description | 组件描述 | String | 是 |
| docUrl | 组件文档链接 | String | 否 |
| screenshot | 组件快照 | String | 否 |
| icon | 组件的小图标 | String (URL) | 是 |
| tags | 组件标签 | String | 是 |
| keywords | 组件关键词,用于搜索联想 | String | 是 |
| devMode | 组件研发模式 | String (proCode,lowCode) | 是 |
| npm | npm 源引入完整描述对象 | Object | 否 |
| npm.package | 源码组件库名 | String | 否 |
| npm.exportName | 源码组件名称 | String | 否 |
| npm.subName | 子组件名 | String | 否 |
| npm.destructuring | 解构 | Bool | 否 |
| npm.main | 组件路径 | String | 否 |
| npm.version | 源码组件版本号 | String | 否 |
| snippets | 内容为组件不同状态下的低代码 schema (可以有多个), 用户从组件面板拖入组件到设计器时会向页面 schema 中插入 snippets中定义的组件低代码 schema | Object[] | 否 |
| group | 用于描述当前组件位于组件面板的哪个 tab | String | 否 |
| category | 用于描述组件位于组件面板同一 tab 的哪个区域 | String | 否 |
| priority | 用于描述组件在同一 category 中的排序 | String | 否 |
组件属性信息 ElRow 示例:
"props": [
{
"name": "gutter",
"propType": "number"
},
{
"name": "type",
"propType": "string",
"defaultValue": "flex"
},
{
"name": "justify",
"propType": {
"type": "oneOf",
"value": ["start", "end", "center", "space-around", "space-between"]
},
"defaultValue": "start"
},
{
"name": "align",
"propType": {
"type": "oneOf",
"value": ["top", "middle", "bottom"]
}
},
{
"name": "tag",
"propType": "string",
"defaultValue": "div"
}
]组件属性信息 props
描述组件属性信息,通常包含名称、类型、描述、默认值 4 项内容。
| 字段 | 字段描述 | 字段类型 | 允许空 |
|---|---|---|---|
| name | 属性名称 | String | 否 |
| propType | 属性类型 | String/Object | 否 |
| description | 属性描述 | String | 是 |
| defaultValue | 属性默认值 | Any | 是 |
经验:描述可改为用 title: {label:'',tip:''}
存在基本类型和复合类型,描述如下:Prop — Vue.js
基本类型
| propType 值 | 类型描述 | PropType 类型 |
|---|---|---|
| 'array' | 数组类型 | Array |
| 'bool' | 布尔类型 | Boolean |
| 'func' | 函数类型 | Function |
| 'number' | 数字类型 | Number |
| 'object' | 对象类型 | Object |
| 'string' | 字符串类型 | String |
| 'node' | 节点类型 | 定义具名插槽 |
| 'any' | 任意值类型 | 会生成多个setter切换,如:node、string、object、array类型 |
复合类型
能力配置/体验增强 configure
configure ElRow 示例:
"configure": {
"supports": {
"events": ["click", "change"],
"loop": true,
"condition": true,
"style": true
},
"component": {
"isContainer": true,
"isLayout": true
},
"props": [
{
"type": "group",
"title": "布局样式",
"display": "block",
"items": [
{
"type": "field",
"title": "类型",
"name": "type",
"defaultValue": "flex",
"condition": false
},
{
"type": "field",
"title": "栅格间隔",
"name": "gutter",
"setter": "NumberSetter"
},
{
"type": "field",
"title": "水平排列",
"name": "justify",
"setter": {
"componentName": "SelectSetter",
"defaultValue": "start",
"props": {
"options": [
{ "title": "start", "value": "start" },
{ "title": "end", "value": "end" },
{ "title": "center", "value": "center" },
{ "title": "space-around", "value": "space-around" },
{ "title": "space-between", "value": "space-between" }
]
}
}
},
{
"type": "field",
"title": "垂直排列",
"name": "align",
"setter": {
"componentName": "SelectSetter",
"defaultValue": "start",
"props": {
"options": [
{ "title": "top", "value": "top" },
{ "title": "middle", "value": "middle" },
{ "title": "bottom", "value": "bottom" }
]
}
}
}
]
}
]
}基础字段
| 字段 | 字段描述 | 字段类型 | 备注 |
|---|---|---|---|
| props (A) | 属性面板配置 | Array | 用于属性面板能力描述 |
| component(A) | 组件能力配置 | Object | 与组件相关的能力、约束、行为等描述,有些信息可从组件视图实例上直接获取 |
| supports (AA) | 通用扩展配置能力支持性 | Object | 用于通用扩展面板能力描述 |
| advanced (AAA) | 高级特性配置 | Object | 用户可以在这些配置通过引擎上下文控制组件在设计器中的表现,例如自动初始化组件的子组件、截获组件的操作事件进行个性化处理等 |
属性面板配置 props
根据属性值类型 propType,确定对应控件类型 (setter) ,详见https://lowcode-engine.cn/site/docs/guide/appendix/setters
configure下的props还可以是对象的形式,与组件属性信息props并存
优先使用组件下的props,当不能满足用户体验时,需用configure来扩展
坑点:设置ArraySetter类型时,不要定义type:filed, 不然会导致面板数据改变后视图不同步。isRequired 属性配置快捷编辑项。
extraProps示例标签demo:
const getValue = function (target, fieldValue) {
const map = target.getNode().children.map((child) => {
const primaryKey = child.getPropValue('primaryKey')
? String(child.getPropValue('primaryKey'))
: child.id
return {
primaryKey: primaryKey,
title: child.getPropValue('title'),
}
})
return map
}
const setValue = function (target, value) {
const node = target.getNode()
const map = {}
if (!Array.isArray(value)) {
value = []
}
value.forEach((item) => {
const tabitem = Object.assign({}, item)
map[item.primaryKey] = tabitem
})
node.children.mergeChildren(
(child) => {
const primaryKey = String(child.getPropValue('primaryKey'))
if (Object.hasOwnProperty.call(map, primaryKey)) {
child.setPropValue('title', map[primaryKey].title)
delete map[primaryKey]
return false
}
return true
},
() => {
const items = []
for (const primaryKey in map) {
if (Object.hasOwnProperty.call(map, primaryKey)) {
items.push({
componentName: 'van-tab',
props: map[primaryKey],
})
}
}
return items
},
(child1, child2) => {
const a = value.findIndex(
(item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey'))
)
const b = value.findIndex(
(item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey'))
)
return a - b
}
)
}API说明:https://lowcode-engine.cn/site/docs/api/project#mergechildren
通用扩展面板支持性配置 supports
样式配置面板能力描述,描述是否支持行业样式编辑、是否支持类名设置等。
{
"configure": {
// 支持的事件枚举
"supports": {
// 支持事件列表
"events": ["click", "change"],
// 支持循环设置
"loop": true,
// 支持条件设置
"condition": true,
// 支持样式设置
"style": true
}
}
}组件能力配置 component
特别说明: 当默认插槽和其他具名插槽是互斥的情况下,需要显示的定义default, 且isContainer 属性需设为false
描述举例:
{
configure: {
component: {
// 组件是否是容器组件(可拖入,类似于插槽)
isContainer: true,
isModal: false,
descriptor: 'title',
nestingRule: {
childWhitelist: ['SelectOption'],
parentWhitelist: ['Select', 'Table'],
},
rootSelector: '.next-dialog',
disableBehaviors: ['copy', 'remove'],
actions: {
name: 'copy', // string;
content: '+', // string | ReactNode | ActionContentObject;
items: [], // ComponentAction[];
condition: 'always', // boolean | ((currentNode: any) => boolean) | 'always';
important: true, // boolean;
},
},
},
}
高级功能配置 advanced
| 字段 | 用途 | 类型 | 备注 |
|---|---|---|---|
| initialChildren | 组件拖入“设计器”时根据此配置自动生成 children 节点 schema | NodeData[]/Function NodeData[] | ((target: SettingTarget) => NodeData[]); |
| getResizingHandlers | 用于配置设计器中组件 resize 操作工具的样式和内容 | Function | (currentNode: any) => Array<{ type: 'N' |
| callbacks | 配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等 | Callback | - |
| callbacks.onNodeAdd | 在容器中拖入组件时触发的事件回调 | Function | (e: MouseEvent, currentNode: any) => any |
| callbacks.onNodeRemove | 在容器中删除组件时触发的事件回调 | Function | (e: MouseEvent, currentNode: any) => any |
| callbacks.onResize | 调整容器尺寸时触发的事件回调,常常与 getResizingHandlers搭配使用 | Function | 详见 Types 定义 |
| callbacks.onResizeStart | 调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers搭配使用 | Function | 详见 Types 定义 |
| callbacks.onResizeEnd | 调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers搭配使用 | Function | 详见 Types 定义 |
| callbacks.onSubtreeModified | 容器节点结构树发生变化时触发的回调 | Function | (currentNode: any, options: any) => void; |
| callbacks.onMouseDownHook | 鼠标按下操作回调 | Function | (e: MouseEvent, currentNode: any) => any; |
| callbacks.onClickHook | 鼠标单击操作回调 | Function | (e: MouseEvent, currentNode: any) => any; |
| callbacks.onDblClickHook | 鼠标双击操作回调 | Function | (e: MouseEvent, currentNode: any) => any; |
| callbacks.onMoveHook | 节点被拖动回调 | Function | (currentNode: any) => boolean; |
| callbacks.onHoverHook | 节点被 hover 回调 | Function | (currentNode: any) => boolean; |
| callbacks.onChildMoveHook | 容器节点的子节点被拖动回调 | Function | (childNode: any, currentNode: any) => boolean; |
描述举例:
{
configure: {
advanced: {
callbacks: {
onNodeAdd: (dragment, currentNode) => {
const layoutPNode = currentNode.document.createNode({
componentName: "WsCard",
title: "卡片组件",
props: { },
children: [dragment.schema],
});
setTimeout(() => {
if (!currentNode.getChildren().has(dragment)) {
return;
}
const newNode = currentNode.document.createNode(
Object.assign(layoutPNode.schema)
);
currentNode.insertBefore(newNode, dragment, false);
dragment.remove(false);
newNode.getChildren().get(0).select();
}, 1);
}
},
getResizingHandlers: () => {
return [ 'E' ];
},
initials: [
{
name: 'linkType',
initial: () => 'link'
},
]
},
}
}
开发规范
目录结构
引入的第三方库vant、element和wshoto的组件库,需在public下的lib下以库名建立文件夹,文件名为 index 。示例:
物料资产
一个UI 组件库对应一个json文件,方便管理。示例:
组件定义规范
宗旨: 以低代码平台用户体验为优先级,而不是物料书写方便
- description 字段描述定义清晰,需用中文,描述文字过长时需定义成 title 字段
"title": {
"label": "自定义搜索逻辑",
"tip": "第一个参数是节点node,第二个参数是搜索关键词keyword,通过返回布尔值表示是否命中"
},- defaultValue 默认值字段 按需在 componentsList 下的 props 上定义默认值
"componentList": [
{
"title": "WSHOTO_PC 组件",
"children": [
{
"componentName": "WeShineExportButton",
"library": "WSHOTO_PC_UI",
"snippets": [
{
"screenshot": "https://helios-allpublic-1257616148.cos.ap-shanghai.myqcloud.com/img/input.png",
"title": "导出列表",
"schema": {
"componentName": "WeShineExportButton",
"props": {
"moduleId": "demo",
"moduleFileName": "导出列表文件",
"btnText": "导出列表",
"getParams": {
"type": "JSFunction",
"value": "function getParams() {\n return {};\n }"
},
"createFn": {
"type": "JSFunction",
"value": "function createFn(data) {\n return { url: '/v3/base-auditlog/api/audit/log/download/jobId', method: 'post', data};\n }"
},
"getProgressFn": {
"type": "JSFunction",
"value": "function getProgressFn(options) {\n return { url: '/v3/base-auditlog/api/audit/log/download/progress', method: 'get', params: {...options}}; \n }"
},
"getUrlFn": {
"type": "JSFunction",
"value": "function getProgressFn(options) {\n return { url: '/v3/base-auditlog/api/audit/log/download/file', method: 'get', params: {...options}}; \n }"
}
}
}
}
]
}
]
}
]
- propType 需严格定义类型
- 可枚举的字符串类型需定义成 oneOf 枚举值类型,而不能定义成 string
{
"name": "justify",
"propType": {
"type": "oneOf",
"value": ["start", "end", "center", "space-around", "space-between"]
}
}- 可同时存在多个类型时,需用 oneOfType 的复合类型定义出来
{
"name": "v-model",
"description": "绑定的值",
"propType": {
"type": "oneOfType",
"value": [
"string",
"bool",
"number"
]
}
},
- 对象类型需定义成 shape 或 exact 复合类型
"propType": {
"type": "shape",
"value": [
{
"name": "span",
"description": "span",
"propType": "number"
},
{
"name": "offset",
"description": "offset",
"propType": "number"
}
]
},
- 当props的值为颜色值时,需使用 ColorSetter
{
"name": "inactive-color",
"title": "关闭时的背景色",
"setter": "ColorSetter"
}完整demo示例
Element row和col组件
{
"version": "0.0.1",
"components": [
{
"category": "基础组件",
"componentName": "ElRow",
"npm": {
"package": "element-ui",
"version": "2.30.6",
"exportName": "Row",
"destructuring": true
},
"props": [
{
"name": "gutter",
"propType": "number"
},
{
"name": "type",
"propType": "string",
"defaultValue": "flex"
},
{
"name": "justify",
"propType": {
"type": "oneOf",
"value": ["start", "end", "center", "space-around", "space-between"]
},
"defaultValue": "start"
},
{
"name": "align",
"propType": {
"type": "oneOf",
"value": ["top", "middle", "bottom"]
}
},
{
"name": "tag",
"propType": "string",
"defaultValue": "div"
}
],
"configure": {
"supports": {
"loop": true,
"condition": true,
"style": true
},
"component": {
"isContainer": true,
"isLayout": true
},
"props": [
{
"type": "group",
"title": "布局样式",
"display": "block",
"items": [
{
"type": "field",
"title": "类型",
"name": "type",
"defaultValue": "flex",
"condition": false
},
{
"type": "field",
"title": "栅格间隔",
"name": "gutter",
"setter": "NumberSetter"
},
{
"type": "field",
"title": "水平排列",
"name": "justify",
"setter": {
"componentName": "SelectSetter",
"defaultValue": "start",
"props": {
"options": [
{
"title": "start",
"value": "start"
},
{
"title": "end",
"value": "end"
},
{
"title": "center",
"value": "center"
},
{
"title": "space-around",
"value": "space-around"
},
{
"title": "space-between",
"value": "space-between"
}
]
}
}
},
{
"type": "field",
"title": "垂直排列",
"name": "align",
"setter": {
"componentName": "SelectSetter",
"defaultValue": "start",
"props": {
"options": [
{
"title": "top",
"value": "top"
},
{
"title": "middle",
"value": "middle"
},
{
"title": "bottom",
"value": "bottom"
}
]
}
}
}
]
}
]
}
},
{
"category": "基础组件",
"componentName": "ElCol",
"npm": {
"package": "element-ui",
"version": "2.30.6",
"exportName": "Col",
"destructuring": true
},
"configure": {
"supports": {
"loop": true,
"condition": true,
"style": true
},
"component": {
"isContainer": true,
"isLayout": true,
"nestingRule": {
"descendantBlacklist": ["ElCol"],
"parentWhitelist": ["ElRow"]
}
},
"props": [
{
"type": "group",
"title": "布局样式",
"display": "block",
"items": [
{
"type": "field",
"title": "占据列宽",
"name": "span",
"setter": "NumberSetter"
},
{
"type": "field",
"title": "左侧间隔",
"name": "offset",
"setter": "NumberSetter"
},
{
"type": "field",
"title": "向右移动",
"name": "push",
"setter": "NumberSetter"
},
{
"type": "field",
"title": "向左移动",
"name": "pull",
"setter": "NumberSetter"
}
]
}
]
}
}
],
"componentList": [
{
"title": "布局组件",
"children": [
{
"componentName": "ElRow",
"library": "element-ui",
"snippets": [
{
"screenshot": "https://helios-allpublic-1257616148.cos.ap-shanghai.myqcloud.com/img/card.png",
"title": "栅格-行",
"schema": {
"componentName": "ElRow",
"children": []
}
}
]
}
]
},
{
"title": "布局组件",
"children": [
{
"componentName": "ElCol",
"library": "element-ui",
"snippets": [
{
"screenshot": "https://helios-allpublic-1257616148.cos.ap-shanghai.myqcloud.com/img/card.png",
"title": "栅格-列",
"schema": {
"componentName": "ElCol",
"children": []
}
}
]
}
]
}
]
}Vant grid和gridItem组件
{
"version": "0.0.1",
"components": [
{
"category": "基础组件",
"componentName": "van-grid",
"npm": {
"package": "vant",
"version": "2.12.53",
"exportName": "Grid",
"destructuring": true
},
"props": [
{
"name": "column-num",
"title": "列数",
"propType": "number",
"defaultValue": "4"
},
{
"name": "gutter",
"title": "格子间隔",
"propType": "number",
"defaultValue": "0"
},
{
"name": "direction",
"title": "排列方向",
"propType": {
"type": "oneOf",
"value": ["vertical", "horizontal"]
},
"defaultValue": "vertical"
},
{
"name": "border",
"propType": "bool",
"title": "显示边框",
"defaultValue": true
},
{
"name": "center",
"propType": "bool",
"title": "居中显示",
"defaultValue": true
},
{
"name": "square",
"propType": "bool",
"title": "显示正方形",
"defaultValue": false
},
{
"name": "clickable",
"propType": "bool",
"title": "开启点击反馈",
"defaultValue": false
}
],
"configure": {
"supports": {
"events": ["click"],
"loop": true,
"condition": true,
"style": true
},
"component": {
"isContainer": true
}
}
},
{
"category": "基础组件",
"componentName": "van-grid-item",
"npm": {
"package": "vant",
"version": "2.12.53",
"exportName": "GridItem",
"destructuring": true
},
"props": [
{
"name": "default",
"title": "默认插槽",
"propType": "node"
},
{
"name": "text",
"description": "文本内容",
"propType": {
"type": "oneOfType",
"value": ["string", "node"]
},
"defaultValue": ""
},
{
"name": "icon",
"propType": {
"type": "oneOfType",
"value": ["string", "node"]
},
"defaultValue": ""
},
{
"name": "dot",
"propType": "bool",
"defaultValue": false
},
{
"name": "badge",
"propType": "string",
"defaultValue": ""
},
{
"name": "url",
"propType": "string",
"defaultValue": ""
},
{
"name": "to",
"propType": "string",
"defaultValue": ""
},
{
"name": "replace",
"propType": "bool",
"defaultValue": false
}
],
"configure": {
"supports": {
"events": ["onClick"],
"loop": true,
"condition": true,
"style": true
},
"component": {
"isContainer": false
}
}
}
],
"componentList": [
{
"title": "布局组件",
"children": [
{
"componentName": "van-grid",
"library": "vant",
"snippets": [
{
"screenshot": "https://helios-allpublic-1257616148.cos.ap-shanghai.myqcloud.com/img/card.png",
"title": "宫格-容器",
"schema": {
"componentName": "van-grid",
"children": []
}
}
]
}
]
},
{
"title": "布局组件",
"children": [
{
"componentName": "van-grid-item",
"library": "vant",
"snippets": [
{
"screenshot": "https://helios-allpublic-1257616148.cos.ap-shanghai.myqcloud.com/img/card.png",
"title": "宫格-子项",
"schema": {
"componentName": "van-grid-item",
"children": []
}
}
]
}
]
}
]
}