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组件单独打包、安装。