Web Components:原生组件化开发新趋势,一个考公程序员的真实探索
上周五晚上十点半,浦东张江某小区出租屋里,台灯的光斜斜地打在我的MacBook屏幕上。女友小雅已经蜷在沙发上看《令人心动的offer》第五季了,时不时笑出声。而我,还在调试一个奇怪的样式隔离问题——明明用了Shadow DOM,为什么全局CSS还是“污染”进来了?
“你又在搞什么神秘代码?”她头也不抬地问。
“Web Components……”我叹了口气,“公司新项目要用,但文档太散,社区也不热闹,感觉像在荒野里搭积木。”
“哦。”她顿了顿,又补了一句,“你不是说要考公吗?怎么还在研究新技术?”
我愣了一下,没回答。这个问题,其实我也一直在问自己。
我是阿哲,坐标上海,一名在职程序员,月薪22k(税前),和小雅合租在浦东,月租3500。每天早上七点起床,挤地铁去张江,晚上九点才到家。表面看,生活稳定,技术栈也还行——React、Vue都用过,Node.js也能撸,但内心却越来越不安。
去年十月,我妈打来电话:“隔壁老王家儿子考上税务局了,朝九晚五,公积金高,还有食堂。”语气里满是羡慕。那晚我失眠了。我开始认真考虑“上岸”这件事——不是因为讨厌编程,而是厌倦了35岁焦虑、需求变更如流水、以及永远在“交付倒计时”中的窒息感。
但现实是,考公不是说走就走的旅行。报名费、教材、培训班,再加上万一辞职备考的风险,我和小雅商量后决定:在职备考,同时把手头工作做到极致。毕竟,哪怕未来进了体制,懂技术也是优势,对吧?
于是,我一边刷行测题,一边硬着头皮接下了公司新项目的前端架构任务——一个面向内部运营团队的低代码平台。产品经理老李拍着我肩膀说:“这次要支持高度可复用的组件,运营同事拖拽就能用,你看着办。”
我苦笑。这不就是组件化的终极命题吗?
我们团队之前一直用React。说实话,React生态强大得离谱,Hooks、Context、Redux Toolkit……应有尽有。但这次的需求有点特殊:组件要能被非React项目调用,比如老系统用的jQuery,或者未来可能用Vue重写的模块。更头疼的是,运营同事不懂JSX,他们只想要一个<data-chart>标签,传几个属性就行。
“能不能做成像HTML原生标签那样?”老李在周会上问。
那一刻,我脑子里闪过一个词:Web Components。
但说实话,我对它印象很模糊。几年前在MDN上扫过一眼,觉得“原生是好,但生态弱,没人用”。可现在,面对跨框架、长期维护、运营友好这些硬需求,React的“封闭生态”反而成了枷锁。
于是,我开始深入研究Web Components。
Web Components 其实是一组浏览器原生支持的技术规范,主要包括三块:Custom Elements(自定义元素)、Shadow DOM(影子DOM)、HTML Templates(模板)。听起来很抽象,但核心思想特别朴素:用原生方式封装UI组件,不依赖任何框架。
我试着写了一个最简单的例子:
class DataChart extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
.chart { width: 100%; height: 300px; background: #f5f5f5; }
</style>
<div class="chart">数据图表占位</div>
`;
}
}
customElements.define('data-chart', DataChart);
然后在HTML里直接写:
<data-chart></data-chart>
搞定!不需要打包,不需要构建工具,浏览器原生支持。运营同事看到后眼睛一亮:“这不就是个新标签吗?我会用!”
但问题很快来了。React怎么用这个组件?
起初我以为很简单,直接<data-chart />就行。结果控制台报错:“Unknown DOM property”。原来React会把props当作DOM属性处理,而Web Components依赖的是attributes或properties,两者机制不同。
我查了一堆资料,最后用ref手动设置属性才解决:
const MyComponent = () => {
const chartRef = useRef(null);
useEffect(() => {
if (chartRef.current) {
chartRef.current.data = someData; // 直接操作实例属性
}
}, [someData]);
return <data-chart ref={chartRef} />;
};
虽然能跑,但体验远不如React自己的组件顺滑。那一刻我有点动摇:是不是选错了路?
转机出现在一次深夜加班。
那天凌晨一点,我和后端小陈在公司改bug。他突然问我:“你们前端那个<user-badge>组件,能不能给我们管理后台用?我们是纯HTML+jQuery的老系统。”
我心头一震。如果用React,他们得引入整个React运行时,还要配Webpack,光构建就得折腾半天。但Web Components?只要浏览器支持,复制粘贴一段JS,再加个标签就行。
我当场演示给他看。他瞪大眼睛:“真的假的?就这么简单?”
那一刻,我忽然明白了Web Components的真正价值:不是取代React,而是作为“通用语言”存在。
React适合构建复杂交互的应用,而Web Components适合做原子级、跨技术栈、长期维护的UI模块。尤其是面向运营场景——运营工具往往生命周期长,技术栈杂,需求变化快但功能单一。用原生组件,既能保证稳定性,又降低协作成本。
于是,我调整了策略:核心应用继续用React,但把可复用的UI原子(如按钮、表单控件、图表、通知栏)抽成Web Components。这样,无论是未来的Vue项目,还是老系统的jQuery页面,都能无缝接入。
我还写了个简单的文档,教运营同事怎么用:
“只需要在页面加一行script,然后写
<ops-button variant='primary'>提交</ops-button>,就行了。颜色、大小、禁用状态,全靠属性控制。”
他们居然真的学会了!上周,运营小姐姐自己拼出了一个完整的活动配置页,没找我帮忙。那一刻,比收到年终奖还爽。
当然,Web Components也不是万能药。
它的缺点很明显:没有状态管理、没有响应式更新、事件系统原始。如果你要做一个复杂的表单联动,用它会写到怀疑人生。而且,调试Shadow DOM里的样式也挺反人类——Chrome DevTools虽然支持,但层级嵌套深了就眼花。
但换个角度想,这些“缺陷”恰恰是它的优势。正因为简单,所以稳定;正因为无依赖,所以长寿。在一个追求“快速迭代”的互联网公司里,这种“慢而稳”的技术,反而成了对抗技术债的利器。
更重要的是,它让我重新思考“组件化”的本质。
React教会我们用函数和状态构建UI,而Web Components提醒我们:组件的本质,是封装与复用,而不是绑定某个框架。真正的工程能力,不是掌握多少框架API,而是能在不同约束下,选择最合适的工具。
回过头看,这段经历对我备考也有启发。
很多人觉得考公就是“逃离技术”,但我觉得未必。体制内也在数字化转型,很多部门急需既懂业务又懂技术的人。比如我最近刷到的岗位:“信息化岗”、“数字政府建设岗”,明确要求“熟悉前端技术,有组件化开发经验”。
或许,Web Components 这样的“通用技能”,反而比某个框架的熟练度更有长期价值。
上周日,我和小雅去世纪公园散步。她问我:“你还焦虑吗?”
我说:“还是会,但没那么怕了。技术在变,岗位在变,但解决问题的能力不会过时。不管是写代码,还是写申论,底层逻辑都是:看清问题,拆解步骤,一步步来。”
她笑了:“那你申论练得咋样了?”
“别提了,大作文还在跑题……”我挠头。
最后,给同样在技术和稳定之间摇摆的朋友几点建议:
- 不要神化或妖魔化任何技术。Web Components 不是银弹,React 也不是洪水猛兽。关键是根据场景选工具。
- 运营导向的项目,优先考虑简单、稳定、易接入。Web Components 在这类场景有天然优势。
- 综合能力比单一技能更重要。考公也好,跳槽也罢,面试官更看重你如何思考问题,而不是你会几个框架。
- 保持学习,但别被潮流裹挟。新技术值得了解,但不必盲目追。Web Components 已经存在十年了,现在才火,说明它经得起时间考验。
写这篇文章的时候,已经是凌晨一点。窗外张江的写字楼大多熄了灯,只有零星几盏还亮着。我知道,明天还要早起刷题,还要改bug,还要面对无数个“能不能加个需求”的消息。
但我不再慌了。因为无论未来是在代码世界,还是在体制之内,解决问题的能力,永远是我的底气。
Web Components 教会我的,不只是如何写一个自定义标签,更是如何在复杂世界中,找到属于自己的那份“原生稳定”。
共勉。

评论 0