组件
组件(Component)是构成 LCUI 应用程序的 UI 的基本元素,其它 UI 开发库可能会将这类元素称之为控件(Control)或部件(Widget),你可以按照自己的习惯称呼它们,不过由于作者受到 Web 前端开发技术的影响,本文档统一采用“组件”这一名字称呼它,即便它的数据类型名是 LCUI_Widget
。
将一个完整的 UI 拆分成多个独立可复用的组件,这过程就是组件化,它与模块化相似,两者的目的都是为了解决代码中的耦合、内聚、复用问题,区别在于组件化注重 UI 层面的复用,模块化注重逻辑层面的职责 分离。
在学习组件开发之前,我们先简单了解一下如何拆分和设计组件,这将有助于我们以后的组件开发。
如何拆分组件
在拆分组件前,我们应该考虑以下几个条件来决定哪部分需要拆分成组件:
- **这部分的元素数量或逻辑复杂度是否足以证明它应该成为组件?**如果它只是几行代码,那么为了将其组件化我们可能会编写更多的代码,还不如让它继续嵌入在父组件内。
- **代码是否重复?**如果某些东西只使用一次,并且服务于一个不太可能在其他地方使用的特定用例,那么不做组件化可能会更好。如果需要,你可以随时将其分开(但不要在需要做这些工作的时候将此作为偷懒的借口)。
- **它会减少你需要写的样板代码吗?**以卡片为例,如果你想让列表内的列表项拥有卡片式布局和样式,那么你会需要创建包含卡片各个部分且有特定结构和属性的组件,然后将列表项的内容嵌套进这些部分中。构建这种组件的代码就是样板代码,如果需要编写的样板代码较多的话,可以考虑将其组件化。
- **它是否与其它部分存在耦合关系?**如果它与其它部分有着较强的耦合,那么强行将它组件化会需要编写额外的代码来实现与其它部分的交互,从而导致复杂度增加。
- **这些好处是否超过了成本?**做组件化不可避免地需要投入时间和精力,这些成本视具体情况而定,所以在做出决定之前需要权衡这两个方面。
如何设计组件
在知道哪些部分需要拆分成组件后,我们还需要考虑以下条件来对组件代码进行拆分。
- **是否包含复杂的逻辑?**组件应该尽量只包含 UI 相关逻辑,假设你的组件是个带有缩略图缓存、图片懒加载等功能的图片列表,那么我们建议你将这些功能相关代码从组件代码中分离出去,作为独立的模块来开发和维护。
- **是否包含自定义动画?**由于 LCUI 还未实现动画系统,像淡入淡出、弹入弹出等常见动画都得手动编码实现,考虑到复用,我们建议你将它们分离为独立的模块。
- **是否包含复杂的交互?**除了常规鼠标点击交互,我们可能还会添加一些其它交互效果来提升用户体验和操作效率,例如:鼠标操作中的拖拽和拖放,触控操作中的双指缩放和旋转。和上述条件一样,我们也建议你将它们分离为独立的模块。
以上条件是类似的,本质上是让你根据业务逻辑、动画和交互这几类再对组件代码做一次模块化。
待办事项
添加 img 组件
功能与 HTML 中的 img 元素相同,组件宽高自适应图片尺寸。
改进组件增量更新机制
为了应对数十万量级的组件更新,保证界面的流畅度,现有的做法是统计组件的更新耗时然后为每帧更新的组件总量设置一个合适的限制,这种做法并不是最优的,可参考 React 的 Fiber reconciler 的架构,重新设计 LCUI 的组件增量更新机制。
完善组件文档
这个章节的内容较少,应该参考 UI 开发相关文章继续完善。
📄️ 属性
介绍组件属性的分类及用途。
📄️ 样式
介绍组件的样式表操作方法和相关该概念。
📄️ 原型
介绍组件的原型相关概念和用法。
📄️ 事件
组件事件的相关概念和用法介绍。
📄️ 生命周期
组件从创建到更新再到销毁的过程。
📄️ 绘制流程
LCUI 的绘制流程是由脏矩形驱动的,窗口尺寸变化和组件的样式变化都会产生脏矩形,这些脏矩形主要集中在样式计算阶段和布局阶段产生,当脏矩形记录不为空时就会进入绘制流程,绘制流程由以下步骤组成: