Lit介绍
Lit is a simple library for building fast, lightweight web components.
- Lit出自Google,是一个速度快且轻量的库,用来开发Web components非常方便。
- Lit前身是Polymer,那个时候Web Component标准还未正式发布,记得当时还需要polyfill。
- 而今天Web Component标准已经正式发布,可能将来的组件都全部会统一成Web Components。
更多关于Lit的介绍可以访问官网
封装一个Button
import { LitElement, html, css } from 'lit';
export class LuiButton extends LitElement {
// 相当于props
static properties = {
label: {
type: String
}
};
static styles = css`
.lui-button {
color: green;
}
`;
render() {
//相当于template
return html`
<button class="lui-button">
<slot>${this.label}</slot>
</button>
`;
}
}
//定义一个custom element这样就可以在html里面直接使用这个组件了
customElements.define('lui-button', LuiButton);
使用直接插入html即可,非常方便,和使用原生html组件一样的
<body>
<lui-button>Button Name</lui-button>
<!-- 因为定义了一个label的属性,也可以这样用 -->
<lui-button label="Button Name"></lui-button>
</body>
支持响应式
在properties里面默认就支持响应式,详情可以阅读:
同时Lit还可以通过Reactive Controllers的方式来支持Composition API
假设需要一个全局的Router的Controller,也就是把所有的路由都交由它管理,支持自动相应
//router-controller.js
export const Util = {
getHash(key) {
let hash = {};
const h = location.hash.substr(1);
if (h) {
const usp = new URLSearchParams(h);
hash = Object.fromEntries(usp);
}
if (key) {
return hash[key];
}
return hash;
},
setHash(key, value) {
if (!key) {
return;
}
const hash = Util.getHash();
if (hash[key] === value) {
return;
}
hash[key] = value;
const usp = new URLSearchParams(hash);
location.hash = usp.toString();
},
delHash(key) {
if (!key) {
return;
}
const hash = Util.getHash();
delete hash[key];
const usp = new URLSearchParams(hash);
location.hash = usp.toString();
}
};
class RouterController {
constructor() {
this.host = [];
this.hash = Util.getHash();
window.addEventListener('popstate', (e) => {
this.hash = Util.getHash();
this.updateHost();
});
}
set(key, value) {
this.hash[key] = value;
Util.setHash(key, value);
}
get(key) {
return Util.getHash(key);
}
del(key) {
Util.delHash(key);
}
addHost(host) {
if (!host) {
return;
}
if (typeof host.requestUpdate !== 'function') {
return;
}
this.host.push(host);
}
removeHost(host) {
if (!host) {
return;
}
this.host = this.host.filter(item => {
if (item === host) {
return false;
}
return true;
});
}
//当路由更新时,刷新对应的组件
updateHost() {
this.host.forEach(item => {
item.requestUpdate();
});
}
}
export default new RouterController();
将Controller注册到组件里面
import routerController from './controllers/router-controller.js';
export default class extends LitElement {
connectedCallback() {
super.connectedCallback();
//注册
routerController.addHost(this);
}
disconnectedCallback() {
super.disconnectedCallback();
//解除注册
routerController.removeHost(this);
}
render() {
//使用Controller,读取url的hash值渲染
//如果其他地方通过routerController.set(k, v)修改值且变动时,也会被requestUpdate触发渲染更新
const tab = routerController.get('tab');
return html`<div>${tab}</div>`;
}
}
封装一套组件库 Lithops UI - 生石花UI
- github:cenfun/lithops-ui: Lightweight UI web components based on lit (github.com)
- 在线预览:cenfun.github.io/lithops-ui/
几点体会
- 确实非常小,运行时0依赖
- 原生的方式使用方便
- 速度非常快,网上有benchmark对比,速度超过Vue3
- 但功能和生态确实比不过Vue这些成熟框架,很多东西需要二开