组件化简介
使用场景
设计稿上传到 CODE.FUN 平台之后,这时直接查看/下载代码,只能得到由 View/Text/Image 组成的静态页面,不具备交互能力。 而通常我们需要在页面上收集用户输入、提供反馈、展示动态数据 等,以此来达到与用户的动态交互,从而实现所需的业务逻辑。 又或者团队内部已经有了一批通用的公共组件,如何将这些组件与 CODE.FUN 打通,在生成代码时自动生成组件代码呢?
为此,我们提供了组件化能力,通过组件标记实现自动生成组件代码,比如输入框、单选/多选框等基础组件,表格、标签页、轮播图等高级组件,或自定义组件。
标记原理
组件标记原理分定义组件、标签使用和组件代码三个板块介绍。
- 定义组件:触发组件标记时,组件化代码是如何被编译的
- 标签:设置标签面板各组件标签的含义
- 组件代码
定义组件
每个组件库下都可以自由定义组件,本质上每个组件以标签的形式存在,当一个节点被标记之后,也会展示相应的标签,目前的标签有以下 3 种类型:
- 组件标签:包含依赖、编译模版、属性等配置项,是生成代码的入口
- 属性提取器标签:与某个组件属性绑定,当标记该标签时自动提取值到指定的属性
- Slot 标签:根据组件的编译模版配置,来参与最终的代码生成


目前 CODE.FUN 支持以下 3 种表达式语法,这些语法将在配置组件模版、属性时使用到:
- 自定义属性表达式:$.props.x,获取组件已定义的属性 x 对应的值
- DOM 属性表达式:$.x,获取 DOM 节点的属性 x 对应的值(DOM 节点指的是设计稿详情页左侧 DOM 树上的节点,大部分时候这些节点属性供内部使用,这里仅开放部分属性供组件化使用)
// 节点坐标信息
interface UIFrame {
left: number // x 轴坐标
top: number // y 轴坐标
width: number // 宽度
height: number // 高度
}
// DOM 节点通用属性
interface UIDOMNode {
_id: string // 节点 id
type: string // 节点类型:View/Text/Image
frame: UIFrame // 相对于父节点的坐标信息
absFrame: UIFrame // 对于设计稿左上原点的坐标信息
style: Record<string, string> // 节点样式信息,以驼峰形式命名的 css 属性,例如:{ fontSize: 12px }
}
// View 节点
interface UIViewNode extends UIDOMNode {
children: UIDOMNode[] // 孩子节点
}
// Text 节点
interface UITextNode extends UIDOMNode {
text: string // 文本内容
}
// Image 节点
interface UIImageNode extends UIDOMNode {
src: string // 图片 url
}
- 标签选择表达式:$('x y'),获取标记了 x 或 y 的 DOM 节点(这里的 DOM 节点同上),多个标签以空格分隔
标签使用
1.组件标签:将节点按照自定义模板生成代码,顶层标签必须是组件标签。

字段说明
字段说明 | 字段名称 |
---|---|
名称 | 用于展示,标记节点之后也会在 DOM 树上展示对应的标签名称 |
智能识别 | 可选,关联智能标签,可以实现自动标记和智能处理,详情参照智能组件 |
依赖导入 | 可选,配置第三方依赖或本地依赖(设置了依赖导入,就需要配置相关的依赖设置项) |
导入名称 | 导入的组件名 |
是否解构导入 | 是否解构导入组件名,例如:解构 import { name} from 'x',非解构 import name from 'x' |
导入路径 | 组件所在位置,第三方 npm 包路径或本地路径 |
Npm 包名 | npm 包版本号,默认 *,用于生成 package.json 中的依赖项 |
编译模版 | 可选,为空时不生成代码,需要是合法的 xml 语法,可嵌套任意层级,包含普通标签和指令标签 |
普通标签:会被原样生成到代码中,属性值支持 自定义属性表达式 或 DOM 属性表达式 | |
指令标签:内部指令,会按照特殊规则进行代码生成,有以下指令标签 | |
cf-slot: 根据 cf-content 指令属性获取到的 DOM 节点进行代码生成,cf-content 支持 DOM 属性表达式 或 标签选择表达式,其他属性按照普通属性生成 | |
属性 | 组件配置项,主要用于编译模版中的属性绑定,目前有 4 种属性:输入框、布尔值、下拉选项、颜色,属性默认值支持 DOM 属性表达式 |
2.属性提取器标签:通过打标签的方式自动提取值到组件属性,简化手动填写属性值的繁琐。

3.Slot 标签:主要用于筛选节点,将标记了该标签的节点插入到组件编译模版的指定位置。

组件代码
依次打上三种标签后代码的变化,如下图所示:

标记前后代码的变化
// 0-未标记组件时的源代码
<div class="flex-row items-center equal-division-item space-x-7 input">
<img class="image_5" src="assets/80cd.png" />
<span class="font_2">请输入</span>
</div>
注:源代码由 View/Text/Image 三种标签组成
// 1-标记上组件标签组件标签(elInput)的代码
<el-input class="input elinput-vwffmYek" v-model="v_model" size="small"></el-input>
注:源代码被替换为 el-input 组件标签
// 2-标记上组件标签组件标签(elInput)+属性提取器标签(palceholder)的代码
<el-input class="input elinput-vwffmYek" v-model="v_model" placeholder="请输入" size="small"></el-input>
注:源代码被替换为 el-input 组件标签,同时提取了源代码中的文本:placeholder="请输入"
// 3-标记上组件标签(elInput)+属性提取器标签(palceholder)+插槽Slot(prependSlot)的代码
<el-input class="input elinput-vwffmYek" v-model="v_model" placeholder="请输入" size="small">
<img class="image_5" src="assets/80cd.png" slot="prefix" />
</el-input>
注:源代码被替换为 el-input 组件标签,同时提取了源代码中的文本:placeholder="请输入" 和 img节点并插入制定的位置
样式还原
生成组件代码时如果按照设计稿进行样式还原,就需要深层次的样式穿透、覆盖,由于各 UI 库自定义样式规则不同,很难提供统一模式的样式还原。根据常用的开发流程,大多数公司内部有统一的组件风格,会针对 UI 库自带的主题样式进行全局配置、覆盖,实现自定义样式的修改。
基于以上两点,目前组件化在样式还原上分为两个阶段:
第一阶段:
- 只保留组件位置样式(left、right、margin、flex、alignSelf 等),其他样式全部丢弃(width、padding、color 等)
- 在组件库中配置全局样式,实现样式统一、覆盖
视觉效果:标记后生成的组件样式完全由原组件库组件默认样式控制,组件的大小、颜色、边框及内部结构样式与组件默认样式保持一致。
第二阶段:
- 标记组件后,新生成的组件可自动继承原设计稿样式,生成和设计稿视觉效果一致的组件。
- 保留组件位置样式(left、right、margin、flex、alignSelf 等
- 继承组件自身的大小、颜色、边框等样式信息,同时内部样式也会自动继承(width、height、margin、padding、color 等)。
组件类型
官方标签
官方标签是为了优化移动端的页面布局结构而设置,包括 Header、Footer、Fixed、List、Grid、Table。
List 标签输出代码:
<template>
<div class="flex-col space-y-20">
<div class="flex-row items-center list-item space-x-24" :key="i" v-for="(item, i) in list_V4ebIDxs">
<img class="image_7" src="assets/359ad2271a0865b504011ff4e1e38f2d.png" />
<div class="flex-col items-start flex-auto space-y-39">
<span class="font_2">星巴克咖啡</span>
<div class="flex-col justify-start items-center text-wrapper"><span class="font_3">全品类8折</span></div>
</div>
</div>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
list_V4ebIDxs: [null, null, null, null], // 需要绑定数据才能显示
};
},
methods: {},
};
</script>
UI 标签
UI 标签的作用是将 View/Text/Image 这些标签组成的静态页面转换为组件化代码。比如:轮播、标签页、输入框等。
平台 | 组件库 | 样式覆盖情况 |
---|---|---|
微信小程序 | vant-weapp、小程序原生组件 | vant-weapp ✅、小程序原生组件 ✅ |
uni-app | uView1.0、uni-app、原生组件 | uView1.0 ❎、uni-app 原生组件 ✅ |
Vue | vant2、HTML5、基础标签、ECharts、element-ui | vant2 ✅、HTML5 基础标签 ✅、ECharts 定制化✅、element-ui 开发中🔥 |
Taro (Vue) | Taro (Vue) 原生组件 | 定制化 ✅ |
Taro (React) | 定制化 | 定制化 ✅ |
React | Taro (Vue)、原生组件 | Taro (Vue) 原生组件 ❎ |
HTML5 | HTML5、基础标签 | HTML5 基础标签 ✅ |
vant-cell 标签输出代码:
<div class="flex-col section_5">
<van-cell title="单元格" :center="true" class="cell" title-class="cell-title"></van-cell>
<van-cell
title="单元格"
value="内容"
:center="true"
class="cell_1"
title-class="cell-title_1"
value-class="cell-value"
></van-cell>
</div>
<van-cell
class="view_8 cell_2"
title="单元格"
value="内容"
label="描述信息描述信息描述信息"
:center="true"
title-class="cell-title_2"
value-class="cell-value_1"
></van-cell>
业务组件
业务组件是为了解决代码的复用性问题。在不同页面中,如果存在功能结构相同的模块,可将其创建为业务组件,并在另外一个页面中引入,从而达到组件复用的效果。

业务组件输出代码:
<template>
<div class="flex-col group_4">
<div class="flex-row items-center group_5 space-x-60">
<span class="font_4 text_6">今日秒杀</span>
<span class="font_3 text_7">秒杀预告</span>
</div>
<div class="list grid">
<MyCard></MyCard>
<MyCard></MyCard>
<MyCard></MyCard>
<MyCard></MyCard>
</div>
</div>
</template>
<script>
import from '../../components/MyCard/MyCard.vue';
export default {
components: { MyCard },
data() {
return {
list_o82ONUpZ: [],
};
},
methods: {},
};
</script>
标记组件
- 标记组件:选中要标记的节点 -> 打开标记组件面板 -> 标记组件
- 查看代码:标记的组件节点已按照组件定义进行代码生成

❤️温馨提示: 一个节点可以标记多个标签,当两个组件标签同时出现在节点上时,会以第一个组件标签的编译模版进行代码生成。