手绘 UI 组件库跨框架进阶:Web Components 原生自定义元素封装

在开源前端组件库「Tide UI」的发展过程中,虽然我们已经提供了 React、Vue 3 和 Svelte 的适配包,但在面向原生 HTML/JS 静态站点、WordPress 博客、Webflow、或老旧 jQuery 系统时,引入任何现代前端框架的运行时都显得过于沉重。
Web 平台原生标准的终极跨框架解决方案是——Web Components(自定义元素 Custom Elements + Shadow DOM):
- 0 框架依赖:直接在浏览器原生支持,无论在 React、Vue、Angular 还是纯 HTML 里,都能像使用原生
<button>一样使用<tide-card>。 - 100% 绝对样式隔离:借助 Shadow DOM,组件内部的手绘边框和胶带样式绝对不会受到外部全局 CSS 的任何干扰,也不会污染外部。
今天我把自用的纯 TypeScript + Lit(极轻量 Web Components 库,体积仅 5KB)封装手作组件的工程实战公开出来。
+--------------------------------------------------------------------+
| 基于 Web Components 的原生手作组件架构 |
+--------------------------------------------------------------------+
| [组件定义: packages/web-components/src/TideCard.ts (基于 Lit 3)] |
| └── @customElement('tide-card') class TideCard extends LitElement|
| |
| [Shadow DOM 强样式隔离边界 (Encapsulation)] |
| ├── 内部包含: 纯手绘边框 CSS + 和纸胶带装饰插槽 <slot name="tape">|
| └── 外部 CSS 永远无法破坏内部复杂的 border-radius 与滤镜 |
| |
| [跨框架原生直接调用 (0 依赖打包: 仅 5.2KB)] |
| ├── 原生 HTML: <tide-card theme="sage">便签内容</tide-card> |
| ├── Vue 模板: <tide-card :theme="activeTheme">...</tide-card> |
| └── React JSX: <tide-card theme="dark">...</tide-card> |
+--------------------------------------------------------------------+
1. 编写原生自定义元素 TideCard
import { LitElement, html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
@customElement("tide-card")
export class TideCard extends LitElement {
@property({ type: String }) theme = "sage";
@property({ type: Boolean }) tilt = true;
// 严格隔离在 Shadow DOM 内部的样式
static styles = css`
:host {
display: block;
position: relative;
}
.card-box {
background-color: #FAF7F0;
border: 2px solid #2D2B2A;
border-radius: 255px 15px 225px 15px / 15px 225px 15px 255px;
padding: 20px;
box-shadow: 3px 4px 0px #2D2B2A;
transition: transform 0.2s ease;
color: #2D2B2A;
font-family: inherit;
}
.card-box.theme-dark {
background-color: #1A2421;
color: #FAF7F0;
border-color: #384A44;
}
.card-box.tilt:hover {
transform: rotate(-1deg) translateY(-2px);
cursor: pointer;
}
`;
render() {
const isDark = this.theme === "dark";
const boxClass = `card-box ${isDark ? "theme-dark" : ""} ${this.tilt ? "tilt" : ""}`;
return html`
<div class="${boxClass}">
<slot name="tape"></slot>
<slot></slot>
</div>
`;
}
}
2. 在任意普通 HTML 页面中引入并使用
只需在 HTML <head> 中引入一行打包后的 JS 脚本:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<script type="module" src="https://unpkg.com/@tide-ui/elements/dist/index.js"></script>
</head>
<body style="background-color: #FAF7F0; padding: 40px;">
<!-- 原生标签直接使用 -->
<tide-card theme="sage" tilt>
<h3 style="margin-top: 0;">原汁原味的 Web 标准手绘卡片 🌿</h3>
<p>完全不需要 React 或 Vue,原生浏览器直接秒开!</p>
</tide-card>
</body>
</html>
拥抱 Web 原生标准的永恒生命力
框架可能会随流行趋势而更迭,但 Web 标准永远长青。
把核心组件库封装为原生 Web Components,让温润的手作美学能够在整个互联网的任意角落自由生长。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/weixin_63764436/article/details/166482414




