【思考】为什么前端组件化可以一统江湖

Photo by AltumCode on Unsplash

许多入门前端的朋友都知道组件的概念,也在日常工作中用到组件,写组件,也和别人讨论组件。但是前端为什么是建立在组件上的呢?昔日辉煌一时的 jQuery 为什么会没落,到底要怎样组织组件才能提高平时的工作效率,减轻逻辑复杂度引起的脱发失眠和扯皮翻脸呢?

本文会从以下几点回答上面的问题:

  • 首先,讲一点点组件概念的来源,跨多个平台语言
  • 然后,掰开组件背后隐藏的线,讲一下这种思维模型的大一统
  • 再然后,从软件工程的全局视野聊组件的分类管理
  • 最后算是彩蛋,聊一聊为什么“道理全都懂”就是写不好组件

一、组件的概念源于已有的 UI 解决方案

所谓组件,其实是一种对 UI 界面做组织的解决方案。复杂点的网站,UI 模块千千万,管理不好真难看。

UI 的管理,从最早的桌面应用开始,就是一个头疼的问题。

早期 Java 或是 C++ 使用代码一行一行写界面,一个界面几百行,顺带参入数据逻辑控制,方法接口调用,基本就是一锅大杂烩,啥都有了。

这就导致代码很难维护,修任何小问题、小改动都要看200+行代码,脑袋里容下30多个变量,真是干过的都头大。

怎么管理这种复杂度呢?

同许多软件行业中复杂问题的解决方案类似:

树。

于是 XML 站了出来。把复杂的 UI 结构分层次、分模块地写成一棵树,根部是入口,入口拆三五大模块,每个模块再分叉成子模块,子模块再分叉成子子模块,子子孙孙无穷尽。

想象一下,100w 个节点挂在一棵二叉树(每个节点最多分两叉所以叫二叉)上,也就只有20层,这样一个 XML 的解决办法,一下就 hold 住了大量的 UI 模块。

tree-xml-xueya.png

做过 Android 开发或 iOS 开发的朋友应该对 XML 定义 UI 都不会陌生。如下是 Android 入门中的一个 UI 定义,简单来看,主界面是 ConstraintLayout,一种布局,里面包含一个 TextView 文本展示 “Hello World!”.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

彼时(上古时代,也就是十来年前)的前端也是用这样的方式来定义 UI 的,称之为 HTML。

前端那时候的工作内容,就是把内容搬到 HTML 里,简单到被同行瞧不起(就是个玩具🎈)。不过也没办法,设备太慢跑不起来逻辑。急?那就在后端稍微渲染一下数据。

所以有那么一段时间,前端代码不是纯正的 HTML,而是各种改动过的版本,里面标记了许多小脚本在服务器上运行,这样用户下载的网页可以在下载前被事先放上去一些数据,勉为其难称之为逻辑。。吧。那个模板引擎满天飞的旧时光。

然后,时代变了,设备变快了。

jQuery 就像一行一行写就的 UI,跟不上 XML 的强交互性,新的时代需要一位新的霸主。React.js 应运而生。

借着 XML (咳咳,HTML)的 UI 标记思维,设备提速的东风,React.js 用组件(a.k.a. Component)更新了前端的设计思维。

一套完整的 UI 解决方案,更新了一个领域,形成了这个领域的新职业,才有了我们这些前端攻城狮的饭碗。

二、组件,思维模型的大一统

教过家里老人用手机的人,一定都体会过让他们理解什么是按钮的痛苦。为什么呢?因为你我上网多年,也被电脑程序教育了多年。我们习惯于每个界面都是个方框,方框里有文字有图片,内容多了可以上下滚动,按钮总是整齐地摆在一边。

这些潜移默化中形成的共识,是多年互联网融入生活的过程,也是 XML 解决 UI 问题的过程。

你品这个过程:

  • 产品经理从产品构思初期就在画大框框
  • 他们忙完了交付设计师,设计师在大框框里设计美观的小框框和交互体验
  • 前端工程师把这些大大小小的框框画进界面标记(即组件的 JSX)里,接好数据生米煮成熟饭
  • 用户拿到产品,直观接受产品的大框架,欢心地体验小框细节(也偶尔对着某些不靠谱的 bug 破口大骂)

整个过程从生产到用户,同一个心理模型,减少多少不必要的转换?要知道,软件工程的宏观视角里,就没有转换引不进来的坑。

(所以最高的效率就是不要转换!不要转换!不要转换!不产生过多的心理模型,不引入思维负担,人类还值得被拯救。)

心理模型的统一带来了高效的沟通,便捷的改动,顺应时代潮流,顺应民心,自然开发也快了,bug 也少了,大家都睡得着觉了,双双双赢。

组件思维也因此,从 React 走向 Vue,走向 Angular,Ionic,Svelte,Web Component 和其他。

三、鸟瞰组件规划

讲到组件之于 UI 复杂度的功效,就不得不讲软件开发的另外一个大冤种:数据管理。

不同的界面可能要用到同样的数据,同一个界面可能又要加载不同的数据。这些稀松平常的场景,其实隐藏了一个非常大的问题:

UI 树上挂不下数据管理的果。

左手 UI 树,右手数据池,中间是数据牵线,这是近几年前端工程师最平淡的日常,数据关联密密麻麻,头皮发麻。

用 MVC 的话说,V(View 就是 UI)和 M(Model 就是数据)站两边,中间 Controller 能写多满写多满。

明白这个道理,就明白了合理的组件获取数据,是不受 UI 组件在组件树中位置限制的。

Redux(某著名 React 全家桶数据管理库)就提出,应当专门把组件分成两类:

  • Presentational Components:负责组件的形,类似于橱窗里的人台(那个假人)
  • Container Components:负责对接数据,类似于人台身上的衣服

你再品一品前面说的大一统的思维模型,组件的拆分马上就清晰了:

  • 先按照产品的思路,大块大块地拆组件
  • 然后按照设计师的思路,局部拆小组件
  • 拆好的组件全是展示层,没有数据(此时你就可以满地写 const FAKE_DATA 赶紧调试了,赶在后端想好之前跟他对,兵贵神速)
  • 数据接进来,给 Presentational Components 套上 Container (给人台穿上衣服)

组件越趋近于产品与设计师的思维模型,改动成本就越小,所以我建议你同时也多了解一下这些上游同事(专指多请客吃饭),好在下次概念大改的时候可以争取一下。

末、彩蛋:什么道理都懂,为什么代码还是屎山 ⛰

最重要的话先刷三遍:

代码写不好其实不怪你。

代码写不好其实不怪你。

代码写不好其实不怪你。

这是一个 Deadline 思维引起的不可持续发展的形态问题。

软件公司一开始只有一个思维模型形态,于是做成做好很容易。

然而无论是市场还是老板,都期望这个模型有所变化,以更好地适应用户的需求。

于是出现了 v2.0。

你,无辜弱小可怜的从业者,和 HR 聊福利的时候开心得花枝乱颤,很不幸,拿到的是 v10.0 版本。前面有9个版本已经废弃,转型,而且当时的人没有留下来,想法没有记录下来(大概率记录下来了,但是写得不明不白,还有记错的)。

给你10天时间,改 v10.0 为 v11.0。你做得了吗?做完马上开始 v12.0 你开得了吗?

你必须回答做得了。

于是你折腾,深夜里痛哭,晨曦中 debug,反正懂不懂的都看到效果了,上线,然后倒头睡觉。

Deadline 杀死了员工的懒惰心理,也葬送了对复杂度的合理管控。

这些都不重要,因为你也不可能在这家公司干一辈子不是?(事实是有限的 Deadline 面前,挑战屎山大概率都是自寻死路

所以进了下一家公司,你闭着眼睛也会说:这个项目没法维护了,需要重写(我才不当大冤种)。


软件行业一直是一个需要快速学习的行业,今天 React 明天 Vue,学完 Java 又要学 Golang。

工具更新千千万,其实背后的原理却不多,而且大多数对复杂度的管理早就在软件工程专业发展的过程中被定位并解决掉了。网页渲染在重前端和重后端的选择之间反复横跳,根本目的不过是压榨设备的利用效率和提高开发工作的效率和质量。

相较于技术的飞速迭代,原理本身才是陈年的老酒,在这个换汤不换药的洪流里,始终散发着智慧的光芒。

我是雪牙,一名新手友好的程序员,带你品酒的攻城狮。希望我的分享可以帮你清醒,思辨,成长。

感谢你的点赞、收藏和关注,祝好。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容

  • 组件化 应用➡️页面➡️模块➡️组件➡️ 组件与组件之间的关系是组合不是依赖 资源加载路径的层级问题? ../....
    神刀阅读 1,435评论 0 2
  • 引言提到前端往往很多人的映像就是入门简单,HTML、CSS加一起一个星期基本上就能大概上手,JS难一点但也能很快写...
    Mr丶Sunny阅读 4,334评论 0 16
  • 本文章是我最近在公司的一场内部分享的内容。我有个习惯就是每次分享都会先将要分享的内容写成文章。所以这个文集也是用来...
    Awey阅读 9,452评论 4 67
  • 设计B端项目,我们需要思考的是如何运用组件化的思维去维护后续的迭代和优化,以及如何进行团队的协作。而团队化的组件规...
    设计芯阅读 1,834评论 0 16
  • 一、前端框架库: 1.Zepto.js 地址:点击打开链接 描述:Zepto是一个轻量级的针对现代高级浏览器的Ja...
    武汉前端阿杰1001阅读 12,146评论 0 1