在前面的幾篇中,已經把 Lit 的原理層拉出來溜了一圈:
- 它為什麼不需要 Virtual DOM
- lit-html 如何通過 Part 精確更新 DOM
- 響應式系統為什麼極度剋制
- 生命週期為什麼貼近瀏覽器模型
- 為什麼幾乎沒有狀態管理
現在不再停留在“理解”上,而是發出靈魂的拷問,問出真正有工程價值的問題:
為什麼 Lit 特別適合用來構建「跨框架組件庫」?
以及,應該怎麼做?
一、為什麼“跨框架組件庫”是一個真實需求
在真實業務中,經常會遇到以下情況:
- 公司內部同時存在 Vue / React / 原生項目
- Design System 希望 統一 UI 規範
- 組件需要被第三方系統接入
- 微前端架構下,不同子應用技術棧不同
如果用 Vue / React 寫組件庫,通常意味着:
組件和框架強綁定
這正是 Lit 的優勢所在。
二、為什麼 Lit 天然適合這件事
2.1 Lit 的組件是「標準 Web Components」
Lit 組件本質是:
<my-button></my-button>
而不是:
<MyButton />
這意味着:
- Vue / React / Angular / 原生都能用
- 沒有運行時依賴衝突
- 不需要橋接層
2.2 對比三種方案
|
方案
|
可行性
|
代價
|
|
Vue 寫 Vue 組件庫
|
僅 Vue
|
框架綁定
|
|
React 寫 React 組件庫
|
僅 React
|
框架綁定
|
|
Lit 寫 Web Components
|
全部
|
學習成本
|
Lit 的代價是前期理解,
收益是長期複用能力。
三、組件庫整體架構設計
3.1 推薦的目錄結構
packages/
├── components/
│ ├── button/
│ │ ├── button.ts
│ │ ├── button.styles.ts
│ │ └── index.ts
│ ├── modal/
│ └── index.ts
├── theme/
├── tokens/
└── utils/
特點:
- 組件高度獨立
- 不依賴任何框架上下文
- 只依賴瀏覽器標準
3.2 組件基類設計
export class BaseElement extends LitElement {
static shadowRootOptions = {
mode: 'open',
delegatesFocus: true,
}
}
所有組件統一繼承,方便:
- 注入主題
- 統一行為約束
- 控制 Shadow DOM 行為
四、一個 Button 組件的完整實現思路
4.1 定義組件
@customElement('ui-button')
export class UIButton extends BaseElement {
@property({ type: String }) type = 'default'
@property({ type: Boolean }) disabled = false
render() {
return html`
<button ?disabled=${this.disabled}>
<slot></slot>
</button>
`
}
}
特點:
- API 極其穩定
- 屬性即接口
- 沒有框架侵入
4.2 樣式隔離策略
static styles = css`
button {
padding: 8px 16px;
}
`
- Shadow DOM 原生隔離
- 不污染宿主項目
- 不怕樣式衝突
五、在 Vue / React 中如何使用
5.1 在 Vue 3 中使用
<ui-button type="primary">
提交
</ui-button>
注意點:
- Vue 對 Web Components 是一等公民
- 只需在
compilerOptions.isCustomElement中聲明
5.2 在 React 中使用
<ui-button type="primary">
Submit
</ui-button>
注意:
- 事件使用
addEventListener - 或通過屬性回調
button.addEventListener('click', handler)
六、事件設計:跨框架的關鍵點
6.1 不要暴露框架事件
不推薦:
this.$emit('change')
推薦:
this.dispatchEvent(
new CustomEvent('change', {
detail: value,
bubbles: true,
composed: true
})
)
這是 Web Components 標準事件模型。
七、主題與樣式系統設計
7.1 使用 CSS Variables
:host {
--btn-bg: #1677ff;
}
好處:
- 框架無關
- 可運行時切換
- 可被外部覆蓋
7.2 Design Token 層
export const colors = {
primary: 'var(--color-primary)',
}
形成:
Token → CSS Variables → Component Styles
八、構建與發佈策略
8.1 構建目標
- 輸出 原生 ES Module
- 不打包 Lit 本身(peer dependency)
- 支持 tree-shaking
build: {
target: 'es2020',
lib: {
entry: 'index.ts',
formats: ['es']
}
}
8.2 使用方式
import '@your-scope/ui-components'
即可全局註冊組件。
九、Lit 在微前端中的優勢
在微前端場景下,Lit 的優勢會被放大:
- 不共享運行時
- 不依賴框架上下文
- 不怕版本衝突
- 天然沙箱友好
十、什麼時候不該用 Lit?
必須説清楚邊界:
不適合:
- 大型業務應用
- 複雜狀態流轉
- 強路由依賴
適合:
- 組件庫
- Design System
- 基礎 UI
- 跨團隊 / 跨系統複用
十一、A Very Important 結論
Lit 並不是“更好的 React / Vue”,
而是“更接近瀏覽器的組件模型”。
當你的目標是:
- 長期維護
- 跨技術棧
- 低運行時成本
Lit 往往是最優解。
最後
如果 you 理解了 Lit,就會發現:
前端並不一定要“越來越重”,
也可以選擇“回到瀏覽器本身”。