大家好,很高興又見面了,我是"進階前端進階",由我帶着大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發,您的支援是我不斷創作的動力。
今天給大家帶來的主題是Lit ,即一個簡單的庫,用于建構快速、輕量級的 Web Component。話不多說,直接進入正題!
1.什麼是 Lit
Lit 是一個簡單的庫,用于建構快速、輕量級的 Web Component。 Lit 的核心是一個消除樣闆的元件基類,它提供反應式狀态、作用域樣式和一個微小、快速且富有表現力的聲明性模闆系統。
Lit 具有以下優勢:
- 簡單/去樣闆化:Lit 建立在 Web Component 标準之上,添加了反應性、聲明性模闆和一些優秀功能,以減少樣闆檔案并使工作更輕松。 每個 Lit 功能都經過精心設計,并考慮到 Web 平台的發展。
- 快速地/體積小/即時更新:Lit 的體積約為 5 KB(minified and compressed),有助于保持較小的包體積并縮短加載時間。而且渲染速度非常快,因為 Lit 在更新時隻涉及 UI 的動态部分 ,無需重建虛拟樹并将其與 DOM 進行比較。
- 可互操作/面向未來:每個 Lit 元件都是原生 Web Component,具有超強的互操作性。 Web Component 可以在任何使用 HTML 的地方工作,可以使用任何架構,也可以不使用架構。 這使得 Lit 成為建構可共享元件、設計系統或可維護、面向未來的網站和應用程式的理想選擇。
除了以上特點外,Lit 的優勢還包括:
- 标準自定義元素:Lit 元件是标準的自定義元素,是以浏覽器将它們完全視為内置元素。 在手寫的 HTML 或架構代碼中使用它們,從 CMS 或靜态站點建構器輸出它們,甚至在 JavaScript 中建立執行個體
- 支援範圍樣式(Scoped styles):Lit 預設使用 Shadow DOM 來确定樣式的範圍,進而使得 CSS 選擇器保持簡單,并確定元件的樣式不會影響頁面上的任何其他樣式,也不受其影響。
- 支援反應性:支援聲明響應式屬性來對元件的 API 和内部狀态進行模組化。 每當反應性屬性(或相應的 HTML 屬性)發生變化時,Lit 元件就會有效地重新渲染。
- 聲明性模闆:Lit 模闆基于标記的模闆文字,簡單、富有表現力且快速,具有 HTML 标記和内聯的原生 JavaScript 表達式。 無需學習自定義文法,更重要的是無需編譯。
目前 Lit 在 Github 上通過 BSD-3-Clause 協定開源,有超過 15.1k 的 star、0.8k 的 fork、38.1k 的項目依賴量,代碼貢獻者 160+,npm 周平均下載下傳量 845k,是一個妥妥的前端優質開源項目,值得長期關注。
2.Lit 的使用場景
開發者可以使用 Lit 建構幾乎任何類型的 Web UI!
每個 Lit 元件都是标準的 Web 元件。 Web 元件具有互操作性的超強能力,本身受浏覽器的支援,可以在任何 HTML 環境中使用,可以使用任何架構,也可以不依賴架構。
這使得 Lit 成為開發可共享元件或設計系統的理想選擇。 Lit 元件可以跨多個應用程式和站點使用,即使這些應用程式和站點建構在各種前端堆棧上。 使用 Lit 元件的站點開發人員不需要編寫甚至不需要檢視任何 Lit 代碼,可以像使用内置 HTML 元素一樣使用這些元件。
Lit 還非常适合用于逐漸增強基本 HTML 網站。 浏覽器将識别标記中的 Lit 元件并自動初始化, 無論站點是手工制作的、通過 CMS 管理的、使用伺服器端架構建構的,還是由 Jekyll 或 Eleventy 等工具生成的。
當然,開發者也可以使用 Lit 元件建構高度互動、功能豐富的應用程式,就像使用 React 或 Vue 等架構一樣。 Lit 的功能和開發人員體驗與這些流行的替代方案相當,但 Lit 通過采用浏覽器的本機元件模型最大限度地減少鎖定、最大限度地提高靈活性并提高可維護性。
總結起來,Lit 非常适用于以下場景:
- 共享元件:支援可放入任何站點、建構在任何堆棧上的互動式内容。由于浏覽器本身就支援 Web Component,是以 Web Component 是完美的解決方案,而且 Lit 使它們易于建構。
- 設計系統:設計系統可幫助創造始終如一的卓越品牌體驗,而 Lit 能夠有效解決跨框前端架、跨團隊的諸多問題。
- 網站和應用程式:使用 Lit 元件逐漸增強靜态站點或建構整個應用程式。 通過采用 Web Component,Lit 最大限度減少了鎖定并提高了可維護性。
3.開始使用 Lit
3.1 安裝 Lit
首先需要使用 npm 安裝 Lit:
npm i lit
然後導入 JavaScript 或 TypeScript 檔案:
import { LitElement, html } from "lit";
import { customElement, property } from "lit/decorators.js";
當然,Lit 還可以作為預建構的單檔案包提供,進而提高開發工作流程的靈活性:例如,如果開發者更願意下載下傳單個檔案而不是使用 npm 和建構工具。
這些包是沒有依賴關系的标準 JavaScript 子產品 , 任何現代浏覽器都能夠從 <script type="module"> 中導入并運作這些代碼,如下所示:
import {
LitElement,
html,
} from "https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js";
3.2 使用 Lit 開發一個 Web Component
下面使用 Lit 開發了一個 Web Component:
import {LitElement, html, css} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {play, pause, replay} from './icons.js';
@customElement("my-timer")
// @customElement是類裝飾器工廠将裝飾類定義為自定義元素,即 my-timer
export class MyTimer extends LitElement {
static styles = css`/* playground-fold */
:host {
display: inline-block;
min-width: 4em;
text-align: center;
padding: 0.2em;
margin: 0.2em 0.1em;
}
footer {
user-select: none;
font-size: 0.6em;
}
@property() duration = 60;
@state() private end: number | null = null;
@state() private remaining = 0;
render() {
const {remaining, running} = this;
const min = Math.floor(remaining / 60000);
const sec = pad(min, Math.floor(remaining / 1000 % 60));
const hun = pad(true, Math.floor(remaining % 1000 / 10));
return html`
${min ? `${min}:${sec}` : `${sec}.${hun}`}
<footer>
${remaining === 0 ? '' : running ?
html`<span @click=${this.pause}>${pause}</span>` :
html`<span @click=${this.start}>${play}</span>`}
<span @click=${this.reset}>${replay}</span>
</footer>
`;
}
start() {
this.end = Date.now() + this.remaining;
this.tick();
}
pause() {
this.end = null;
}
reset() {
const running = this.running;
this.remaining = this.duration * 1000;
this.end = running ? Date.now() + this.remaining : null;
}
tick() {
if (this.running) {
this.remaining = Math.max(0, this.end! - Date.now());
requestAnimationFrame(() => this.tick());
}
}
get running() {
return this.end && this.remaining;
}
connectedCallback() {
super.connectedCallback();
this.reset();
}
}
上面代碼有幾點值得說明:
- Lit 的主要功能是 LitElement 基類,它是原生 HTMLElement 的便捷且多功能的擴充, 主要功能是:管理元素 properties 和 attribute 并渲染 lit-html 模闆的基本元素類。
- @property()是一個屬性裝飾器,它建立相應屬性值的反應性屬性。 當設定裝飾屬性時,元素将更新并渲染。 也可以選擇提供 PropertyDeclaration 來配置屬性功能。
- @state() 聲明一個私有或受保護的響應式屬性,代表元件的公共 API 和/或内部狀态,該屬性在更改時會觸發元素的更新,它不會從相應的屬性中反映出來。
- 預設情況下,樣式是有範圍(scope)的,使 CSS 選擇器保持簡單,并確定元件的樣式不會污染(或被污染)周圍的上下文。
- Lit 富有表現力的聲明性模闆(利用 JavaScript 标記模闆文字)可以輕松描述元件的渲染方式。
- Lit 在普通 JavaScript 表現良好,開發者可以通過使用裝飾器和類型聲明來使用 TypeScript 以獲得更好的人體工程學效果。
聲明了 my-timer 這個 Web Component 後,接着就可以在 HTML 中引入這個 my-timer 來直接使用:
<!doctype html>
<head>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@1,800&display=swap" rel="stylesheet">
<script type="module" src="./my-timer.js"></script>
<style>
body {
font-family: 'JetBrains Mono', monospace;
font-size: 36px;
}
</style>
</head>
<body>
<my-timer duration="7"></my-timer>
<my-timer duration="60"></my-timer>
<my-timer duration="300"></my-timer>
</body>
當然,Lit 還包括:指令(Directives)、Shadow DOM、生命周期(Lifecycle)、上下文(Context)、Lit 服務端渲染(Lit SSR)、前端架構內建等進階用法,這些可以在文末的參考資料中直接使用,本文不再過多展開。
4.本文總結
本文主要和大家介紹 Lit ,即一個簡單的庫,用于建構快速、輕量級的 Web Component。相信通過本文的閱讀,大家對 Lit 會有一個初步的了解。
因為篇幅有限,關于 Lit 的更多用法和特性文章并沒有過多展開,如果有興趣,可以在我的首頁繼續閱讀,同時文末的參考資料提供了大量優秀文檔以供學習。最後,歡迎大家點贊、評論、轉發、收藏,您的支援是我不斷創作的動力。
參考資料
https://github.com/lit/lit
https://lit.dev/tutorials/intro-to-lit/
https://lit.dev/docs/
https://www.npmjs.com/package/lit
https://lit.dev/docs/frameworks/react/
https://coderpad.io/blog/development/web-components-101-framework-comparison/
https://medium.com/front-end-weekly/web-components-lwc-stencil-and-lit-by-numbers-b158efcf82f7