「组件化」 一直是前端工程师绕不开的话题,不管是日常业务开发封装业务组件;还是基础设施建设开发UI组件或基础组件;亦或者是 React 、Vue、Angular 等MV*框架,都是秉承着组件作为基础原子概念,所以可以肯定的是: 组件是下一代 web 技术的发展关键 。
但业界并没有对组件化有一个准确的定义,都是一些主观的意识,一般都是以程序模式设计思想里的“高内聚、低耦合、高扩展、可复用”的几个基本概念来描述,组件内部要保证逻辑的集中和完整,组件外部要提供可扩展性api,并且独立性、简单可用性要保证。几个小的组件可层层嵌套,组合成一个大的组件,提供给外部使用,就像搭积木一样。
前端框架的本质也是进行组件化的抽象,现在前端框架的格局就是第一梯队三足鼎立、第二梯队百花齐放,但是归本溯源,各个框架最后编译的结果还是回归js、css、html,对于「组件」这一概念来说,只是在框架的设计思想上进行一些功能的抽象和代码的隔离,那这会带来什么问题?
- 由于我们前端项目越来越复杂,大型的项目中可能依赖几十、上百个第三方库,其中靠代码框架上的一些设计进行代码隔离,多多少少还是会出现一些适配性的冲突,比如DOM操作的冲突、样式CSS的冲突等。
- 越来越多公司的项目,为了适应新技术或者提升效率,不得不进行了技术栈的迁移,或者老项目新项目并存、微前端的引入等等,来融合不同的框架或者框架的版本到一个页面中。如 Vue2.x 升级到Vue3.x,则导致封装的基础组件和业务组件都面临着不可用的状况。
- 公司各个项目技术栈的不同,为了提高效率,封装组件的时候不得不去适配各个框架,比如一个业务组件就需要适配Vue、React技术栈,造成开发基础组件成本比较高。
图为 2021 前端框架top5
为了解决这些问题,我们需要一套完备的组件系统,来提高 前端 的开发效率,减少重复劳动,这才是符合前端提效、稳定的发展趋势。在此情况下,各种解决方案应运而生,而 Web Components 是其中关键性的一环。
那么,使用 Web Components 带来了哪些改变?我们来举个。
以前:
A:我造了一个Vue3的轮子,是关于身份信息卡片的。
B:正好,我需要我试试。wtf 是vue3的啊,我vue2用不了。
C:好可惜,我是react框架,也用不了。
D:啊!我是angular,也用不了!
E:老jq项目能不能用?
F:我引入了,但是和我目前项目的逻辑冲突了!
假如基于 Web Components 构建:
A:我造了一个Web Components的轮子,是关于身份信息卡片的,引入标签就能用了。
B:正好,我需要我试试,好像可以,用起来好简单!
C:我是react框架,没问题。
D:啊!我是angular,没问题,也完美!
E:老jq项目能不能用?能啊 nice!
F:我引入了,完美,无冲突。
那么,到底什么是 Web Components?
什么是 Web Components?
Web Components 提供了基于原生支持的、对视图层的封装能力,可以让单个组件相关的 javaScript、css、html模板运行在以html标签为界限的局部环境中,不会影响到全局,组件间也不会相互影响 。 再简单来说:就是提供了我们自定义标签的能力,并且提供了标签内完整的生命周期 。
Google 一直在推动浏览器原生组件规范「Web Components API」的发展,组件化的概念既然作为下一代发展的趋势,那么Google 肯定不会缺席。早在 Google I/O 2017 Polymer 就升级到了 2.0 版本,而这次升级的最主要意义就是将 Shadow Dom 和 Custom Elements 升级到 v1 版本,从而获得更多浏览器支持下一 代 Web Components 规范,时隔4年,各大浏览器厂商自然是纷纷跟进。目前支持情况如下:
Web Components 可以将组件化的概念直接应用到浏览器可以识别的 html 标签上,就比如我们开发html 页面常用的
- Custom elements:自定义元素
通过 CustomElementRegistry 来自定义可以直接渲染的html元素,并提供了组件的生命周期connectedCallback、disconnectCallback、attributeChangedCallback 等提供给开发者聚合逻辑时使用。
- Shadow DOM :隐式DOM
「影子DOM」 或 「隐式 DOM」,顾名思义,他具有隐藏属性,具体的意思就是说,在使用Shadow DOM的时候,组件标签内的 CSS 和 HTML 会完全的隐式存在于元素内部,在具体页面中,标签内部的HTML 结构会存在于#shdaow-root,而不会在真实的dom树中出现。
- HTML template: HTML模板
它的特性是用 template 标签包裹的元素不会立即渲染,只有在内容有效的时候,才会解析渲染,具有这个属性后,我们可以在自定义标签中按需添加我们需要的模板,并在自定义标签渲染的时候再去解析我们的模板,这样做可以在 HTML 有频繁更改更新任务,或者重写标记的时候非常有用。
我们来做一个 Web Components 特性简单的总结:
- 「标准统一」浏览器支持的底层api。
- 「灵活多变」可用于封装基础、业务组件。
- 「无侵入」以标签隔离、不会侵入业务代码、组件间不会相互影响。
- 「清晰」简单直接、不依赖外部模块、代码体积小。
看起来 Web Components 可以尝试解决由框架带来的基础组件不适配问题、复杂应用带来的组件定义冲突问题。并且得到了chrome 的支持和积极推动,顺应前端的发展潮流,是个不错的选择。
而且 Web Components 在移动化趋势的浪潮中,隐隐地向大前端方向渗透,跨端和跨框架实现的复用渐渐都是以组件的形式推动发展,所以我感觉 Web Components 的思想不单单是在web端,在多端开发领域也会有一定的影响。
所以这就是我选择 Web Components 来深入研究和应用的原因,顺应前端的时代的发展必将乘风破浪、水涨船高。
国外对于新技术的应用和探索一直领先我们,希望国内的小伙伴们也快速认识到趋势,并可以把前端的新思想,新趋势带入到业务中,提升研发效率,得到正向的反馈。同时也多多贡献自己的想法和轮子,提升中国前端在世界的影响力。