当前位置:   article > 正文

八个 Web Components 前端框架,一定有一个你用得上

webcomponents 框架

聚焦于真正的技术, 所以, 今天你又博学了吗?

大厂技术  坚持周更  精选好文

通过之前的系列文章,大家对 Web Components 一定有了一个深入的了解。通过实战也对 Web Components 怎么写、怎么用比较熟悉了。

但是,在实现时我们不难发现,原生的 Web Component 对于封装组件其实并不是很流畅,需要对属性进行处理、需要对数据进行监听、需要对事件进行控制等等。这一切都在和效率开发背道而驰。

所以在针对这些不符合现在开发模式的情况,出现了很多 Web Components 前端框架

Stencil

Stencil 是用于生成 Web Components 的编译器,由 Ionic 团队构建。Stencil 允许开发人员使用。TypeScript 和 JSX 等技术来定义组件,然后生成可在现代浏览器和旧版浏览器上运行的 100% 基于标准的 Web Component。当你的组件一旦经过 build 完成后,就会脱离 Stencil,不再依赖。并且 Stencil 相对原生 Web Components 提供了完善的项目目录架构和配置,与直接使用 Custom Elements 相比,Stencil 提供了额外的 API,使编写快速组件变得更加简单,Stencli 具有以下特性:

  • Virtual DOM

  • JSX 和异步渲染等 API 使快速

  • 强大的组件创建

  • Reactive data-binding 单向数据流

  • 组件懒加载

  • 无依赖性组件

  • 静态网站生成(SSG)

  • ...

开发人员体验也得到了调整,并带有实时重新加载和嵌入编译器的小型开发服务器。

通过 "npm init stencil" 我们可以去体验 Stencil 提供 cli 工具,Stencil 会提供保姆式的选项配置:

272032e7cd1d13da860bea7e7df600d3.png

Stencil 组件看起来很像基于类的 React 组件,只是添加了 TypeScript 装饰器:

  1. import { Component, Prop, h } from '@stencil/core';
  2. import { format } from '../../utils/utils';
  3. @Component({
  4.   tag: 'my-component',
  5.   styleUrl: 'my-component.css',
  6.   shadow: true,
  7. })
  8. export class MyComponent {
  9.   /**
  10.    * The first name
  11.    */
  12.   @Prop() first: string;
  13.   /**
  14.    * The middle name
  15.    */
  16.   @Prop() middle: string;
  17.   /**
  18.    * The last name
  19.    */
  20.   @Prop() last: string;
  21.   private getText(): string {
  22.     return format(this.first, this.middle, this.last);
  23.   }
  24.   render() {
  25.     return <div>Hello, World! I'm {this.getText()}</div>;
  26.   }
  27. }

上面的组件可以像任何其他 HTML 元素一样使用:

<my-component first="Stencil" last="'Don't call me a framework' JS"></my-component>
11e1fe770c95beb36de0701d686eb50e.gif

Omi

Omi 是腾讯开源的前端跨框架跨平台的框架。是下一代 Web 框架,Omi 的目标是去万物糟粕,合精华为一。Omi 是一个跨框架的框架,任何框架都可以使用 Omi 自定义原始,当然 Web Components 也可以。它具有以下特性:

  • 小巧并且高性能

  • 基于 Shadow/Ligit Dom 设计

  • Web Components + JSX/TSX 融合为一个框架 Omi

  • Shadow/Light DOM 与 Virtual DOM 融合,Omi 既使用了虚拟 DOM,也是使用真实 Shadow DOM,让视图更新更准确更迅速

  • 局部 CSS 最佳解决方案(Shadow DOM),社区为局部 CSS 折腾了不少框架和库(使用 js 或 json 写样式,如:Radium,jsxstyle,react-style;与 webpack 绑定使用生成独特的 className 文件名—类名—hash值,如:CSS Modules,Vue),还有运行时注入scoped atrr 的方式,都是 hack 技术;Shadow DOM Style 是最完美的方案

  • 对 custom elements 友好, 通过字符串 '0'或者'false'传递 false,通过:和Omi.$传递任意复杂类型

  • 符合浏览器的发展趋势以及 API 设计理念

  • ...

我们可以通过一下命令快速开始开发项目。

  1. $ npm i omi-cli -g    # install cli
  2. $ omi init my-app     # 初始化项目,也可以在空目录里执行 'omi init'
  3. $ cd my-app           # 如果在空目录里执行 'omi init' 忽略这条命令
  4. $ npm start           # 开发
  5. $ npm run build       # 编译发布
  1. import { WeElement, render, h, tag } from 'omi'
  2. import './o-counter'
  3. import './index.css'
  4. import * as css from './index.less'
  5. import logo from './logo.svg'
  6. interface MyAppProps {
  7.   name: string
  8. }
  9. @tag('my-app')
  10. export default class extends WeElement<MyAppProps> {
  11.   static css = css.default
  12.   abc: string
  13.   onCountChanged = (evt: CustomEvent) => {
  14.     console.log(evt.detail)
  15.   }
  16.   render(props) {
  17.     return (
  18.       <div class="app">
  19.         <header class="app-header">
  20.           <img
  21.             src={logo}
  22.             class="app-logo"
  23.             alt="logo"
  24.           />
  25.           <h1 class="app-title">Welcome to {props.name}</h1>
  26.         </header>
  27.         {this.abc}
  28.         <o-counter onCountChanged={this.onCountChanged}></o-counter>
  29.       </div>
  30.     )
  31.   }
  32. }
  33. render(<my-app></my-app>, '#root', {
  34.   // if using OMI to build the whole application, ignore the attributs of DOM and use props of virtual dom
  35.   ignoreAttrs: true
  36. })

Omi 组件看起来也非常像 React 组件。相似度 95%,哈哈哈。如果你是一个 React 开发者一定感觉这语法非常的友好。

a4259ca612f9fdfd6ce1b0de2db21ee9.gif

Slim.js

Slim.js 是一个开源的轻量级 Web Components 库,它为组件提供数据绑定和扩展能力,使用 es6 原生类继承。专注于帮助开发者更好的编写原生web组件,而不依赖于其他框架,但是也提供了良好的拓展性,开发者可以自由拓展。

  • slim.js 核心很小(压缩后不到 3kB),从名字也能看出它很小

  • slim.js 带有可选的内置指令——可以选择适合的指令,从而保持包很小

  • slim.js 速度很快——它使用浏览器的 Background Task API 按需创建绑定并释放内存作为后台任务(在所有主要浏览器上)。

  • slim.js 是可扩展的。您可以使用简单的 API 将您自己的自定义指令添加到注册表中,或者添加在组件生命周期的每一步执行您的代码的全局插件。

  • slim.js 基于自定义元素技术,因此您的用户界面可以在任何地方使用,并且不会干扰任何其他库或框架。

  • slim.js 使您能够编写核心组件、用户界面的复杂部分和整个 web 应用程序——您选择您的尺寸,slim.js将提供。

  • ...

通过以下命令可以快速开始 slim.js:

  1. npm install slim-js
  2.  # 或者
  3. yarn add slim-js

或者从 CDN 使用:

  1. IIFE / Global: <script src="https://unpkg.com/slim-js"></script>
  2. Module: <script src="https://unpkg.com/slim-js?module"></script>
  1. import { Slim } from 'slim-js';
  2. const myHTML = `<h1>Welcome, {{this.username}}!</h1>`;
  3. class AwesomeComponent extends Slim {
  4.   constructor() {
  5.     super();
  6.     this.username = 'John Jimmy Junior';
  7.   }
  8. }
  9. Slim.element('my-awesome-component', myHTML, AwesomeComponent);

slim.js 基于浏览器的原生 DOM API 的网络组件规范。如果您希望支持旧版浏览器,您可能需要添加一个 polyfill。将以下标记添加到您的主 HTML 文件中:

<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.17/webcomponents-lite.js"></script>
343868cef789043a06e5437f8d99899d.gif

Polymer

Polymer 是 Google 推出的 Web Components 库,支持数据的单向和双向绑定,兼容性较好,跨浏览器性能也较好;提供了一组用于创建 custom elements 的功能。这些功能旨在使 custom elements 像标准 DOM 元素一样工作更容易和更快。与标准 DOM 元素类似,Polymer 元素可以是:

  • 使用构造函数或 document.createElement

  • 使用特性或特性配置

  • 在每个实例中填充内部 DOM

  • 响应属性和属性的变化

  • 使用内部默认值或外部样式

  • 响应操纵其内部状态的方法

  • ...

使用以下命令可以运行一个 Polymer 程序:

  1. npm install -g polymer-cli@next
  2. git clone https://github.com/PolymerLabs/polymer-3-first-element.git
  3. cd polymer-3-first-element
  4. npm install
  5. polymer serve --open

polymer 这语法和 Web Components 的原生语法真的非常的像。

  1. import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
  2. import '@polymer/iron-icon/iron-icon.js';
  3. class IconToggle extends PolymerElement {
  4.   static get template() {
  5.     return html`
  6.       <style>
  7.         :host {
  8.           display: inline-block;
  9.         }
  10.         iron-icon {
  11.           fill: var(--icon-toggle-color, rgba(0,0,0,0));
  12.           stroke: var(--icon-toggle-outline-color, currentcolor);
  13.         }
  14.         :host([pressed]) iron-icon {
  15.           fill: var(--icon-toggle-pressed-color, currentcolor);
  16.         }
  17.       </style>
  18.       <!-- shadow DOM goes here -->
  19.       <iron-icon icon="[[toggleIcon]]"></iron-icon>
  20.     `;
  21.   }
  22.   static get properties () {
  23.     return {
  24.       toggleIcon: {
  25.         type: String
  26.       },
  27.       pressed: {
  28.         type: Boolean,
  29.         notify: true,
  30.         reflectToAttribute: true,
  31.         value: false
  32.       }
  33.     };
  34.   }
  35.   constructor() {
  36.     super();
  37.     this.addEventListener('click', this.toggle.bind(this));
  38.   }
  39.   toggle() {
  40.     this.pressed = !this.pressed;
  41.   }
  42. }
  43. customElements.define('icon-toggle', IconToggle);
070d8d78ad6ea2b0f2bf182145686ff2.gif

hybrids

hybrids 是一个 JavaScript UI 框架,用于创建功能齐全的 Web 应用程序、组件库或具有独特的混合声明性和功能性架构的单个 Web Components。该框架的主要目标是为网络平台提供一套完整的工具——一切都没有外部依赖。它支持构建 UI 组件、管理复杂状态、使用客户端路由创建应用程序流以及针对全球市场本地化其内容。所有部分都遵循相同的独特概念,使其易于理解和使用!它具有:

  • 简单的结构,组件模型基于普通对象和纯函数,仍然在底层使用Web Components API

  • 无缝本地化,对组件内容自动翻译的内置支持使翻译无缝且易于集成

  • 该框架提供了一种方法来添加具有复数形式的动态消息、HTML 内容,或在模板上下文之外使用消息

  • 复杂状态管理,store 模块提供基于声明式模型定义的全局状态管理,内置对异步外部存储、关系、离线缓存等的支持

  • 结构化客户端路由,路由器模块为客户端应用程序提供了一个全局导航系统。它不是仅仅将 URL 与相应的组件匹配,而是依赖于树状结构的视图,这些视图在组件定义中有自己的路由配置。它使 URL 成为可选的,对对话框、受保护的视图等具有开箱即用的支持

  • ...

这里套用一个官网的例子,给大家演示一下:

  1. import { define, html } from "hybrids";
  2. export function increaseCount(host) {
  3.   host.count += 1;
  4. }
  5. export default define({
  6.   tag: "simple-counter",
  7.   count: 0,
  8.   render: ({ count }) => html`
  9.     <button onclick="${increaseCount}">
  10.       Count: ${count}
  11.     </button>
  12.   `
  13. });

这代码相对前面几个实例,非常的简单,代码结构也非常的清晰。

b7c8de44e2c20c0d8caaa12565a26895.gif

X-Tag

X-Tag 是微软推出的开源库,支持 Web Components 规范,兼容Web Components。X-Tag 最初由 Mozilla 开发,现在由 Microsoft 的开发人员提供支持,它是一个开源 JavaScript 库,它包装了 W3C 标准 Web Components API 系列,为组件开发提供了一个紧凑、功能丰富的接口。虽然 X-Tag 可以轻松利用所有 Web Components API(自定义元素、Shadow DOM、模板和 HTML 导入),但它只需要自定义元素 API 支持即可运行。在没有原生自定义元素 API 的情况下,X-Tag 使用 Google 的 Polymer 框架所依赖的相同的 polyfill 。它的特点也很明显:

  • 标准,基于 Web Components API 构建

  • 高效,3k min/gzip中的强大功能

  • 可插拔,可以和其他库一起使用

它有两种版本:

  • x-tag + polyfills

  • Just x-tag no polyfills

这里演示一个 x-tag + polyfills 版本,看看效果:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.   <title>Document</title>
  8. </head>
  9. <body>
  10.   <x-clock></x-clock>
  11. </body>
  12. <script src="../src/x-tag-polyfilled.min.js"></script>
  13. <script src="../src/index.js"></script>
  14. </html>
  1. //index.js
  2. xtag.create('x-clock', class extends XTagElement {
  3.   connectedCallback () {
  4.     this.start();
  5.   }
  6.   start (){
  7.     this.update();
  8.     this._interval = setInterval(() => this.update(), 1000);
  9.   }
  10.   stop (){
  11.     this._interval = clearInterval(this._data.interval);
  12.   }
  13.   update (){
  14.     this.textContent = new Date().toLocaleTimeString();
  15.   }
  16.   'tap::event' (){
  17.     if (this._interval) this.stop();
  18.     else this.start();
  19.   }
  20. });
dc255472ad6e5a67ded4d0d28b77c975.gif

LitElement

LitElement 是一个简单的基类,用于使用 lit-html 创建快速、轻量级的 Web Components。LitElement 现在是Lit 库 monorepo的一部分。Lit 2 包括 lit-html 2.x 和 LitElement 3.x。LitElement 使用lit-html渲染到元素的Shadow DOM 中,并添加 API 来帮助管理元素属性和特性。LitElement 对属性的变化做出反应。

LitElement 具有以下特点:

  • 简单、现代、安全、小巧且快速

  • 允许您使用带有嵌入式 JavaScript 表达式的模板文字在 JavaScript 中编写 HTML 模板

  • lit-html 识别模板的静态和动态部分,因此它可以有效地只更新更改的部分

  • lit-html 不依赖于任何组件模型,它只专注于创建和更新 DOM

  • ...

这里也演示一个简单的例子,运行下面的 HTML 代码:

  1. <!doctype html>
  2. <html>
  3. <head>
  4.   <!-- Polyfills only needed for Firefox and Edge. -->
  5.   <script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>
  6. </head>
  7. <body>
  8.   <!-- Works only on browsers that support Javascript modules like
  9.   Chrome, Safari, Firefox 60, Edge 17 -->
  10.   <script type="module">
  11.     import {LitElement, html, css} from 'https://unpkg.com/lit-element/lit-element.js?module';
  12.     
  13.     class MyElement extends LitElement {
  14.       static get properties() {
  15.         return {
  16.           mood: {type: String}
  17.         }
  18.       }
  19.       
  20.       static get styles() {
  21.         return css`.mood { color: green; }`;
  22.       }
  23.       render() {
  24.         return html`Web Components are <span class="mood">${this.mood}</span>!`;
  25.       }
  26.     }
  27.     customElements.define('my-element', MyElement);
  28.   </script>
  29.   
  30.   <my-element mood="great"></my-element>
  31.   
  32. </body>
  33. </html>
2d565b9ea29f6be33561e5bd99c8b732.gif

5d363b22f52041408c591f0e288e64db.png

direflow

direflow 是一个 React组件 + web component +web componen t属性变化重新挂载 React 组件的 web component框架。direflow的响应式其实分为2块:组件内部响应式(通过React自身响应式流程),组件外部响应式(WebComponents属性变化监听重渲染组件)。如果外部属性不会经常变化的话,性能这块没有问题,因为组件内部的响应式完全是走了React自身的响应式。属性外部属性如果会经常变化的话,direflow框架在这块还有一定的优化空间。

direflow 具有以下特点:

  • 使用 React 的强大功能来创建您的组件构建它

  • Direflow 使开始开发变得非常容易!在几分钟内创建您的第一个 Direflow 组件

  • 创建丰富且完全独立的微前端

  • 构建整个 UI 库并在任何 UI 框架和库中使用它

  • ...

运行下面的命令自己尝试一下:

  1. npm i -g direflow-cli
  2. direflow create
  3. cd <project-folder>
  4.   
  5. npm install
  6. npm start

这完全就是在写 React。

  1. import React, { useContext } from 'react';
  2.   import PropTypes from 'prop-types';
  3.   import { EventContext, Styled } from 'direflow-component';
  4.   import styles from './App.css';
  5.   const App = (props) => {
  6.     const dispatch = useContext(EventContext);
  7.     const handleClick = () => {
  8.       const event = new Event('my-event');
  9.       dispatch(event);
  10.     };
  11.     const renderSampleList = props.sampleList.map((sample) => (
  12.       <div key={sample} className='sample-text'>
  13.         → {sample}
  14.       </div>
  15.     ));
  16.     return (
  17.       <Styled styles={styles}>
  18.         <div className='app'>
  19.           <div className='top'>
  20.             <div className='header-image' />
  21.           </div>
  22.           <div className='bottom'>
  23.             <div className='header-title'>{props.componentTitle}</div>
  24.             <div>{renderSampleList}</div>
  25.             <button className='button' onClick={handleClick}>
  26.               Click me!
  27.             </button>
  28.           </div>
  29.         </div>
  30.       </Styled>
  31.     );
  32.   };
  33.   App.defaultProps = {
  34.     componentTitle: 'Test Direflow',
  35.     sampleList: [
  36.       'Create with React',
  37.       'Build as Web Component',
  38.       'Use it anywhere!',
  39.     ],
  40.   }
  41.   App.propTypes = {
  42.     componentTitle: PropTypes.string,
  43.     sampleList: PropTypes.array,
  44.   };
  45.   export default App;
c1952d38e8088eb86fc70104732a20b0.gif

总结

尽管 Web Components 可能还没有全面的进入研发者的视野,现在还备受争议,但是它已经被很多大厂已经直接或者间接将它用于实践,并且在市场上也出现了很多 Web Components 库,可以轻松的使用和构建 Web Components,本文也列举了八个 Web Components 的前端框架:

  • Stencil:是一个用于构建可重用、可扩展的设计系统的工具链。生成可在每个浏览器中运行的小型、极快且 100% 基于标准的 Web Components。

  • Omi:是 Web Components + JSX/TSX 融合为一个框架,小巧的尺寸和高性能,融合和 React 和 Web Components 各自的优势。

  • Slim.js:是一个开源的轻量级 Web Components 库,它为组件提供数据绑定和扩展能力,使用 es6 原生类继承。专注于帮助开发者更好的编写原生web组件,而不依赖于其他框架,但是也提供了良好的拓展性,开发者可以自由拓展。

  • Polymer :是 Google 推出的 Web Components 库,支持数据的单向和双向绑定,兼容性较好,跨浏览器性能也较好;提供了一组用于创建 custom elements 的功能。这些功能旨在使 custom elements 像标准 DOM 元素一样工作更容易和更快。

  • hybrids:是一个 JavaScript UI 框架,用于创建功能齐全的 Web 应用程序、组件库或具有独特的混合声明性和功能性架构的单个 Web Components。

  • X-Tag:是微软推出的开源库,支持 Web Components 规范,兼容Web Components API。

  • LitElement:是一个简单的基类,用于使用 lit-html 创建快速、轻量级的 Web Components。

  • direflow:是一个 React组件 + web component +web componen t属性变化重新挂载 React 组件的 web component框架。

这些框架都有自己的特性,也各具自己的优缺点,在实战了中具体需要用哪一个 Web Components 前端框架完全取决于你自己。好啦,本文的内容到此结束了。

最后,我希望从这个 Web Components 系列教程中你可以学到了很多东西.

❤️ 谢谢支持

以上便是本次分享的全部内容,希望对你有所帮助^_^

喜欢的话别忘了 分享、点赞、收藏 三连哦~。

17de41e630e062f3a159b8bd0e30b73b.gif

从零搭建全栈可视化大屏制作平台V6.Dooring

从零设计可视化大屏搭建引擎

Dooring可视化搭建平台数据源设计剖析

可视化搭建的一些思考和实践

基于Koa + React + TS从零开发全栈文档编辑器(进阶实战

点个在看你最好看

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/93183
推荐阅读
相关标签
  

闽ICP备14008679号