基于 Lit 官方 JavaScript 模板构建 `<my-element>` Web 组件:从零开始的实战指南
2026/9/13 12:49:46 网站建设 项目流程

基于 Lit 官方 JavaScript 模板构建<my-element>Web 组件:从零开始的实战指南

【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/lit

<my-element>是 Lit 官方lit-starter-js模板内置的示例组件,它用最简的代码演示了 Lit 构建 Web Components 的完整链路:模板渲染、属性(attribute/property)配置、事件派发、插槽(slot)与 CSS Shadow Part。本文以该组件为骨架,结合packages/lit-starter-js仓库内的源码、配置与示例页,逐步拆解如何在纯 JavaScript 项目中用 Lit 定义自定义元素,并把它跑起来、测起来、发布成文档站。

组件是什么:一个"即插即用"的 HTML 元素

<my-element>的全部实现位于 packages/lit-starter-js/my-element.js,约 70 行代码。它导出一个继承自LitElement的类,并在文件末尾通过window.customElements.define('my-element', MyElement)注册为浏览器原生自定义元素。

组件对外暴露的能力非常清晰,从类上方的 JSDoc 注释(my-element.js)即可一览:

  • 事件(@fires)count-changed,点击按钮时派发;
  • 插槽(@slot):默认插槽,承载外部传入的子内容;
  • CSS Shadow Part(@csspart)button,允许外部通过::part(button)定制按钮样式。

组件内部维护两个响应式属性(properties 声明):

属性类型默认值作用
nameString'World'生成问候语的收件人名字
countNumber0按钮被点击的次数

render()方法(my-element.js)用 Lit 的html模板标签声明视图:一个由sayHello(this.name)生成的标题、一个带@click事件绑定与part="button"的按钮,以及一个<slot></slot>用于投影子内容。点击按钮时_onClick使count自增并派发count-changed自定义事件(my-element.js)——这正是 Lit 响应式系统的典型用法:改属性,视图自动更新

组件还通过静态styles定义了宿主样式(:host { display: block; border: 1px solid gray; ... }),展示 Lit 内置的css标签写法(my-element.js)。

场景一:像写 HTML 一样直接使用

<my-element>是标准 HTML 元素,凡是可以写 HTML 的地方都能直接用。文档站首页(docs-src/index.md)给出的最小用法只有一行:

<my-element></my-element>

在浏览器中加载时,只需要保证my-element.js作为 ES Module 被执行过即可。仓库的 dev/index.html 展示了完整的最小页面结构:先加载@webcomponents/webcomponentsjs的 loader 做旧浏览器降级,再引入lit/polyfill-support.js(Lit 的 polyfill 支持,主要用于 shadow DOM 相关的浏览器兼容),最后以type="module"引入组件源码:

<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script> <script src="../node_modules/lit/polyfill-support.js"></script> <script type="module" src="../my-element.js"></script>

页面 body 里直接嵌套使用:

<my-element> <p>This is child content</p> </my-element>

这段子内容会进入组件的默认插槽被渲染出来,同时演示了"组件可以包裹内容"这一 Web Components 基本能力。文档站的 Basic 示例(docs-src/examples/index.md)也复用了同样的写法,并额外展示了从外部用 CSS 影响插槽内容的方式。

场景二:用 attribute 配置组件

Web 组件与普通 HTML 元素的亲和力,还体现在可以用 attribute 直接传参。文档首页给出的配置方式:

<my-element name="HTML"></my-element>

这里的nameattribute 会被 Lit 的属性反射机制映射到组件的nameproperty 上。在 my-element.js 中name: {type: String}的声明正是这种映射的契约:Lit 读取 HTML attribute 的字符串值,按type转换后赋给 property;反过来,当 property 变化时 Lit 也会将其序列化回 attribute(count同理,默认的 attribute 名即属性名小写)。所以运行时组件会渲染出Hello, HTML!这样的标题。

另一个 Name Property 示例(docs-src/examples/name-property.md)给出等价用法:

<my-element name="Earth"></my-element>

值得注意的是,模板中的nameattribute 是静态写法;若想在动态场景中传值,就要用到下面介绍的声明式渲染,通过.name的 property 绑定语法(点号前缀)传入任意 JavaScript 值。

场景三:在声明式渲染框架中集成

<my-element>并不局限于手写 HTML,它可以无缝嵌入 Angular、React、Vue 以及 lit-html 等声明式渲染体系。文档首页给出的 lit-html 示例:

import {html, render} from 'lit-html'; const name = 'lit-html'; render( html` <h2>This is a &lt;my-element&gt;</h2> <my-element .name=${name}></my-element> `, document.body );

这段代码中有两个关键点:

  1. .name=${name}是 property 绑定:点号告诉 lit-html 直接设置 DOM property 而非 attribute,因此可以传入非字符串值。由于name是响应式属性,后续更新name变量并重新render时,Lit 的差异算法会精准更新对应节点,无需手动操作 DOM。
  2. &lt;my-element&gt;是 HTML 实体转义:在模板字面量中写出&lt;&gt;,是为了让<h2>内以纯文本形式显示标签名字符串,属于演示性写法。

这一场景还体现了 Lit 生态的核心设计:任何 Lit 组件(包括模板、指令、装饰器)都遵循同一套响应式与更新机制,因此可以被其它框架的渲染循环"驱动",这是 Web Components 跨框架复用的天然优势。

在本地把项目跑起来

packages/lit-starter-js是一个独立的 npm 包(package.json),dependencies中直接依赖lit(当前仓库对应版本为^3.2.0)。按以下步骤可完成从安装到预览:

npm i # 安装依赖 npm run serve # 启动 Web Dev Server 并打开浏览器预览

serve实际执行的是wds --watch(@web/dev-server),它负责两件事:解析浏览器不支持的 Node 风格裸模块导入(bare import,如import {LitElement} from 'lit'),以及自动转译与按需注入 polyfill。开发预览地址为http://localhost:8000/dev/index.html

package.json中还提供了开发/生产两种模式的切换:

npm run serve # 开发模式:Lit 输出更详细的报错信息 npm run serve:prod # 生产模式:MODE=prod 环境变量驱动,输出更精简

测试、Lint 与格式化:质量闭环

模板内置了基于 @web/test-runner 的完整测试链路,全部脚本见 package.json:

npm test # 依次跑 test:dev 与 test:prod(双模式回归) npm test:watch # 开发模式 + 文件变更自动重跑 npm run test:prod # 仅生产模式 npm run test:prod:watch # 生产模式 + watch

双模式测试的意义在于:开发模式下 Lit 提供更详尽的报错提示便于调试,而生产模式则验证打包后的真实行为,二者组合能最大化覆盖问题面。

代码质量方面,模板同时接入两套工具:

npm run lint # = eslint '**/*.js' + lit-analyzer my-element.js npm run format # Prettier 统一格式化

其中lit-analyzer专门对 lit-html 模板做类型检查与 lint,使用的规则引擎与 VS Code 的 lit-plugin 扩展完全一致。仓库推荐在 VS Code 中安装 lit-plugin,以获得模板语法高亮、悬停文档、跳转定义、快速修复等能力;.vscode目录也配置了扩展推荐。Lint 规则基于各工具推荐配置并针对 LitElement 做了适度放宽,可按需编辑.eslintrc.json调整。

生成文档站:eleventy + Custom Elements Manifest

lit-starter-js另一个特色是自带一个由Eleventy(11ty)静态站点生成器构建的文档站,源码在 docs-src 目录,构建产物输出到docs/。站点页面由三部分支撑:

  • 手工编写的 Markdown 页面:如首页 docs-src/index.md(即<my-element>的主页)、docs-src/install.md 安装页,以及 docs-src/examples/ 下的示例页(Basic、Name Property);
  • API 文档页:由 docs-src/api.11ty.cjs 从 Custom Elements Manifest(custom-elements.json)自动生成,将组件的 Attributes、Properties、Methods、Events、Slots、CSS Shadow Parts、CSS Custom Properties 渲染成结构化表格,真正实现"文档与源码同步";
  • 布局与导航模板:位于 docs-src/_includes,其中example.11ty.cjs扩展自page.11ty.cjs,为示例页额外渲染可切换的示例导航列表。

构建与预览文档站的命令:

npm run docs # 完整构建:clean → analyze → build → assets → gen npm run docs:serve # 本地预览,默认 http://localhost:8000 npm run docs:gen:watch # watch 模式,改文件自动重建

构建链路的各环节对应 package.json 中的脚本:rimraf docs清理旧产物;cem analyze --litelement用 Custom Elements Manifest Analyzer 扫描**/*.js生成custom-elements.jsonrollup -c --file docs/my-element.bundled.js将组件打包压缩成单文件(供文档站演示用);eleventy --config=.eleventy.cjs生成静态站点。注意:这里的 Rollup 打包仅服务于文档站,并非组件发布流程。

站点按docs-src/_README.md的说明部署到 GitHub Pages:在仓库 Settings 中将 Pages 的 Source 设置为main branch /docs folder,把构建产物提交并推送即可生效。

发布组件时的正确姿势

模板 README 特别提醒:推荐以未压缩的 ES Module 形式发布组件,把构建期优化留给应用层(如摇树、去重等由打包器完成)。也就是说,lit-starter-js中 Rollup 配置的存在理由是生成文档站演示产物,而不是作为组件发布的默认方式;真正面向生产应用时,应按应用级打包工具(如 Rollup、webpack、Vite)的惯例去处理依赖与压缩。

小结:一条从示例到生产的学习路径

docs-src/index.md的三段式演示(直接使用 → attribute 配置 → lit-html 声明式渲染)出发,配合 my-element.js 的实现、package.json 的脚本体系和 dev/index.html 的页面样例,可以完整掌握 Lit 组件开发的五个核心环节:定义响应式组件、属性映射与事件派发、在任意框架中集成、双模式测试与 Lint、自动生成并部署文档站。这套模板既是初学者理解 Lit 的入口,也是可复用组件项目的起步骨架。

【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/lit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询