
干了8年前端,有时候回头看,感觉就像看了一部浓缩的科技史。我刚入行那会儿,简历上写"精通jQuery"还是个很重要的加分项;而现在,面试时聊的都是React Hooks、Vue Composition API,甚至开始讨论Svelte的runes
了。
技术名词在变,框架在变,但背后有一条主线,我觉得一直没变,那就是我们对组件化的追求。
今天不聊某个具体的技术,我想聊聊我作为一个亲历者,是如何看待前端组件化思想这近十年的演进的。从 jQuery 时代,到如今百花齐放的现代框架,我们解决如何组织和管理UI这个核心问题的思路,到底发生了怎样的变化?
jQuery 与"插件"思路

我职业生涯的初期,接触过不少用jQuery维护的老项目。在那个时代,我们还没有框架的概念。jQuery不是一个框架,它是一个极其强大的工具箱 ,它的核心使命是 Write Less, Do More,帮我们抹平浏览器差异,用简洁的API去操作DOM。
那时的组件化是什么样的?
它不是一种技术,而是一种约定 。我们把一块HTML、CSS和JS代码,在文件结构 上放在一起,然后用BEM这样的命名规范来防止CSS冲突。JS逻辑呢?通常是封装成一个jQuery插件。
比如,我们要写一个Tab切换组件:
JavaScript
// 伪代码,回忆一下当年的感觉
;(function($) {
$.fn.myTabs = function() {
// this 指向被选中的jQuery对象,比如 $('.tabs-container')
const $container = this;
const $navItems = $container.find('.tab-nav-item');
const $contentItems = $container.find('.tab-content-item');
$navItems.on('click', function() {
const index = $(this).index();
// 手动操作DOM,移除和添加class
$navItems.removeClass('active');
$(this).addClass('active');
$contentItems.hide().eq(index).show();
});
return this; // 维持链式调用
};
})(jQuery);
// 使用
$('.tabs-container').myTabs();
它的特点:
- 命令式 :代码充满了对DOM的直接、手动的操作(
addClass
,removeClass
,hide
,show
)。 - 状态与视图耦合 :UI的状态,一部分存在于JS变量里(比如
index
),一部分直接存在于DOM里(比如.active
这个class)。
React 与"状态驱动视图"

大概在2015、2016年之后,React带来了前端开发思想上的变革。
它告诉我们: "你不要再去管DOM了,你只需要关心你的'状态'(state)。状态变了,UI会自动更新。"
这是一种从命令式 到 声明式的巨大转变。
它的核心是什么?
- 虚拟DOM (Virtual DOM) :React在内存中维护一个轻量的JS对象树,来描述真实的DOM。当我们改变状态时,React会计算出一个新的虚拟DOM树,然后通过Diff算法,找出新旧两棵树的最小差异,最后才把这些差异,一次性地更新到真实DOM上。
- 真正的组件 :React从语言层面,提供了一个强大的组件模型。一个组件,就是一个独立的、拥有自己状态(
state
)、属性(props
)和生命周期的单元。我们开始像搭乐高一样,把这些独立的组件拼装成一个完整的应用。
JavaScript
// React Hooks的写法
function MyTabs({ items }) {
const [activeIndex, setActiveIndex] = useState(0);
return (
<div className="tabs-container">
<nav>
{items.map((item, index) => (
<div
key={item.id}
className={`tab-nav-item ${index === activeIndex ? 'active' : ''}`}
onClick={() => setActiveIndex(index)}
>
{item.title}
</div>
))}
</nav>
<div className="tab-content">
{items[activeIndex]?.content}
</div>
</div>
);
}
它的特点:
- 声明式 :我们只描述在某个状态下,UI应该长什么样,而不用关心具体如何操作DOM。
- 状态驱动:UI是状态的映射。状态是唯一的数据源。
当然,这样也带来了新的"烦恼"。我们从"手动管理DOM"的痛苦,进入了"手动管理性能优化(memo
, useCallback
)"和"手动管理副作用(useEffect
)"的新阶段。
Svelte 与"编译器"思维

当React和Vue还在为"如何优化运行时"而"内卷"时,Svelte另辟蹊径,提出了一个颠覆性的想法:
"我们能不能,在'运行时',什么都不干?"
如果说React是把"如何更新DOM"的复杂工作,从"开发者"交给了"框架的运行时",那么Svelte则更进一步,它把这项工作,从"运行时 ",提前到了"编译期"。
Svelte的核心思想:
Svelte不是一个传统意义上的"框架库",它是一个"编译器"。它会在你写完代码、执行打包时,把你的.svelte组件文件,直接编译成没有额外抽象、极其高效的原生JavaScript代码。
HTML
<script>
let activeIndex = 0;
export let items = []; // 接收props
</script>
<div class="tabs-container">
<nav>
{#each items as item, index}
<div
class="tab-nav-item"
class:active={index === activeIndex}
on:click={() => activeIndex = index}
>
{item.title}
</div>
{/each}
</nav>
<div class="tab-content">
{items[activeIndex]?.content}
</div>
</div>
它的特点:
- 真正的响应式 :你看到
activeIndex = index
这行代码时,Svelte的编译器就会自动在它后面"织入"更新DOM所需要的原生JS代码。没有虚拟DOM,没有Diff算法,就是最直接的DOM操作。 - 极致的简洁:代码量极少,没有各种Hooks的规则和心智负担,非常接近原生JS。
到了2025年的今天,Svelte 5推出的runes
,更是将这种"响应式"模型变得更加清晰和强大,解决了之前版本的一些边界问题。
回顾这八年,前端组件化的演进,在我看来,本质上就是一部经典的前端历史。
- jQuery:需要手动同步状态和DOM。
- React:只需要管理好状态,把DOM更新的工作交给框架。
- Svelte时代:只需要描述清楚意图,剩下的脏活累活,都由编译器在打包时就完成了。
我们写的代码越来越少,框架和工具为我们做的事情越来越多,让我们能更专注于业务逻辑本身。
未来会怎样?我不知道。但我很期待。作为一个热爱探索的工程师,能亲身处在这个飞速变化的时代,本身就是一件幸事。你们怎么看🙂