从 Web Components 到 React 谈前端组件化

0

前端的社区非常活跃,各种底层的框架和库层出不穷,而在这些框架和库的基础上也涌现出了一批又一批用各自的思想来实现的 UI 组件。前端本身的工作领域就专注在 UI 展现层上,一套好用的 UI 组件能提升团队的工作效率,但是这些组件的通用性和移植性并不强。

W3C 提出来的 Web Components 标准化的组件化方案,尝试去解决上面提到的各自为战的问题,在其刚提出来的那段时间确实火了一阵子,Google 的开发团队也在此基础上推出了基于 Web Components 的框架 Polymer。

先来看看使用 Web Components 如何定义一个组件。

<hello-world>
<!-- Shadow dom -->
<style>
.para { background: orange; color: #fff;}
</style>
<div>
    <button onclick="handleClick()">Say Hello</button>
    <p class="para"></p>
</div>
<script>
    var handleClick = function(event) {
        window.event.target.nextElementSibling.textContent = 'Hello World!';
    };
</script>
<!-- /Shadow dom -->
</hello-world>

Web Components 把组件的资源都封装到了 Shadow DOM 中,Shadow DOM 中包含了组件的结构、样式、行为,对于使用者来说,这些资源都是不可见的,对于开发人员来说,可以直接使用原生的 HTML、CSS、JavaScript 代码来开发一个组件。一个组件就是一个 .html 文件,通过 HTML Imports 来加载使用。

看起来挺美好的,但是真正要使用起来会存在一些问题:

  • 兼容性
  • 性能
  • 易用性

而 React 并没有采用 Web Components 的方案,React 用自己的设计思想解决了组件设计中的痛点。对比 React 和 Web Components 的流行程度和社区的活跃程度就知道开发者更喜欢哪种组件化的设计思想。

再来看看使用 React 如何定义一个组件。

var HelloWorld = React.createClass({
    handleClick: function () {
        this.refs.para.getDOMNode().textContent = 'Hello World!';
    },

    render: function () {
        var paraStyle = {
            background: 'orange',
            color: '#fff'
        };

        return (
            <div>
                <button onClick={this.handleClick}>Say Hello</button>
                <p className="para" ref="para" style={paraStyle}></p>
            </div>
        );
    }
});

React 通过 JSXInline Style 将组件的结构、样式、行为都封装在一个 JavaScript 的类中,一个组件就是一个类,要使用该组件可以通过 React.render 来将其渲染到页面中。

<div id="root"></div>

React.render(
    <HelloWorld />,
    document.getElementById('root')
);

一个组件可以是可以是一个独立的 .js 模块文件,加载和使用一个模块非常方便。JSX 解决了在 JavaScript 代码中能很方便的放置组件结构的问题,就跟写原生的 HTML 一样,Inline Style 解决了将组件的样式封装在组件内部的问题,使用 JavaScript 对象来描述样式。这些看起来都是反模式化、反标准化的,但却解决了实实在在的问题,对于组件的开发者和使用者都非常方便。

仅仅从上面提到的特性来说,还没有足够的理由来让大家使用 React,退一步讲可能只是个人偏好而已。但是 React 还有保证其组件能有高性能的 Virtual DOM,开发者并不直接操作真实的 DOM,而是由 React 来接管 DOM 操作,其底层的 DiffRender 算法能确保大批量和频繁的操作 DOM 都有很高的性能。Virtual DOM 对于开发者来说是透明的,关于 Virtual DOM 在本文中就不展开详述了,在后续的文章中将详细的探讨。

原载于:雨夜带刀’s Blog
本文链接:https://blog.yiguochen.com/web-components-and-react.html
如需转载请以链接形式注明原载或原文地址。