面向未来的 Vue3.0 桌面组件设计
如果无法正常显示,请先停止浏览器的去广告插件。
1. 面向未来的 Vue 3 组件设计
郑傲
小米 · 资深前端研发工程师
2.
3. 写在前面的话
关于我和 CarsDesign
郑傲 小米汽⻋·自动驾驶资深前端研发工程师,曾就职于百度外卖、⻋好多集团。
CarsDesign 组件库是⻋好多对于 Vue3.x 桌面端实践的一种尝试。作为组件库核心开发者,负责
企业内前端基础架构方向的研究与新技术的探索。先后负责企业级 Vue2.0 组件库,React Mobile
组件库,有丰富组件研发经验。在组件的设计和表达上有独到的⻅解。在⻋好多推动 Vue3.0 组件
库研发和落地工作,从零到一设计了一套完整、易用、独立的组件库。
4. 写在前面的话
关于我和 CarsDesign
CarsDesign 从设计开始目标就是⻓久的未来。
分梯队开发一期交付组件 71 个,涉及基础布局、样式、数据展示、表单类、弹窗等场景;
Commit 近 2000 次。代码行数: 142,488 行;
TypeScript 占比大于 90%;
5. • 组件设计的视⻆与规范
• 企业级组件的设计与实现
• CarsDesign 组件库周边
• 一些 Public Topic
6. / 01 组件设计的视⻆与规范
不同⻆色对组件的认知、组件设计要遵循基本的设计规范
7. 不同⻆色对组件的认知、组件设计要遵循基本的设计规范
设计视⻆(品质)
产品视⻆(沟通)
一套标准的组件库可以对交付的品质兜底,符合大众预期的设计; 通过了解组件相关能力可以更加专业的表达产品能力;
企业级产品迭代快速,种类繁多,组件库可以减少用户的理解成本; 减少沟通 Gap;
组件库可以传递设计价值观;
研发视⻆(认知)
减少认知能量消耗
研发使用组件的目的是可以快速完成业务的开发。搭建出符合大众的基础业务逻辑。
同时从研发的⻆度出发,对组件的要求又是苛刻的, 需要丰富的功能,简单易用同时又足够灵活的 API。
8. 组件的设计是一个精细活
栅格系统建立布局标准
组件标准(设计视⻆): 栅格,间距,布局基数,行高,
字体。
丰富API(研发视⻆):Gutter Inline
功能扩展(产品视⻆): 同行等高布局。
9. 成熟的组件都经历设计、迭代、场景适配等多个产品周期
Step 1 . 理解: 将B端业务场景抽象成基础组件;
Step 2. 丰富: 考虑到组件的通用性,大量增加组件的API,以服务业务;
Step 3. 抽象: 抽象设计理念, 形成设计价值观。 平行扩展更多的组件;
Step 4. 业务设计模式的抽象, 将部分能力通过配套的周边服务推广给更多的开发者;
Step 5. 提效的下一步: 标准的 SASS 服务, Low Code , Pro Code, D2C 等等场景, 形成完整的产品信任感;
10. 未来的组件库设计 — 专注打造产品信任感
组件库和业务系统对标准化的设计和每一个细节的实现
可以有效将信任感和专业性传达给用户
11. / 02 企业级组件的设计与实现
梯队建设、组件多种实现、实现方案的取舍与纠结
12. 组件库梯队建设 — 先想好再出发
13. 组件库梯队建设 — 先想好再出发
14. 组件库梯队建设是快速迭代的基础
布局样式类组件
浮层弹窗类组件
表单交互类组件
数据展示类组件
组件库便捷指令
15. 组件库梯队建设是快速迭代的基础
布局样式类组件
浮层弹窗类组件
表单交互类组件
数据展示类组件
组件库便捷指令
16. 组件库梯队建设是快速迭代的基础
布局样式类组件
浮层弹窗类组件
表单交互类组件
数据展示类组件
组件库便捷指令
17. 组件库梯队建设是快速迭代的基础
布局样式类组件
浮层弹窗类组件
表单交互类组件
数据展示类组件
组件库便捷指令
18. 组件库梯队确立之后需要更易于扩展的架构、层次设计
19. 组件库是一个多人协同的技术项目,需要建设一些规范
Layout
Button
ButtonGroup
Packages
… …
脚本 脚本 脚本
目录结构 BEM 等 Lint 类
口头协议 公开规范 规则插件
20. 组件库开发逐步进入核心区,需要执行开发流程保开发者信息交换
API调研
API讨论/制定
组件开始
视觉交互设计
组件完成
组件创建 API实现 UI实现
Review 组件测试 文档和示例
视觉交互确认
视觉走查
FE
来源:组件库组件开发流程示意图
UED
21. 信息交换与讨论的过程让我们的组件库收获颇丰
讨论中 Rate 投票组件, 有 3 种非常优秀的实现方案。 我们统统支持并成功落地;
讨论中 Panel 布局组件在 API 设计上存在两种不同的声音 。 让我们难以取舍,多次争吵;
讨论中 Table 组件的实现意外获得了灵感。 让我们兴奋了很⻓一段时间;
甚至每一个组件都会因为 API 的设计而出现分歧
始终坚信 CarsDesign 从实现、设计、方案上都是勇于尝试,面向未来开发者使用更爽快而设计的
22. CarsDesign 鼓励一个组件的不同实现方式
很少在各类的组件库中看到同样的功能组件会有不同的实现方案,甚至各大组件库中的组件实现和设计都千篇一律。我们鼓励尝试更多思路为更多的场景而设计;
对于 Rate 投票组件
实现滑动、点击变换星星数量的功能
实现半星甚至 1/N 星的功能
实现星星替换成不规则图形(文字)
有多少种实现方案?
23. CarsDesign 鼓励一个组件的不同实现方式
DOM 事件 + 数据驱动
Hover
完全通过改变偏移数据,控制样式展示
Click
触发事件
计算偏移
改变数据
MouseIn
双层 DOM 结构覆盖
配合鼠标划入,移动,离开等事件,控制滑块尺寸或位置
DOM结构 input type=range来实现, template 没有其他代码很简洁
Input type=range
通过修改 Input 的伪类选择器实现覆盖
通过伪元素 ::-webkit-slider-runnable-track 滑块可滑动区域样式
通过伪元素 ::-webkit-slider-thumb滑块的样式
通过mask遮罩将图案遮罩在背景之上,设置图案为星星或者字符
驱动更新
24. CarsDesign 鼓励一个组件的不同实现方式
对比维度 方案一 方案二 方案三
核心思路 事件 + 数据驱动 双层DOM结构 + 样式逻辑 Input type=range
代码量 正常 很多 很少
Template 及其简洁
兼容性 好 好 弱(需要适配)
功能丰富度 均可实现 均可实现 没有 hover 状态
CarsDesign ✔ ✔ ✔
适合场景 PC
覆盖率为有限枚举 PC
覆盖率任意(百分比场景) 移动端
touch 拖拽
25. CarsDesign 的取舍与纠结 — 如何让开发者更爽的使用
想要实现一个 panel 布局组件, 业务方有很强的需求;
panel 尺寸上可以修改, 支持无限层级的嵌套;
纠结于提供怎么样的数据结构可以让开发者使用的更自然;
26. 使用平铺的结构, 可以让开发者清楚的自己的绝对位置,便于下一步操作
扁平化的数据结构
27. 使用平铺的结构, 可以让开发者清楚自己的绝对位置,便于下一步操作
A
①
②
③
结论: 让开发者通过位置描述边界比较难;
结论:描述边界线 resize 时候的影响范围也比较难;
B
28. 使用嵌套的数据结构, 可以让开发者清楚的知道每一个panel的边界
嵌套递归的数据结构
29. 使用嵌套的数据结构, 可以让开发者清楚的知道每一个 panel 的边界
A
①
②
B
③
结论: 开发者配置起来很爽快, 清晰的知道panel的边界和边界影响范围;
结论:后向扩展的时候比较麻烦, 整体 DOM 结构比较复杂;实现拖拽功能很难;
30. 纠结组件要如何取舍整合才能帮助开发者在各个方向的体验拉满
开发者
组件 API
入参处理
数据拍平
用于Panel渲染
平铺数据
panel h 计算
panel pos
其他用途
用于边界渲染
用于伸缩动作
panel w 计算
vDOM
冗余数据管理
vDOM
31. CarsDesign 从组件设计上从来不局限于现有的设计。会使用很多先进的特性与属性并把方案整合成产品
信息交换的过程中, 我们讨论出一个超棒的技术实现方案
32. 与 ElementPlus Table 组件对比 FPT 效果
实验条件: 7列 * 576 行数据 + 固定高度 300px + 固定宽度 900px + Fixed 列(开启左右滑动)
CarsDesign Table
33. 与 ElementPlus Table 组件对比 FPT 效果
实验条件: 7列 * 576 行数据 + 固定高度 300px + 固定宽度 900px + Fixed 列(开启左右滑动)
Element-Plus 1.0.2.beta.45 (2021.05.28)
34. 使用平铺的结构, 可以让开发者清楚的自己的绝对位置,便于下一步操作
实验条件: 7列 * 576 行数据 + 固定高度 300px + 固定宽度 900px + Fixed 列(开启左右滑动)
CarsDesign 对比 Element-Plus Table 组件 FPT 时间对比
实验条件: 7列 * 576 行数据 + 固定高度 300px + 固定宽度 900px + Fixed 列(开启左右滑动)
单位:ms
400
CarsDesign
294.2
300
Element-Plus
289.5
378.2
384.6
315.2
260.8
249
200
207
195.7
210.7
100
47.4
0
1
27.3
2
37.2
3
13.1
4
37.3
5
来源: 组件库 BaseTable 组件对比 Element-Plus 1.0.2.beta.45 (2021.05.28)
31.9
6
37.7
7
14.7
8
32.8
9
13.9
10
35. TOPIC: 可以通过实验分析一下影响 FPT 的渲染有哪些因素
实验过程中,两个组件库都是以 Vite 为基础的。均使用了 vite 的单包加载策略。
CarsDesign 中组件的代码逻辑比 Element 有更好的模块化, 在渲染中执行 (加载)的代码量变得更少。
CarsDesign 中也没有 Element 复杂的子组件逻辑,更减轻了需要加载的代码量
可能会说: 对于单独组件来说 FPT 的意义不大。那我们比较 DOM Ready 时间
36. 对比两个组件的 DOM Ready 时间
实验条件: 7列 * 576 行数据 + 固定高度 300px + 固定宽度 900px + Fixed 列(开启左右滑动)
CarsDesign 对比 Element-Plus Table 组件 Dom Ready 时间对比
CarsDesign
4000
3000
3562
3002
2000
3361
1504
3590
1522
3271
1458
3287
1440
Element-Plus
3206
1464
2963
1420
2667
1486
2986 3063
1716 1563
1000
0
1
2
3
4
5
来源: 组件库 BaseTable 组件对比 Element-Plus 1.0.2.beta.45 (2021.05.28)
6
7
8
9
10
37. 揭开 CarsDesign Table 的神秘实现方式
揭开 CarsDesign Table
DOM Ready 和 FPT 都遥遥领先的神秘实现方式
38. 桌面端组件的天花板 –- Table 组件
Table 组件的起源
CarsDesign 中 BaseTable 组件的实现及设计 灵感起源于我们组内的一次组件 API 讨论
讨论 Layout 布局组件的过程中,有一种布局方是使用 Grid 布局
发现 Grid 布局可以快速的使用 fr 和 grid-* 的属性配置行和列,就很像是一个 Table
Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell
* 他们每一行的行高都是自动撑开的, 每一列的列宽都是可以自适应和设置固定宽度的
39. CarsDesign 的 BaseTable 组件实现过程
可以控制 CSS 实现, 自适应宽度,固定宽度, 高度宽度分别设置,区域合并等
1 fr
40px
40px
Cell
1 fr
1 fr
Cell
minmax(1fr, 100px)
Cell
Cell
Cell
Cell Cell
Cell Cell
Cell
40px
Cell
Grid-area-*
结论: 回归CSS, 因为 CSSOM 在浏览器里有单独的线程去计算,且浏览器针对性的优化有很多
40. 桌面端组件的天花板 –- Table 组件
Element 使用一个新的 Table 通过绝对定位,盖住原来的 Table Cell
Th
Td
Td
Td
Td
Td
Td
Td
Td
Td
Td
Tr
Table
Tr
Td
Td
Td
Td
Td
Tr
Td
Td
Td
Td
Td
41. 桌面端组件的天花板 –- Table 组件
BaseTable 对 Fixed 的处理也有黑科技 ~
STICKY
Cell
Cell
Cell
STICKY
STICKY
来源: CarsDesign 对 表头和列 Fixed 的处理过程
Cell Cell Cell
Cell Cell Cell
42. 桌面端组件的天花板 –- Table 组件
TOPIC: CarsDesign 对比 Element 原理上的优势
Element 将 Fixed 的列计算出新的 Table 并覆盖。导致DOM节点的增多,行数越多,DOM 节点越多
Element 要大量的 JS 运算来处理这个新的 Table 带来的问题,比如滚动跟随。行数越多帧数越低。
Element 的新Table导致原有的DOM 是割裂的, 行高和列宽都需要 JS 运算得出。
CarsDesign 中 表格都是 Grid 对⻬的整体块,行高和列宽都是被CSS Grid 所控制的。
Fixed 的计算使用 STICKY 粘性布局, 把一切的渲染 都交给 CSS。 行数越多性能越强。
43. TOPIC: CarsDesign && Element 大数据量渲染
动态渲染数据量 500 行
DEMO
SHOW ME RESULT
44. Element-Plus 数据渲染结果
滚动帧数:12-16
滚动 CPU :< 90%
JS Heap : 29.5MB
DOM Nodes: 36,897
来源: Element 渲染数据
45. CarsDesign 的 BaseTable 数据渲染展示
滚动帧数:12-16
滚动 CPU :< 70%
JS Heap : 45MB
DOM Nodes: 19,792
来源: CarsDesign 数据渲染滚动示例
46. TOPIC: CarsDesign && Element 大数据量渲染
动态渲染数据量 2000 行
Element 会由于 跟随计算 过慢,导致进程阻塞,出现滚动严重卡顿的情况, 无法交互
CarsDesign 会由于 CSS Layout 重绘时间⻓,出现短暂白屏现象,白屏后可交互
47. / 03 CarsDesign 组件库周边
48. 我们一心想让组件库研发服务化和产品化
使用产品的配置服务,将研发对样式分层的理解产品化;
逐步公布迭代计划, 让我们的用户有更多的信息很信心;
提供便捷的 CLI 和项目模板, 助力从 0 到 1 的工程化创建;
49. 我们一心想让组件库研发服务化和产品化
样式抽离与可视化配置
50. 通过不断的公布迭代计划使组件库更加容易被信任
51. CLI 使用命令行工具创建统一的桌面端代码库
统一的 eslint 校验规则、 commit 校验规则
通用布局模板
登录校验解决方案
通用构建流程通用部署方案
通用样式封装 cars-ui
接入集团埋点系统
常用package预安装、组件库、eslint等等
接入水印 watermark
52.
53.
54. / 04 Feature && Topic
55. 抽象业务基础组件
基础组件带有业务生命力 Numberal 组件设计,反爬加密组件
基础组件带有集团架构基因 字体, 水印等基础业务系统组件。
头像, 业务包裹组件,集成 SSO 相关配置。
56. Topic 如何理解面向未来
使用未来 N 年的主流开发框架、语言、语法、规则等硬条件。便于⻓期迭代与维护;
API 、 交互设计等方面遵循开发者最自然的使用和选择;未来很⻓一段时间会形成不可分离的习惯;
组件的实现细节上,使用更为先进的实现方式,从原理上优化整个组件的实现;
逐步从专业的开发者,向 Sass 服务, LowCode 平台等未来的使用场景转移,为特殊场景设计;
未来会有更多的小众组件、会有更好的表达方式、会有更爽的使用体验。
57. Q && A
小米汽⻋ · 自动驾驶 · 郑傲
2022.08
58.
59.