React、Vue与Web Components

微软21年发布了基于Web Components的UI框架Fast
官网
Github

Web Components与React、Vue等主流前端框架相比有什么优势或劣势?
这个问题搜索一下会有很多模棱两可的答案,都是两者各有优劣,基本等于什么都没说。 本人也只能大胆猜测,Web Components作为原生API,性能、兼容性、通用性都胜于三方框架。长远来看,必定会朝Web Components的方向发展。

21年写过一篇文章性能比对,已经比较过React的虚拟Dom和Web Components的Shadow Dom的性能,结果自然是Web Components更胜一筹。本文打算再从通用性角度看一下Web Components。

假设公司有多个前端项目,Vue、React等框架都有用到,那么怎么实现一个组件在不同项目中通用呢? 答案是:Web Components。
以下简单的代码示例演示了在React中实现、使用Web Components组件

新建React项目
create-react-app web-component-demo --template typescript

新建一个Web Components文件:MyComponent.ts, 加入代码如下:

export class HelloWorld extends HTMLElement {
  constructor() {
      super();
  }

  // connect component
  connectedCallback() {
      console.log('hello');
      this.textContent = 'Hello World!';
  }

}

window.customElements.define('hello-world', HelloWorld);

打开App.tsx,改为以下代码

import React, { useState, DOMAttributes }  from 'react';
import { HelloWorld } from './MyComponent';
//下面这行代码是必须的,否则不会被打包到bundle文件
import './MyComponent';


type CustomElement<T> = Partial<T & DOMAttributes<T> & { children: any }>;

declare global {
  namespace JSX {
    interface IntrinsicElements {
      ['hello-world']: CustomElement<HelloWorld>;
    }
  }
}

function App() {
  return (
    <div className="App">
      <hello-world></hello-world>
    </div>
  );
}

export default App;

上述代码中的global定义也可以放到单独的global.ts文件中。

最后:npm run start

这个小demo证明了React中可以使用Web Components组件, 后面我们再尝试在VUE项目中使用Web Components。 这样就能证明可以通过Web Components实现跨框架的组件共享,而不用为每个框架都实现一套组件。

安装Vue Cli

npm install vue@next -g
npm install @vue/cli -g

vue create [项目名称]
cd [项目名称]
vue add typescript

之后的步骤与React的sample差不多,新建MyWebComponents.ts

export class MyWebComponent extends HTMLElement {

    constructor() {
        super();
    }
  
    // connect component
    connectedCallback() {
        console.log('hello');
        this.textContent = 'Hello World!';
    }
  
  }
  
window.customElements.define('my-web-component', MyWebComponent);

修改App.vue

<template>
  <my-web-component />
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component';
import HelloWorld from './components/HelloWorld.vue';
import './components/MyWebComponent';

@Options({
  components: {
    HelloWorld,
  },
})
export default class App extends Vue {}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

最后npm run serve,可以看到和React相同的效果。 当然,这里用的是直接copy/paste代码的方式,实际项目中肯定是要把Web Components组件单独打包、安装。

posted @ 2022-05-04 21:47  老胡Andy  阅读(613)  评论(0编辑  收藏  举报