尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Lit 实战指南:用 LitElement 构建快速、轻量的 Web Components

Lit 实战指南:用 LitElement 构建快速、轻量的 Web Components Lit 实战指南用 LitElement 构建快速、轻量的 Web Components【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/litLit 是一个用于构建快速、轻量 Web Components 的简单库其核心是一个消灭样板代码的组件基类集响应式状态Reactive State、作用域样式Scoped Styles与声明式模板系统于一体。本文以packages/lit包的官方 README 为骨架结合本仓库源码深入讲解 Lit 的四大核心能力声明式模板、响应式属性、可定制的更新生命周期、作用域 CSS帮助你从零开始掌握用 Lit 定义自定义元素并在任意 HTML 中使用它的完整实战路径。Lit 是什么按照 packages/lit/README.md 的定义Lit is a simple library for building fast, lightweight web components——一个用于构建快速、轻量 Web Components 的简单库。Lit 建立在标准 Web Components 之上Custom Elements Shadow DOM目标是让 Web Components 更容易编写。其核心是一个消除样板代码的组件基类LitElement它提供了快速的声明式 HTML 模板系统基于 lit-html响应式属性声明property等装饰器可定制的响应式更新生命周期requestUpdate/performUpdate/shouldUpdate/update/render易于使用的作用域 CSS 样式css标签 Shadow DOM从包结构看lit是一个聚合包它本身没有独立的运行时实现而是把 packages/lit-element组件基类与 packages/lit-html模板引擎重新导出并统一入口。这一点在 packages/lit/src/index.ts 中有明确注释虽然这些符号可以从lit-element.js重新导出但在此处显式import lit/reactive-element与import lit-html是为了在未打包unbundled加载时预先拉取依赖避免额外的网络瀑布开销。快速开始第一个 Lit 组件lit包发布在 npm 上仓库内 packages/lit/package.json 记录当前版本为 3.3.3安装方式为npm install lit安装后即可用 TypeScript或 JavaScript定义组件。README 给出了一个完整的示例这是 Lit 最经典的入门代码我们逐行拆解import {LitElement, html, css} from lit; import {customElement, property} from lit/decorators.js; // Registers the element customElement(my-element) export class MyElement extends LitElement { // Styles are applied to the shadow root and scoped to this element static styles css span { color: green; } ; // Creates a reactive property that triggers rendering property() mood great; // Render the components DOM by returning a Lit template render() { return htmlWeb Components are span${this.mood}/span!; } }这段代码覆盖了 Lit 的全部核心概念customElement(my-element)类装饰器注册自定义元素等价于调用customElements.define(my-element, MyElement)。extends LitElement继承组件基类。LitElement在 packages/lit-element/src/lit-element.ts 中定义它继承自ReactiveElement并在其之上加入 lit-html 模板渲染能力源码注释明确LitElement extends ReactiveElement and adds lit-html templating。static stylescss作用域样式会被应用到组件的 shadow root 中。property()mood great声明一个响应式属性属性变化会自动触发重渲染。render()返回 lit-html 模板驱动 DOM 渲染。定义完成后就可以像使用普通 HTML 标签一样使用它my-element moodawesome/my-element注意这里my-element的mood属性会与组件类中的mood响应式属性双向关联——这正是下一节要讲的响应式属性机制。响应式属性从属性到渲染的自动化property()装饰器是 Lit 响应式系统的入口。在源码 packages/reactive-element/src/decorators/property.ts 中可以找到它的默认声明const defaultPropertyDeclaration: PropertyDeclaration { attribute: true, // 默认与同名 HTML 属性双向关联 type: String, // 默认按 String 转换属性值 converter: defaultConverter, // 默认转换器 reflect: false, // 默认不把属性值反映回 HTML 属性 hasChanged: notEqual, // 默认用 ! 判断是否发生变化 };这解释了 README 示例中的行为property() mood great未传任何选项因此mood默认与mood属性关联、按字符串转换、属性被赋值时触发更新。property()的底层实现standardProperty/legacyProperty最终会调用ReactiveElement.createProperty()并包装属性的 setter当外部给element.mood awesome赋值时会记录旧值并调用this.requestUpdate(name, oldValue, options)请求一次更新。源码注释property.ts明确写道装饰器包装 class accessor 或 setter使其在被赋值时以属性名和旧值调用requestUpdate()。除property外packages/lit/src/decorators.ts 还从lit/reactive-element重新导出了一整套装饰器全部可通过lit/decorators.js入口按需引入装饰器作用customElement注册自定义元素property声明响应式公有属性与属性/attribute 关联state声明响应式内部状态不关联 attribute用于私有/受保护字段eventOptions配置事件监听选项如passive、capturequery/queryAll查询 shadow DOM 中匹配选择器的元素/元素列表queryAsync异步查询返回 PromisequeryAssignedElements/queryAssignedNodes查询插槽slot分配的元素/节点由于lit/decorators.js支持按需导入见 package.json 的 exports 映射tree-shaking 友好你只需引入用到的装饰器。可定制的响应式更新生命周期Lit 的核心机制之一是属性变化 → 调度更新 → 渲染 DOM的响应式更新生命周期。README 将其概括为a customizable reactive update lifecycle。这一生命周期的完整链路在 packages/reactive-element/src/reactive-element.ts 中实现requestUpdate(propertyName, oldValue)reactive-element.ts标记有属性发生变化将元素加入更新队列。更新是异步批量合并的——同一次微任务内的多次赋值只会触发一次渲染这是其高性能的关键。performUpdate()reactive-element.ts真正执行一次更新内部会先收集changedProperties。shouldUpdate(changedProperties)reactive-element.ts钩子方法默认返回true可重写以决定本次更新是否执行例如返回false可跳过不必要的渲染。update(changedProperties)由LitElement覆写lit-element.ts其关键逻辑是先调用this.render()拿到模板再执行super.update()最后调用 lit-html 的render()把模板渲染进 render rootprotected override update(changedProperties: PropertyValues) { // Setting properties in render should not trigger an update const value this.render(); if (!this.hasUpdated) { this.renderOptions.isConnected this.isConnected; } super.update(changedProperties); this.__childPart render(value, this.renderRoot, this.renderOptions); }render()lit-element.ts开发者覆写的模板方法默认返回noChange。此外LitElement还覆写了connectedCallback/disconnectedCallbacklit-element.ts在元素连接/断开文档时同步渲染子部件的连接状态确保异步指令Async Directives在元素移出文档时正确清理。这是 Lit 与原生 Custom Elements 生命周期无缝衔接的体现。开发者可以通过重写shouldUpdate、update、firstUpdated、updated等钩子深度定制这一流程——这就是 README 所说可定制的含义。作用域 CSS 样式static styles css\... 是 Lit 提供样式隔离的方式。其原理是默认情况下LitElement使用Shadow DOM作为渲染根render root样式被注入 shadow root 内部天然与页面其他部分隔离只作用于当前组件。css标签来自lit/reactive-element的 packages/reactive-element/src/css-tag.ts返回CSSResult对象它内部缓存了CSSStyleSheet。在支持adoptedStyleSheets的浏览器中样式以可构造样式表constructible style sheets的方式共享复用源码中supportsAdoptingStyleSheetscss-tag.ts专门检测该能力。CSSResult还支持传入原生CSSStyleSheet或嵌套数组CSSResultGroup灵活组合样式来源。需要注意的是css标签的模板中不能插入动态值这是出于安全与静态分析的考虑如需动态样式可以使用styleMap指令见下文或 CSS 自定义属性。模板系统与指令DirectivesREADME 强调的第一项能力是A fast declarative HTML template system。模板标签html、svg由 packages/lit/src/html.ts 从lit-html整体重新导出。lit-html 的核心原理是把模板编译为可复用的 HTMLtemplate渲染时只对发生变化的部分做精准的 DOM 更新增量更新而非整树重建——这也是它快速的来源。围绕模板系统lit包还提供了一批开箱即用的指令directives位于 packages/lit/src/directives共 21 个均支持按需导入列表与条件渲染repeat带 key 的高性能列表、map、range、choose、when、join、guard、cache、keyed样式与类名classMap、styleMapDOM 查询与引用ref异步渲染asyncAppend、asyncReplace、until不安全内容谨慎使用unsafeHTML、unsafeSVG、unsafeMathML其他ifDefined、live、templateContent例如import {repeat} from lit/directives/repeat.js; import {classMap} from lit/directives/class-map.js;指令可以用class MyDirective extends AsyncDirective的方式自定义异步指令基类通过 packages/lit/src/async-directive.ts 从lit-html/async-directive.js重新导出。此外packages/lit/src/static-html.ts 重新导出了lit-html/static.js的静态模板 APIhtml的静态变体用于在模板编译期就确定静态结构、换取更高性能的场景配合literal、unsafeStatic、withStatic使用可通过lit/static-html.js导入。包结构与构建产物从 packages/lit/package.json 可以看出lit包的设计取向依赖关系lit/reactive-element^2.1.0、lit-element^4.2.0、lit-html^3.3.0三者在语义上分别承担响应式基座、组件基类、模板引擎的职责。exports 映射主入口lit之外还提供lit/decorators.js、lit/directives/*.js、lit/async-directive.js、lit/directive.js、lit/directive-helpers.js、lit/html.js、lit/static-html.js、lit/polyfill-support.js等子路径方便构建工具做 tree-shaking同时保留了development/目录下的开发版含类型与调试信息。构建产物通过 rollup 产出lit-core.min.js与lit-all.min.js见 package.json。其中全量包对应源码 packages/lit/src/index.all.ts它一次性导出全部指令与静态 HTML API并会输出一条提示除非确有需要建议直接使用litnpm 包而非全量 bundle以减小传输体积与解析成本。polyfill 支持lit/polyfill-support.js用于在需要兼容旧浏览器的场景下注入垫片支持。在项目中查看、运行与测试lit包的源码全部位于本仓库阅读入口建议组件基类实现packages/lit-element/src/lit-element.ts响应式核心packages/reactive-element/src/reactive-element.ts 与 packages/reactive-element/src/css-tag.ts模板引擎packages/lit-html/src/lit-html.ts装饰器实现packages/reactive-element/src/decorators聚合包入口packages/lit/src/index.ts 与 packages/lit/src/index.all.ts在本仓库中运行lit包的构建与测试位于 packages/lit/package.json 的wireit配置# 在仓库根目录安装依赖后 npm run build -w packages/lit # 构建含 ts 编译 rollup 打包 类型镜像 npm test -w packages/lit # 运行 dev/prod 浏览器测试与 node 测试测试覆盖了开发模式dev与生产模式prod两套代码路径见test:dev/test:prod脚本并包含test:node/test:node-dev的 Node 侧导入验证。小结回到 README 的核心主张Lit 提供恰到好处的工具来构建快速的 Web Components——声明式模板负责高效的 DOM 更新property等装饰器把属性变化自动映射为渲染shouldUpdate等钩子让更新生命周期完全可控Shadow DOM css标签让样式天然隔离。而这一切都建立在标准 Web Components 之上因此写出的组件可以无缝嵌入任何使用 HTML 的框架或页面。对贡献者而言仓库根目录的 CONTRIBUTING.md 提供了参与开发的完整指引。【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/lit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表