skip to content
logo

Search

部件(业务组件)与上下文

部件

在做业务开发时总会碰到这种情形 👇🏻

几个表格页或者表单页看起来很相似,有很多重复代码,觉得可以封装成一个「业务组件」,于是就那么去做了;当看到重复代码减少了一大半,很有成就感,心里美滋滋~ 😎

但随着这类看似相近的页面越来越多,自己封装的那个「业务组件」的属性也跟着多了起来,并且那些属性中使用率高的也没几个,这时不禁开始怀疑自己:「我是不是被眼前的表象给忽悠了?!」😥

这种在业务开发中,封装的比较强依赖于特定场景的「业务组件」,我一般叫做「部件」。

根据过往的经验,在相对大粒度的部件中,如果还是像处理相对小粒度的基础组件一样主要靠属性和事件进行通信,那效果肯定会不够理想。

那么,在部件中的主要通信手段该是什么呢?🤔

上下文

有个经典的「八股文」前端面试题:「请说说组件间如何进行通信?」

熟背「八股文」的人会立马脱口而出:「父子间用属性和事件,兄弟间就以父组件为中介通过属性和事件;跨层级的话,在 Vue 中用 provide / inject,在 React 中用 Context;再就是 Vuex、Pinia 之类全局的状态管理方案。」

有的面试官可能还会进一步问:「跨层级通信的上下文和状态管理是什么?为什么会有它们?」听到这个问题,面试者心里一颤:「这……这有点超纲了吧?!我背的八股文里没有这个啊……」

在我的理解中,虽然细节上有点区别,但「上下文」和「状态管理」都是更广义一点的「上下文」

在编程语言中,「上下文」一般是指让程序能够正常执行的一组环境变量,如执行上下文;而在应用开发中,通常衍生为用来维护作用于一定范围的状态的对象。

构造并传入或注入「上下文」是一种比较好的让 UI 组件变「瘦」的实践

在 UI 组件树中,从某一层开始往下的几层所包含的 UI 组件是一个相对独立的子系统,它们要协作完成同一个任务,与这个任务相关的状态和操作无需分散在各个 UI 组件中,经由「上下文」集中管理可让状态更好维护,状态变化更容易追踪。

欧雷《聊聊中后台前端应用:模块相关的一些事

在相对大粒度的部件中,如果还是主要依赖属性和事件进行通信的话,那它们的数量很容易就会失控,并且内部的结构和逻辑也会被改得面目全非,维护起来十分困难和难受,最终变成一坨翔!💩

所以,与 UI 组件本身的自然特性无关的东西,不应作为其属性或事件存在,而是「上下文」。

部件内部尽量不要有交互逻辑和业务逻辑,也尽可能不去维护任何状态,部件中理论上只有业务与交互/展现间的转换逻辑

  • 业务的状态与逻辑上升至上下文中
  • 交互逻辑下沉到控件中
  • 展现状态由业务状态计算出来

拿人做类比,帮助理解:人有头、躯干、四肢、脑、五脏六腑等组成部分,经过脑活动可以进行交流、创造等,这些是人的自然特性。

但是人的职业、角色、身份等是自然特性吗?当然不是!这些是人脑的运作机制在特定的环境、上下文中对接收到的信息处理后所形成的结果。

由此可见,人的自然特性是有限的,而由自然特性所衍生出来职业、角色、身份等则是无限的。鉴于此,倘若把 UI 组件的非自然特性设计为属性,其数量将多如牛毛。那些具有业务、配置语义的东西,理应作为环境、上下文被 UI 组件内部起到人脑作用的程序所「理解」,并做出相应的「反应」或「动作」。

另外,集成了像「数据上下文」这种业务应用开发框架所提供的机制的 UI 组件也叫「部件」。这类部件大、小粒度的都有。

综上所述,「上下文」是业务的状态和逻辑复用的一种方式,是「部件」的主要通信手段;而「部件」则是连接了「上下文」与「控件」的「适配器」。

拓展阅读: