在前面的几篇中,已经把 Lit 的原理层拉出来溜了一圈:
- 它为什么不需要 Virtual DOM
- lit-html 如何通过 Part 精确更新 DOM
- 响应式系统为什么极度克制
- 生命周期为什么贴近浏览器模型
- 为什么几乎没有状态管理
现在不再停留在“理解”上,而是发出灵魂的拷问,问出真正有工程价值的问题:
为什么 Lit 特别适合用来构建「跨框架组件库」?
以及,应该怎么做?
一、为什么“跨框架组件库”是一个真实需求
在真实业务中,经常会遇到以下情况:
- 公司内部同时存在Vue / React / 原生项目
- Design System 希望统一 UI 规范
- 组件需要被第三方系统接入
- 微前端架构下,不同子应用技术栈不同
如果用 Vue / React 写组件库,通常意味着:
组件和框架强绑定
这正是 Lit 的优势所在。
二、为什么 Lit 天然适合这件事
2.1 Lit 的组件是「标准 Web Components」
Lit 组件本质是:
/* by 01130.hk - online tools website : 01130.hk/zh/random.html */ <my-button></my-button>而不是:
/* by 01130.hk - online tools website : 01130.hk/zh/random.html */ <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,就会发现:
前端并不一定要“越来越重”,
也可以选择“回到浏览器本身”。