@gyyxds/zy-ui
v0.1.0
Published
Zy UI:Element Plus 二次封装的 Vue 3 组件库与设计规范站
Readme
Zy UI 组件库 · 智云UI
基于 Vue 3 + TypeScript + Vite 的 Element Plus 二次封装组件库,配套一套组件文档 + 设计规范站(智云UI)。
组件带 props / 事件 / 插槽,随包发布;文档站与展示板不发布,它们是这套组件的用法说明与设计依据。
| 属性 | 说明 |
| --- | --- |
| 包名 | @gyyxds/zy-ui |
| 技术栈 | Vue 3、TypeScript、Element Plus |
| 构建工具 | Vite 8(库模式)+ vue-tsc |
| 模块格式 | 仅 ESM("type": "module"),无 CJS 产物 |
| 组件数 | 31 |
| 设计主题 | 2 套材质(图纸 / 键帽)× 2 档光照(浅 / 深) |
仓库里有什么
| | 组件库(src/zy/) | 文档与设计站(src/views/、docs/theme/) |
| --- | --- | --- |
| 是什么 | 有 props / 事件 / 插槽的 Vue 组件 | 组件的用法文档 + 两套材质的设计方案 |
| 怎么用 | npm i @gyyxds/zy-ui 后 import | 浏览器打开站点;设计推导见 docs/theme/ |
| 是否发布 | 进 lib 构建(dist/zy-ui/) | 不进包,只作为站点与设计资料 |
2026-10 站点瘦身:动效页(
/animations)、收藏页(/favorites)与片段体系已下线,仓库回归「组件库 + 组件文档 + 设计规范」。 组件自带的effect微动效(按压缩放、色块扫入、实色键帽等)仍在组件库内,属于组件 API 的一部分。
站点产物与库产物分开放:
dist/site/ # 文档站(npm run build)
dist/zy-ui/ # 组件库(npm run build:lib,进包)功能特性
- 31 个组件,全部是 Element Plus 的二次封装或同构重绘,
type/size/v-model/ 事件写法与 Element 保持一致 - 多个组件带一组
effect微动效:按钮press/sweep/fill,输入框underline,选择器underline… - 两套材质主题 × 深浅两档,四组配色互不回退:图纸(
basic)与实色键帽(solid) - 设计令牌随包发布(
--zy-*),覆盖语义令牌即可换肤,无需改组件代码 - 首页是设计方案本身:两根正交的轴、四种组合、两套色板、原则与判据;点色卡即可切换整站主题
- TypeScript 类型声明随包发布;ESLint 0 警告门槛、Vitest 单测、消费方冒烟检查与视觉回归
组件列表(31 个)
分类与文档站一致(src/mocks/element-components.ts)。
基础(3)
| 组件 | 说明 |
| --- | --- |
| ZyButton | type / plain / round / dashed / circle / square 对齐 Element。effect:press(按压缩放,默认)/ sweep(左侧图标块 + 色块扫入)/ fill(实色键帽 + 悬停中心扩散,仅键帽主题,图纸主题下自动按 press 渲染);square 是固定宽高的方形图标键帽 |
| ZyIcon | 内置 SVG 图标,name 取 src/assets/icons/ 的文件名(如 btn-search);size / label / spin |
| ZyLoading | 纯 div + CSS,不基于 Element。type:dots 点环 / line 心电描线 / text 故障字 / bar 跳球柱形;color / speed / width / height / label |
表单(13)
| 组件 | 说明 |
| --- | --- |
| ZyInput | effect:focus(默认,描边转主色)/ underline(下划线扫过);另有 label 浮动标签、raised 键帽凸起形态 |
| ZyCodeInput | 验证码输入。length / status(idle / error / success)/ size / mask / caret / disabled;v-model + complete 事件 |
| ZySelect | effect:focus / underline;tree + data 树形单选 / 多选(multiple 默认显示复选框);其余 API 照 Element |
| ZyCascader | 基于 el-cascader;主题化触发框 / 多列面板,列内滑行高亮;其余 API 照 Element |
| ZyCheckbox / ZyCheckboxGroup | effect:'' / checkmark / tick;Group 用 v-model 收集选中值 |
| ZySwitch | 自研开关:默认常用基础款(参考 sour-snake-86,默认 72×30,size 48 / 72 / 120,仅改主题色),variant="holographic" 为全息变体(扫描线 / 粒子 / 三环);v-model + activeText / inactiveText / label / disabled |
| ZyRadio / ZyRadioGroup / ZyRadioButton | 选中态辉光圆点 + 过冲弹跳;effect:'' / underline |
| ZySlideVerify | 滑块拼图验证(内置插画底图《缺口光谱》)。gap / tolerance / image / darkImage / showRefresh 与各档文案;事件:成功 / 失败 / 刷新 |
| ZyDatePicker / ZyTimePicker | 触发框与弹层形态重绘,API 照 Element |
数据(7)
| 组件 | 说明 |
| --- | --- |
| ZyCard | shadow(always / hover / never)、hoverFill(悬停铺色,可传颜色) |
| ZyTag | effect:dark / light(默认)/ plain / fill(实色键帽,仅键帽主题;图纸主题下自动退回浅底;closable 时关闭图标跟标签字色) |
| ZyBadge | 等宽数字不跳宽;effect:'' / ping(扩散圈) |
| ZyProgress | 轨道 + 蓝→绿渐变填充 |
| ZyTable | 台账式表格,lines(all / row)控制网格线;数据与列走插槽 / Element 透传 |
| ZyTree | 引导线 + 折角接线 + 写实节点图标;folderIcon / folderOpenIcon / fileIcon |
| ZyPagination | 基于 el-pagination 二次封装,仅重绘样式:纸面按钮 / 中性键帽页码,跳页输入框 |
反馈(2)
| 组件 | 说明 |
| --- | --- |
| ZyAlert | 左侧 3px 语义强调条 / 语义键块,标题留语义色 |
| ZyDialog | v-model 开合;title / width / icon / appendToBody / closeOnClickModal(默认 false)/ destroyOnClose |
布局(6)
| 组件 | 说明 |
| --- | --- |
| ZyDivider | contentPosition:left / center / right |
| ZySpace | 纯布局件,direction 等间距控制 |
| ZyPanel | 通用容器:有 title 分标题栏 + 正文,无 title 通体白面 |
| ZyTabs | 异形标签页:斜切角选中片 + FLIP 滑行 + 面板微动效;items 驱动,#panel-<key> 接管内容,键盘可切换 |
| ZyMegaMenu | 数据驱动导航:items(有 panel = 下拉,无 panel + href = 普通链接)、brand;受控开合 v-model:open;#panel-<key> 接管面板内容;grid 面板按子项数 1 / 2 / 3 列自适应 |
| ZySideMenu | 菜单导航的左侧变体:品牌区 + 一级入口 + 可展开二级;v-model:active / v-model:open,surface 可选 auto / 品牌面 / 白色纸面,支持自定义背景 / 文字 / 选中底色 / 选中文字;行间滑行高亮;二级收起用 inert 隔离 |
设计系统:两套语言 × 两档光照
站点首页(/)展示的就是这套方案,数据源在 src/mocks/theme-design.ts;完整推导、逐组件增量与对比度体检在 docs/theme/README.md。
两根正交的轴
| 轴 | 根属性(设在 <html> 上) | 取值 | 默认 |
| --- | --- | --- | --- |
| 材质主题 | data-zy-theme | basic(图纸)/ solid(实色键帽) | solid |
| 光照 | data-zy-color-scheme + html.dark class | light / dark | light |
两轴自由组合:深浅色在当前选中的材质内切换,不会把 solid 折叠回 basic。
四种组合
| 组合 | 一句话 | 主要落点 |
| --- | --- | --- |
| A · 图纸 / 浅色 | 白纸 + 发丝线 + 6px 方角,一张纸压一张纸 | src/zy/styles/themes/basic.css |
| A · 图纸 / 深色 | 同一张纸,夜里开了一盏台灯:只换光,不加厚度 | basic.css §0.1 + tokens/dark.css |
| B · 键帽 / 浅色 | 白键摆在灰桌上:凸起靠底座,凹槽靠内阴影 | src/zy/styles/themes/solid.css |
| B · 键帽 / 深色 | 同一张桌关了顶灯:顶光收薄、落影加重,厚度一分不减 | solid.css §0.1 / §0.2 |
两套语言只换材质,不动寸法:同一组件在两套主题下的高度差为 0(键高走 box-shadow,不进盒模型)。
判据
- 正文 ≥ 4.5:1、控件边界 ≥ 2.4:1、分层 ≥ 1.1:1。
- 主题不得改变形状、尺寸、圆角与位移方向。
- 深色只换光照:不给 A 加厚度,也不去掉 B 的白弧与底座。
- 字色跟着面走:面亮配墨、面深配白;同一语义允许在两档里给不同答案。
node docs/theme/tools/contrast.mjs 会逐对验算这四张板的色板。
首页展示什么
| 区块 | 内容 | | --- | --- | | 抬头 | 两套语言的立场、两根轴、31 个组件 / 2 套材质 / 2 档光照 | | 四种组合 | 2 × 2 卡片,点任意一格把整站切到那套材质与光照 | | 两套色板 | A / B 各一段,浅色与深色并排印出令牌名、用途与实际值 | | 设计原则 | 两条语言各自的层级、只换材质、两档光照、字色跟面走 | | 判据 | 对比度与尺寸的硬门槛 | | 落地 | 令牌、材质层、展示板与对比度工具的位置 |
安装使用
npm i @gyyxds/zy-ui element-plusvue 与 element-plus 是 peerDependency,需由业务项目自己安装;组件内部直接使用 El*,不需要先全局注册 Element Plus。
// main.ts —— 顺序:Element 样式 → 本包组件样式 → 主题材质
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import '@gyyxds/zy-ui/style.css'
import '@gyyxds/zy-ui/theme/solid.css' // 浅色默认;要图纸语言改用 theme/basic.css
import App from './App.vue'
createApp(App).use(ElementPlus).mount('#app')导出路径(对应 package.json 的 exports):
| 路径 | 内容 |
| --- | --- |
| @gyyxds/zy-ui | 组件库入口(全局 install + 全部具名导出) |
| @gyyxds/zy-ui/style.css | 组件样式 + 设计令牌(dist/zy-ui/zy-ui.css) |
| @gyyxds/zy-ui/theme/basic.css | 主题 A「基础用法 / 图纸」材质层 |
| @gyyxds/zy-ui/theme/solid.css | 主题 B「实色键帽」材质层 |
两个主题 CSS 可同时引入,由根元素属性决定谁生效。
三种引入方式
// ① 全局注册
import ZyUi from '@gyyxds/zy-ui'
app.use(ZyUi) // 之后模板里直接写 <ZyButton /> <ZyInput /> …
// ② 按需引入(推荐,tree-shaking 生效,只打进用到的组件)
import { ZyButton, ZyInput } from '@gyyxds/zy-ui'
// ③ 单组件注册(组件自带 install,对齐 Element 的做法)
import { ZyButton } from '@gyyxds/zy-ui'
app.use(ZyButton)<script setup lang="ts">
import { ref } from 'vue'
import { ZyButton, ZyInput } from '@gyyxds/zy-ui'
const keyword = ref('')
</script>
<template>
<ZyInput v-model="keyword" placeholder="搜索组件…" clearable />
<ZyButton type="primary" effect="press">提交</ZyButton>
</template>使用约定
- 未显式声明的 Element props / 事件按 Vue 的 attribute 透传,落到内部
El*上。 - 具名插槽原样转发给内部 Element 组件(如
<ZyButton><template #icon>…</template></ZyButton>),默认插槽由各组件自己安排位置。 - 自定义组件(
ZySwitch/ZyCodeInput/ZyDialog/ZyCheckboxGroup/ZyRadioGroup)用defineModel,v-model直接可用;ZySlideVerify走事件。 - 图标属性传字符串时按本库内置图标名解析(
ZyIcon/ZyTree等);ZyButton的icon目前只在sweep下解析字符串,press/fill请按 Element 规则传组件或走#icon插槽。 - 不要依赖组件内部
.el-*子结构与内部类名:只有 props / 事件 / 插槽 /--zy-*令牌是稳定契约。
主题与令牌
<html data-zy-theme="solid" data-zy-color-scheme="light"></html>- 业务侧开深色:给
<html>加darkclass 即可(data-zy-color-scheme是语义标记)。 - 换肤覆盖语义令牌,不要动组件内部结构:
/* 业务侧换肤:覆盖语义令牌 */
:root {
--zy-brand: #0066a9;
--zy-radius: 6px;
--zy-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}
/* 深色选择器要与 dark.css 同权重,并让业务 CSS 晚于主题 CSS 加载 */
html.dark[data-zy-theme] {
--zy-brand: #5aa6e4;
}html.dark 的权重低于 dark.css 里的 html.dark[data-zy-theme='basic' | 'solid'],单独写会被盖住;html.dark[data-zy-theme] 与它同级,后加载即可覆盖。
深色实心件另消费 --zy-brand-key(键面),悬停 / 按下走 --zy-brand-deep / --zy-brand-active;换整套品牌色时一并覆盖,/theme 页有可复制片段。
令牌分层固定:primitives.css(原始值)→ semantic.css(语义值,业务应覆盖这一层)→ element.css(Element Plus 映射)→ dark.css(深色覆盖)。
常用语义令牌:--zy-brand / --zy-green / --zy-danger / --zy-warning / --zy-info、--zy-ink / --zy-muted / --zy-inverse、--zy-paper / --zy-surface / --zy-hairline、--zy-radius(6px)/ --zy-radius-sm(4px)/ --zy-radius-pill(999px)、--zy-shadow-card / --zy-shadow-float / --zy-focus-ring、--zy-duration-fast / --zy-duration-press、--zy-ease-out / --zy-ease-soft / --zy-ease-overshoot、--zy-font-sans。
键帽主题额外有 --zy-desk / --zy-slot-* / --zy-key-*,只在该主题下定义。组件级微调优先用组件暴露的局部变量,如按钮 sweep/fill 的 --zy-btn-sweep-clr / --zy-btn-fill-clr / --zy-btn-fill-hover-clr。
本地开发
1. 安装依赖
npm install
# 或 yarn install --ignore-engines(@changesets/cli 要求 yarn ≥ 4.5,本机 yarn 1.x 需跳过引擎检查)Node.js 需 ^20.19 或 >= 22.12(Vite 8 要求)。
2. 启动开发服务
npm run dev该命令会先跑 check:registry 校验组件注册表,再启动 Vite(默认端口 5173,host: true 便于局域网访问)。
3. 访问文档站
浏览器打开 http://localhost:5173。
| 路由 | 内容 |
| --- | --- |
| / | 首页:设计方案(两根轴、四种组合、两套色板、原则与判据) |
| /components/:id | 组件页:左树右文 + 舞台 + 可复制 SFC + API 属性表 |
| /theme | 主题实验室:材质 / 光照切换、真实组件验收、品牌色与圆角令牌覆盖 |
| /about | 关于:项目说明、使用授权、更新日志 |
首页背景是四张 1920 × 1200 PNG:basic / solid 两套材质 × 浅色 / 深色两档,分别铺满视口;首页不再使用页面渐变。图片由 scripts/gen_home_backgrounds.py 生成,设计与构图说明见 docs/theme/home-backgrounds.md。
顶栏可切深浅;顶栏菜单是一枚直接浮在顶栏上的胶囊(不铺轨道),复用 ZyRadioGroup 分段按钮组的 400ms 回弹节奏,切栏目时胶囊从上一格滑过去,不再重建。材质与光照在首页的四种组合或 /theme 切换。?theme=dark&zyTheme=basic 之类的查询参数可固定主题,方便截图与分享。
旧地址 /animations、/favorites 与未知路由都会回到首页。
4. 常用命令
| 命令 | 作用 |
| --- | --- |
| npm run dev | 文档站(前置跑 registry 校验) |
| npm run build | 构建站点 → dist/site/ |
| npm run build:lib | 构建可发布库 → dist/zy-ui/(只含 31 个组件) |
| npm run lint | ESLint 检查(0 警告门槛) |
| npm run test | Vitest 单元测试 |
| npm run check:registry | 组件注册表 ↔ 实现文件、站点组件数、令牌完整性 |
| npm run check:package | 校验包导出目标与 npm pack 文件清单 |
| npm run check:consumer | 用 npm pack 产物在空项目安装、类型检查并构建 |
| npm run check:theme-runtime | 主题运行时校验(需先启动站点) |
| npm run check:visual / :update | 视觉回归 / 审核通过后更新基线(需先启动站点) |
| npm run check:release-env | 发布前置体检:npmjs registry / 登录 / 版本 / changeset / CHANGELOG |
| npm run changeset | 记录一次待发布变更 |
| npm run version | 消费 changeset、抬版本并自动收口 CHANGELOG |
| npm run release | 体检 → 构建 → 用 publishConfig registry 发布 |
站点与库产物分开放(dist/site 与 dist/zy-ui),互不覆盖。
5. 业务项目直接引用本仓库(file: 依赖)
业务项目里写 "@gyyxds/zy-ui": "file:../motion-vault-components" 时,不会触发本仓库的构建(prepublishOnly 只在 npm publish 时跑),装的就是仓库里现成的 dist/zy-ui。所以改了组件后要手动重建一次:
# 本仓库:改了 src/zy 之后都要跑一遍(约 30 秒,跑完 lint / 测试再打更稳)
npm run build:lib
# 业务项目:file: 依赖是软链,重建后产物已经生效,下面这步一般不需要;
# 只有 package.json 的 exports / 版本号变了才重装
npm install几条注意:
file:依赖是软链,node_modules/@gyyxds/zy-ui指向本仓库根目录;本仓库删掉dist后业务项目会立刻报「找不到入口」,重建就好。- 业务项目的 dev server 会缓存
node_modules/.vite:重建后没变化就删掉它、重启 dev。 - 单页调试用
npm run dev(文档站)最快;file:链路是给「在自己的业务页面里验证」用的。 - 样式三件套别漏:Element 样式 →
@gyyxds/zy-ui/style.css→ 一份主题 CSS(theme/basic.css或theme/solid.css)。
6. 新增 / 更新内容
新组件
- 实现放
src/zy/<Name>/(含index.ts),并在src/zy/index.ts追加导出 - 文档条目写进
src/mocks/element-components.ts(描述、完整 SFC、API 属性表;成族组件共用一页时给count) - 同步
src/mocks/components.ts的COMPONENT_TOTAL与 README / AGENTS 的组件数 npm run check:registry会拦住「实现了没注册」「注册了不存在」与漏定义的--zy-*令牌
改设计 / 主题
- 色板与文案改
src/mocks/theme-design.ts(首页与四张展示板共用这一份) - 令牌改
src/zy/styles/tokens/,材质改src/zy/styles/themes/ - 同步
docs/theme/README.md的推导与数值,跑node docs/theme/tools/contrast.mjs - 视觉有变化时先人工确认,再
npm run check:visual:update
发布到 npm
包名 @gyyxds/zy-ui,发布地址固定 https://registry.npmjs.org/(publishConfig 已配 access: public + registry)。发布账号 gyy-xds(@gyyxds 组织),已开启 2FA。
标准发布流程
# 首次 / token 过期时登录一次
npm login --registry=https://registry.npmjs.org/
# 正常提交代码(工作区必须干净)
git add -A
git commit -m "feat: ..."
# 一条命令:消费 changeset → 抬版本 → 收口 CHANGELOG
# → 提交版本 → 体检 → build:lib → changeset publish
npm run releaserelease 会自动:
- 检查工作区干净。
- 有 changeset 时执行
changeset version,把## Unreleased收口成## <version> - <date>,并提交chore: release v<version>。 - 没有 changeset 时按当前版本继续,用于补发或上次发布失败重试。
- 跑
check:release-env(按publishConfig.registry检查 npmjs 登录 / 版本 / changeset / CHANGELOG)。 build:lib,再用同一个 registry 执行changeset publish并打 tag。
需要拆开检查时:
npm run check:release-env
npm run build:lib紧急补发
npm publish 只用于紧急补发,且必须换新版本:
npm version <patch> --no-git-tag-version
npm run build:lib
npm publish --access public --registry=https://registry.npmjs.org/要点:
prepublishOnly会在 publish 前自动重跑一遍build:lib。- 2FA 账号 publish 时需浏览器授权或验证器一次性验证码(EOTP)。
- 发布后用
npm view @gyyxds/zy-ui version --registry=https://registry.npmjs.org/确认上架。 - 要让业务项目验证发布产物,可先跑
npm run check:consumer(npm pack→ 空项目安装 → 类型检查 → 构建)。
目录结构
src/zy/ # 组件库源码(只有这部分会进发布产物)
├── button/ # 每个组件一个目录:index.ts 导出 + Zy*.vue 实现
├── input/ select/ …
├── styles/
│ ├── tokens/ # primitives → semantic → element → dark 四层令牌
│ └── themes/ # basic.css(图纸)/ solid.css(键帽)/ material.css
└── index.ts # 库入口:导出 + install
src/views/ # 文档站页面:首页(设计方案)/ 组件页 / 主题页 / 关于
src/components/ # 站点自身组件(布局、舞台、代码面板、UI 小件)
src/mocks/ # 站点数据:组件元信息、设计方案、关于页内容
src/stores/ # Pinia:主题(材质 + 光照)
src/assets/styles/ # 站点外壳令牌与动效(不影响组件库)
scripts/ # 校验与构建脚本(registry / package / consumer / theme-runtime / visual)
tests/ # Vitest 单测 + 视觉回归基线
docs/theme/ # 设计规范:两套语言、两档光照、四张展示板、对比度工具浏览器支持
现代浏览器。样式用到 color-mix()、:has()、嵌套与 CSS 自定义属性,旧 WebView / IE 需先评估降级方案,详见 浏览器支持。
Credits 致敬
本项目站在以下优秀项目与工具的肩上,衷心感谢:
- Element Plus(含
@element-plus/icons-vue)—— 组件基座:大部分组件在其公开 API 上二次封装,ZySwitch/ZyLoading/ZySlideVerify/ZyMegaMenu等为自研。 - React Bits ——
ZyCodeInput的 CodeSlots、ZySelect的 Glide Select 滑行高亮原型。 - Uiverse · devsebastian44/orange-badger-71 ——
ZyButton的effect="fill"实色键帽。 - Uiverse · yasha_8286/sour-snake-86 ——
ZySwitch基础款的宽轨道 + 圆形滑块 + 箭头翻转参考(MIT)。 - vengenceui · mega-menu-navbar ——
ZyMegaMenu的结构参考。 - ui-ux-pro-max —— 设计核对(Liquid Glass / Depth Layering / 对比度条目)。
另有若干动效原型(holo-toggle、glitch-radio 等)在源码注释中标注出处,未逐一列链接。
声明:Zy UI 为非官方社区项目,与 Element Plus、React Bits、Uiverse、vengenceui 等项目的维护方无隶属关系。组件库以 Element Plus 的公开 API 做二次封装,不包含、也不转售 Element Plus 源码或任何第三方项目的商业版内容。部分动效为公开片段的移植 / 改写,已在源码注释中标注来源;如果你是被引用的原作者并希望调整署名或许可,欢迎通过 issue 联系。各项目名称、商标与代码分别归其各自所有者,并遵循其各自许可。
许可
MIT © 2026 @gyyxds/zy-ui contributors。可自由用于个人与商业项目,保留版权与许可声明即可分发;完整文本见 LICENSE。
