Skip to main content

组件化简介

使用场景

设计稿上传到 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-appuView1.0、uni-app、原生组件uView1.0 ❎、uni-app 原生组件 ✅
Vuevant2、HTML5、基础标签、ECharts、element-uivant2 ✅、HTML5 基础标签 ✅、ECharts 定制化✅、element-ui 开发中🔥
Taro (Vue)Taro (Vue) 原生组件定制化 ✅
Taro (React)定制化定制化 ✅
ReactTaro (Vue)、原生组件Taro (Vue) 原生组件 ❎
HTML5HTML5、基础标签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>

标记组件

  • 标记组件:选中要标记的节点 -> 打开标记组件面板 -> 标记组件
  • 查看代码:标记的组件节点已按照组件定义进行代码生成


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