web components 前端组件化趋势?

前言

前端快速发展的今天,组件贯彻着我们日常开发的方方面面,不管是针对业务封装的业务组件,还是项目中依赖的第三方基础 UI 组件(Ant Design、Element),亦或是依赖的前端框架(Angular、Vue、React),它们都贯彻着「组件化」的概念,而这一切「组件化」都是「高内聚、低耦合」思想下的产物。

「组件化」开发已然成为前端主流开发方式,因为「组件化」开发在代码复用、提升团队效率方面有着无可比拟的优势,现在流行的 Vue、React、Angular 等等框架都是组件框架。所以毫不夸张的说 「组件化将会是前端的发展方向」

目前存在问题

作者所在的部门一半的项目用的 Vue 技术栈,一半的项目用的 React 技术栈,遵循「高内聚、低耦合」的原则,我们为这两套技术栈分别搭建了Vue UI 组件库和React UI 组件库。这两套 UI 组件库的功能几乎毫无差异,但是要由两个团队来维护。适配这两个框架,将要耗费双倍的人力成本。

即使针对同一个技术栈,在面临版本升级时,旧的组件库也会存在不可用的情况。比如:Vue 从 2.x 升级到 3.x 版本,React从 17版本升级到 18 版本, 之前封装的基础组件和业务组件都在新版本中就不能正常使用。一套组件库在同一个框架不同版本之间存在差异,甚至只能固定在某一个版本中使用,这本身于前端的「组件化」趋势是相违背的。

随着前端复杂度的增加,项目中使用的框架越来越多,会在不经意间出现样式的冲突。很多框架在组件设计时没有样式进行样式隔,例如:在使用 React 时,React 在书写组件样式时经常出现样式覆盖、错乱的问题,不得不借助其他方案来解决此类问题。

Webpack 盛行的今天,大多数项目使用 Webpack 作为编译工具,这让组件经过 Webpack 编译之后想要在运行时即引即用变得不太现实。

前端框架的「组件化」并不是真正的「组件化」。虽然书写代码时的确是「组件化」的方法在写,但是编译完之后就不再「组件化」了。

「组件化」给前端的开发带来了极大的效率提升,随着发展前端「组件化」的框架也因此层出不穷,从最早的 jQuery,再到 React、Vue、Angular、Ratchet、Ionic 等等,几乎每年都有很多新的框架如雨后春笋悄然而生,它们或借鉴或颠覆其他已存在的框架,究其本质这些框架的很大一部分模块在功能上是重合的,但也仅仅在功能层面重合,代码层面确完全不兼容。

为了解决这些问题,各种解决方案层出不穷,其中 Web ***ponents 就是其中关键的一环。

什么是web ***ponents?

Web ***ponents 也是一个浏览器原生支持的组件化方案,允许你创建新的自定义、可封装的HTML 标记,使用时不用加载任何额外的模块。自定义组件和小部件基于 Web ***ponents 标准构建,可跨现代浏览器工作,并可与任何支持 HTML 的 JavaScript 库或框架一起使用。

web ***ponents的历史:

实际上:Vue 作者在创建 Vue 的时候大量参考了 Web ***ponents 的语法。

web ***ponents的组成:

Custom element(自定义元素):一组 JavaScript API,允许你定义 custom elements 及其行为,然后可以在你的用户界面中按照需要使用它们。

Shadow DOM(影子 DOM):一组 JavaScript API,用于将封装的“影子”DOM 树附加到元素(与主文档 DOM 分开呈现)并控制其关联的功能。通过这种方式,你可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。

HTML template(HTML 模板): [` 和 `` 元素使你可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。

web ***ponents的使用
js"><!-- 自定义组件的使用 -->
    <my-button as-atom></my-button>
    <template id="my-button-template">
        <button class="my-button">click</button>
        <style>
            .my-button {
                padding: 10px 20px;
                font-size: 16px;
                border-radius: 12px;
                background-color: rgb(35, 64, 121);
                color: white;
                border: none;
            }
        </style>
    </template>
    <script>
        class MyButton extends HTMLElement {
            constructor() {
                super();
                const shadow = this.attachShadow({ mode: 'closed' });

                const templateElem = document.getElementById('my-button-template');
                const content = templateElem.content.cloneNode(true);

                shadow.appendChild(content);

                /* 添加点击事件 */
                this.$button = shadow.querySelector('button');
                this.$button.addEventListener('click', () => {
                    this.dispatchEvent(
                        new CustomEvent('myClick', {
                            detail: 'hello'
                        })
                    )
                });
            }

            // 类似mounted
            connectedCallback() {
                if (this.hasAttribute('as-atom')) {
                    this.$button.style.padding = '0';
                }
            }

            get label() {
                return this.getAttribute('label');
            }

            set label(value) {
                this.setAttribute('label', value);
            }

            static get observedAttributes() {
                return ['label'];
            }

            attributeChangedCallback(name, oldVal, newVal) {
                this.render();
            }

            render() {
                this.$button.innerHTML = this.label;
            }
        }
        window.customElements.define('my-button', MyButton);
    </script>
</body>
成熟的组件库
  • hybrids: 是一个 JavaScript UI 框架,用于创建功能齐全的 Web 应用程序、组件库或具有独特的混合声明性和功能性架构的单个 Web ***ponents。
  • Polymer :是 Google 推出的 Web ***ponents 库,支持数据的单向和双向绑定,兼容性较好,跨浏览器性能也较好;提供了一组用于创建 custom elements 的功能。这些功能旨在使 custom elements 像标准 DOM 元素一样工作更容易和更快。
转载请说明出处内容投诉
CSS教程_站长资源网 » web components 前端组件化趋势?

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买