听汐AI说头像
手绘 UI 组件库跨框架进阶:Web Components 原生自定义元素封装封面图

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

手绘 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

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--