@zl-ui-kit/components 0.6.3 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -28
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -26,6 +26,9 @@ ZL UI 业务组件库 —— Element Plus 体系,`Zl` 前缀,47 个业务组
|
|
|
26
26
|
2. **数据型组件走 `useRequest`** —— 表格/卡片分页/树/图表等组件统一通过 `useRequest` 体系请求数据,与线上请求链路同构。
|
|
27
27
|
3. **样式变量双体系** —— 业务层 `--zl-*` 与 Element Plus 层 `--el-*` 协同,主题切换对两类组件同时生效。
|
|
28
28
|
|
|
29
|
+
> **只想知道「怎么接到自己项目里」?** 直接跳 **§1.2 宿主接入清单**(8 步 + 可直接粘贴的 `main.ts` / `App.vue` + 症状对照表),
|
|
30
|
+
> 或打开 playground 的 `/#/guide` 页面(代码块可一键复制)。后面章节是按能力的参考手册。
|
|
31
|
+
|
|
29
32
|
### 1.1 在业务项目中安装(npm 发布版)
|
|
30
33
|
|
|
31
34
|
```bash
|
|
@@ -34,9 +37,17 @@ npm i @zl-ui-kit/components @zl-ui-kit/composables @zl-ui-kit/utils
|
|
|
34
37
|
npm i @zl-ui-kit/theme
|
|
35
38
|
|
|
36
39
|
# peer 依赖(组件库不打包它们,需宿主提供)
|
|
37
|
-
npm i vue element-plus @vueuse/core
|
|
40
|
+
npm i vue element-plus @vueuse/core vue-i18n
|
|
38
41
|
```
|
|
39
42
|
|
|
43
|
+
> **`vue-i18n` 是必需 peer,不是可选。** `@zl-ui-kit/composables` 的产物里是**静态** `import ... from 'vue-i18n'`
|
|
44
|
+
> (`useLocale` / `createZlI18n` / `useZlT` 都用它),漏装的表现是构建期直接失败:
|
|
45
|
+
> Vite 8 / rolldown 报 `failed to resolve import "vue-i18n"`,Vite 5/6 也只是在有 optional-peer stub 时才降成告警。
|
|
46
|
+
> 版本用 `^11`(`legacy: false` / `useI18n({ useScope: 'global' })` 均适用)。
|
|
47
|
+
>
|
|
48
|
+
> 若 `npm i` 报 `ERESOLVE`(`@vue-office/*` 的 optional peer 会尝试解析出 vue 2),加 `--legacy-peer-deps` 重试;
|
|
49
|
+
> pnpm 不受此影响(会按 peer 自动装齐)。
|
|
50
|
+
|
|
40
51
|
`@zl-ui-kit/icons` 是 `components` 的**直接依赖**(图标由组件内部消费),会自动装上,无需手写。`composables` / `utils` 虽然也列在 `dependencies` 里,但**只要你想在自己的代码里 import 它们,就请显式安装** —— 理由见下方「按需引入」的提示。
|
|
41
52
|
|
|
42
53
|
以下组件**不在主入口**,走独立子路径,依赖按需安装(`peerDependenciesMeta.optional`,没装也不会导致主入口编译失败):
|
|
@@ -56,9 +67,7 @@ import { ZlFilePreview, ZlFileViewer } from '@zl-ui-kit/components/file-preview'
|
|
|
56
67
|
> 例外:`ZlPdfViewer` 没有重型依赖,仍留在主入口,`import { ZlPdfViewer } from '@zl-ui-kit/components'`。
|
|
57
68
|
> `app.use(ZlUI)` 全量注册**不含**上述子入口组件,需要的话手动 `app.component('ZlChart', ZlChart)`。
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
| ---------------------------------------------------- | --- | --------------------------------- |
|
|
61
|
-
| **关于 `echarts` 版本**(\`peerDependencies: "^5.6.0 | | ^6.0.0"\`,5.6+ 与 6.x 均支持): |
|
|
70
|
+
**关于 `echarts` 版本**(`peerDependencies: "^5.6.0 || ^6.0.0"`,5.6+ 与 6.x 均支持):
|
|
62
71
|
|
|
63
72
|
- `ZlChart` 内部是 `import * as echarts from 'echarts'`(全量包,开箱即用、无需自己 `use()` 注册图表类型);
|
|
64
73
|
若宿主用 `echarts/core` + 按需注册,两者是两份独立实例,产物会同时含两份 echarts(实测约 +600KB)。
|
|
@@ -126,6 +135,132 @@ import '@zl-ui-kit/theme/themes.css'
|
|
|
126
135
|
> (前者是 JSON 缺 import attribute,后者依赖 CJS 包 `file-saver` 的具名导出)。
|
|
127
136
|
> Vite / webpack 打包的 Vue 项目不受影响;做 Node SSR 时把这两个包加进 `ssr.noExternal`。
|
|
128
137
|
|
|
138
|
+
### 1.2 宿主接入清单(从零到跑起来)
|
|
139
|
+
|
|
140
|
+
> 这一节是「照抄就能跑」的完整清单,对应 playground 的 **`/#/guide` 页面**(页面里每段代码都能一键复制)。
|
|
141
|
+
> playground 自身就是一个标准宿主,`apps/playground/src/main.ts` 与 `App.vue` 可以直接对照。
|
|
142
|
+
|
|
143
|
+
| # | 做什么 | 漏了会怎样 |
|
|
144
|
+
| --- | ------------------------------------------------------------------------ | --------------------------------------------------- |
|
|
145
|
+
| 1 | 装 5 个包 + peer(`vue` / `element-plus` / `@vueuse/core` / `vue-i18n`) | 解析不到 `@zl-ui-kit/*`;漏 `vue-i18n` 直接构建失败 |
|
|
146
|
+
| 2 | `app.use(ElementPlus)`(或按名注册 kit 内部用到的 EP 组件) | Zl 组件内部那块区域**空白且无报错**(见 1.2.3) |
|
|
147
|
+
| 3 | 引 `element-plus/dist/index.css` **再引** `@zl-ui-kit/theme/themes.css` | 组件无样式 / 主题变量全走 fallback |
|
|
148
|
+
| 4 | `app.use(ZlUI)` 或手动 `app.component()` | `<zl-*>` 全局标签无效 |
|
|
149
|
+
| 5 | `presetIconifyIcon(icons)` | **所有图标空白**,`.zl-icon` 是空 `div`,无告警 |
|
|
150
|
+
| 6 | `app.use(i18n)` + 根组件包 `<ZlI18nProvider>` | 文案不随语言切;EP 分页/日期选择器仍是英文 |
|
|
151
|
+
| 7 | `setDictSource(...)` | `ZlDictTag`、表单里的字典项全空 |
|
|
152
|
+
| 8 | `setGlobalOptions({ pagination })`(键名与默认不同时) | 分页组件拿不到 `total`,列表永远是第 1 页空数据 |
|
|
153
|
+
|
|
154
|
+
#### 1.2.1 `main.ts`(可直接粘贴)
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { createApp } from 'vue'
|
|
158
|
+
import ElementPlus from 'element-plus'
|
|
159
|
+
import 'element-plus/dist/index.css'
|
|
160
|
+
import en from 'element-plus/es/locale/lang/en'
|
|
161
|
+
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
|
162
|
+
|
|
163
|
+
// 组件 + 图标 + hooks + 主题样式,四类入口分开
|
|
164
|
+
import ZlUI, { createZlI18n, presetIconifyIcon } from '@zl-ui-kit/components'
|
|
165
|
+
import { icons } from '@zl-ui-kit/icons'
|
|
166
|
+
import { setDictSource, setGlobalOptions, useGlobalData } from '@zl-ui-kit/composables'
|
|
167
|
+
import '@zl-ui-kit/theme/themes.css'
|
|
168
|
+
|
|
169
|
+
import App from './App.vue'
|
|
170
|
+
import router from './router'
|
|
171
|
+
|
|
172
|
+
// ① 先定初始语言:createZlI18n 用当前 locale 初始化,locale 为空会取到非法值
|
|
173
|
+
const { locale } = useGlobalData()
|
|
174
|
+
locale.value = 'zh'
|
|
175
|
+
|
|
176
|
+
// ② i18n:自动包含组件库内置语言包,只写要覆盖的 key;elLocales 提供给 EP
|
|
177
|
+
const { i18n } = createZlI18n({
|
|
178
|
+
messages: { zh: { 'zl.empty.noData': '暂无数据' } }, // 可选:覆盖文案
|
|
179
|
+
elLocales: { zh: zhCn, en },
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
// ③ 图标集(必须,否则一个图标都不显示)
|
|
183
|
+
presetIconifyIcon(icons)
|
|
184
|
+
|
|
185
|
+
// ④ 后端分页键名与默认(pageNum/pageSize/total/rows)不同时覆盖
|
|
186
|
+
setGlobalOptions({
|
|
187
|
+
pagination: { currentKey: 'pageNum', pageSizeKey: 'pageSize', totalKey: 'total', dataKey: 'rows' },
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// ⑤ 字典数据源:静态表或异步加载函数,全局注册一次
|
|
191
|
+
setDictSource(async (key) => {
|
|
192
|
+
const { data } = await api.get('/dict', { params: { key } })
|
|
193
|
+
return data as { label: string; value: string }[]
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
createApp(App).use(i18n).use(ElementPlus).use(ZlUI).use(router).mount('#app')
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
主题切换与运行时换肤见第 10 章(`setTheme` / `defineTheme` / `enableThemePersistence`)。
|
|
200
|
+
|
|
201
|
+
#### 1.2.2 `App.vue`:根组件包一层 `ZlI18nProvider`
|
|
202
|
+
|
|
203
|
+
```vue
|
|
204
|
+
<script setup lang="ts">
|
|
205
|
+
import { ZlI18nProvider } from '@zl-ui-kit/components'
|
|
206
|
+
</script>
|
|
207
|
+
|
|
208
|
+
<template>
|
|
209
|
+
<ZlI18nProvider>
|
|
210
|
+
<router-view />
|
|
211
|
+
</ZlI18nProvider>
|
|
212
|
+
</template>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`ZlI18nProvider` 的作用是把全局 `elLocaleMessages` 挂到 `<el-config-provider>` 上。**不包这一层时**,Zl 组件自己的文案会跟着切换,但 Element Plus 内置组件(分页、日期选择器、Popconfirm、表格空文案)仍停在默认语言——这是最常见的「一半中文一半英文」原因。
|
|
216
|
+
|
|
217
|
+
#### 1.2.3 组件注册的三种方式(以及 EP 的坑)
|
|
218
|
+
|
|
219
|
+
| 方式 | 写法 | 适用 |
|
|
220
|
+
| ----------- | --------------------------------------------------------------------- | --------------------------------------- |
|
|
221
|
+
| 全量插件 | `app.use(ZlUI)` | 业务项目首选,47 个组件全注册,一次搞定 |
|
|
222
|
+
| 按名注册 | `app.component('ZlTable', ZlTable)` | 只要几个组件,控制产物 |
|
|
223
|
+
| 直接 import | `<script setup>` 里 `import { ZlTable } from '@zl-ui-kit/components'` | 单文件用一次,无需全局 |
|
|
224
|
+
|
|
225
|
+
> ⚠️ **不管用哪种,Element Plus 的组件都必须能被「按名」解析到。**
|
|
226
|
+
> `@zl-ui-kit/components` 发布的是**编译后的 render 函数**,内部用 `resolveComponent('el-select')` 之类按名取组件,**不是模板**。所以 `unplugin-vue-components` 的 ElementPlusResolver **改不到它**(那个插件只处理源码里的模板标签)。
|
|
227
|
+
|
|
228
|
+
漏掉的典型症状:页面某块区域**直接空白、控制台一行报错都没有**(Vue 把未解析的名字当原生自定义元素渲染)。可选做法:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
// A. 省事:全量注册(EP 样式仍需自己引入)
|
|
232
|
+
app.use(ElementPlus)
|
|
233
|
+
|
|
234
|
+
// B. 精确:只注册 kit 内部用到的那批(产物更小)
|
|
235
|
+
import { ElForm, ElFormItem, ElInput, ElOption, ElSelect } from 'element-plus'
|
|
236
|
+
const KIT_EP = { ElForm, ElFormItem, ElInput, ElOption, ElSelect }
|
|
237
|
+
Object.entries(KIT_EP).forEach(([name, c]) => app.component(name, c as never))
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
`ZlSearch` / `ZlForm` / `ZlTable` 还会按 schema 里的 `component` 字段动态渲染控件,**用到哪个控件就要注册哪个**(`el-date-picker`、`el-input-number`、`el-cascader` 等)。
|
|
241
|
+
|
|
242
|
+
#### 1.2.4 子路径入口的组件要手动注册
|
|
243
|
+
|
|
244
|
+
`ZlChart` / `ZlEditor` / `ZlFilePreview` 不在主入口(见 1.1),`app.use(ZlUI)` 也**不包含**它们:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import { ZlChart } from '@zl-ui-kit/components/chart'
|
|
248
|
+
app.component('ZlChart', ZlChart) // 用到才注册,避免把 echarts 打进首屏
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### 1.2.5 接入自检:症状 → 原因
|
|
252
|
+
|
|
253
|
+
| 现象 | 原因 | 处理 |
|
|
254
|
+
| -------------------------------------------- | -------------------------------------------------- | ---------------------------------- |
|
|
255
|
+
| 构建报 `failed to resolve import "vue-i18n"` | 没装 `vue-i18n`(必需 peer,产物里是静态 import) | 见 §1.1 |
|
|
256
|
+
| 图标全空白,`.zl-icon` 里没有 `<svg>` | 没调 `presetIconifyIcon(icons)` | 见 §4.1 |
|
|
257
|
+
| 某块区域空白、无报错 | kit 内部的 `el-*` 没注册 | 见 1.2.3 |
|
|
258
|
+
| 组件完全没有样式 | 没引 `themes.css` / 引在 EP 样式之前被覆盖 | 顺序:EP css → themes.css |
|
|
259
|
+
| 分页一直 0 条 / `total` 为 undefined | 后端分页键名不同 | `setGlobalOptions({ pagination })` |
|
|
260
|
+
| `ZlDictTag` 显示原始 value | 没 `setDictSource` 或 key 不匹配 | 应用入口注册数据源 |
|
|
261
|
+
| EP 分页、日期还是英文 | 没包 `ZlI18nProvider` 或没传 `elLocales` | 见 §13 |
|
|
262
|
+
| 主题切了但 EP 组件颜色不变 | 只引了 `theme/light` 单主题 CSS,且没调 `setTheme` | 见 §10 |
|
|
263
|
+
|
|
129
264
|
---
|
|
130
265
|
|
|
131
266
|
## 2. 环境准备与运行示例
|
|
@@ -182,19 +317,21 @@ setTheme('dark') // 切换主题(light/dark/red-light/red-dark/blue)
|
|
|
182
317
|
|
|
183
318
|
### 2.4 示例页面索引
|
|
184
319
|
|
|
185
|
-
| 路由 | 页面 | 覆盖内容
|
|
186
|
-
| ------------------------ | ------------------ |
|
|
187
|
-
|
|
|
188
|
-
| `/
|
|
189
|
-
|
|
|
190
|
-
| `/
|
|
191
|
-
| `/
|
|
192
|
-
| `/
|
|
193
|
-
| `/
|
|
194
|
-
| `/
|
|
195
|
-
| `/
|
|
196
|
-
| `/examples/
|
|
197
|
-
| `/examples/
|
|
320
|
+
| 路由 | 页面 | 覆盖内容 |
|
|
321
|
+
| ------------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
322
|
+
| `/guide` | 快速接入 | **宿主从零接入的 8 步清单**:安装 → `main.ts` 装配(i18n / 图标 / 字典 / 请求全局配置)→ `App.vue` 包 `ZlI18nProvider` → 主题 → 组件注册与「EP 必须能被按名解析」的坑 → 自检表「症状 → 原因」 |
|
|
323
|
+
| `/hooks` | Hooks 与工具 | `useGlobalData` / `useDict` / `useZlT` / `useGlobalMessage` / `createCacheComputed`,以及 `utils` 的 `convertArrayToTree` / `paginate` / `formatFilesize` / `formatNumber` / `getIndex` / `generateUUID` / `deepCopy`(全部可交互) |
|
|
324
|
+
| `/` | 组件总览 | 按功能分组的组件卡片,点击进入组件页(Element Plus 官网 overview 的组织方式) |
|
|
325
|
+
| `/component/:name` | 组件页 | 基础用法实时示例 + 用法示例 / 插槽用法代码块 + props / 事件 / 插槽 / 暴露方法表 + 上/下一页 |
|
|
326
|
+
| `/manual` | 接口手册 | 全量 API 检索,支持按 props 名 / 事件名反查组件,`?name=ZlTable` 直接定位 |
|
|
327
|
+
| `/icons` | 图标集 | 全量图标浏览/搜索,`zl:` 前缀渲染 |
|
|
328
|
+
| `/theme` | 主题工场 | 5 套主题切换 + `defineTheme` 运行时自定义 |
|
|
329
|
+
| `/gallery` | 组件陈列 | 55 个组件逐个渲染(用于批量截图与冒烟) |
|
|
330
|
+
| `/use-request` | useRequest 联调 | 用 Mock 模块驱动各数据型组件(见第 6 章) |
|
|
331
|
+
| `/examples/basic` | 通用展示示例 | ZlTitle/ZlTag/ZlCornerTag/ZlIcon/ZlText/ZlCopy/ZlAutoTooltip/ZlPagination/ZlEmpty |
|
|
332
|
+
| `/examples/table-form` | 表格/表单示例 | ZlTable/ZlSearchTable/ZlForm/ZlDrawer/ZlPopconfirm/ZlSwitch/ZlDescription/ZlAction/ZlIconLabel/ZlIconHover/ZlSearch |
|
|
333
|
+
| `/examples/general` | 布局与交互示例 | ZlAvatar/ZlCheckAll/ZlRadioTag/ZlCheckboxTag/ZlAddSub/ZlSorter/ZlLayoutSwitch/ZlSection/ZlCard/ZlAppSlogan/ZlPermission/ZlHorizontalTable/ZlUpload/ZlTabs/ZlGrid/ZlDynamicComponent/ZlCardPage |
|
|
334
|
+
| `/examples/search-table` | ZlSearchTable 专项 | 基础用法 / `{ service, options }` 用法 / 暴露方法 / 无查询项 immediate,含分页与查询验证 |
|
|
198
335
|
|
|
199
336
|
> 改造前的扁平路由(`/components`、`/general`、`/table-form`、`/search-table`)保留 **redirect**,历史链接与自动化脚本不会失效。
|
|
200
337
|
|
|
@@ -847,7 +984,52 @@ enableThemePersistence() // 可选:localStorage 记住选择(key: zl-theme
|
|
|
847
984
|
const { theme, themes, setTheme } = useTheme() // 组件内响应式
|
|
848
985
|
```
|
|
849
986
|
|
|
850
|
-
自定义主题与内置主题变量完全同构,色阶派生算法与 EP theme-chalk 对齐,支持任意数量并存切换;`tokens` 参数可覆盖任意底层 token
|
|
987
|
+
自定义主题与内置主题变量完全同构,色阶派生算法与 EP theme-chalk 对齐,支持任意数量并存切换;`tokens` 参数可覆盖任意底层 token 深度定制(键 = `--zl-` 后面的部分,如 `{ 'radius-large': '10px' }`)。
|
|
988
|
+
|
|
989
|
+
### 变量速查(改样式时最常用)
|
|
990
|
+
|
|
991
|
+
全部 `--zl-*` 由 `packages/theme/src/generated/themes.css` 产出。宿主改视觉时优先改这些,不要改组件源码:
|
|
992
|
+
|
|
993
|
+
| 分类 | 变量 | 说明 |
|
|
994
|
+
| -------- | ------------------------------------------------------------------------------------ | ---------------------------------------- |
|
|
995
|
+
| 底色 | `--zl-bg-1` ~ `--zl-bg-5` | 1 页面 / 2 容器卡片 / 3 浮层 / 4-5 更浅 |
|
|
996
|
+
| 文本 | `--zl-text-1` ~ `--zl-text-4` | 主 / 常规 / 次要 / 占位与禁用 |
|
|
997
|
+
| 边框 | `--zl-border-1` ~ `--zl-border-4` | 越深越强调(`-2` 是最常见的 1px 边框色) |
|
|
998
|
+
| 填充 | `--zl-fill-1` ~ `--zl-fill-4` | 表头 / hover / 选中 / 更重 |
|
|
999
|
+
| 主色板 | `--zl-primary-1` ~ `--zl-primary-10` | 6 为主色,1 最浅(选中底),9 较深 |
|
|
1000
|
+
| 其它色板 | `--zl-{modo,link,success,warning,danger,error,purple,cyan,blue,...}-1..10` | 与 `--el-color-*` 双向联动 |
|
|
1001
|
+
| 形状 | `--zl-radius-{small,base,medium,large,xl,round}` | 2 / 4 / 4 / 6 / 12 / 99px |
|
|
1002
|
+
| 字体 | `--zl-font-family-code` / `--zl-slogan-font-family` | 等宽(代码/日志)/ 品牌标语 |
|
|
1003
|
+
| 阴影 | `--zl-shadow` | 卡片投影色 |
|
|
1004
|
+
| 布局 | `--zl-layout-vertical-aside-bg` / `--zl-layout-horizontal-header-bg` / `--zl-menu-*` | 侧栏 / 顶栏渐变,菜单文字与 hover 底 |
|
|
1005
|
+
|
|
1006
|
+
> **形状 / 字体 token 自 `0.6.4` 起才真正产出。** 组件里一直写的是 `var(--zl-radius-large, 6px)` 这类带兜底的形式,此前这些 token 从未生成,等于「值被兜底写死、宿主改不了」。现在按兜底值原样产出 —— 视觉不变,但可在 `body` 上覆写,或经 `defineTheme({ tokens })` 定制。
|
|
1007
|
+
|
|
1008
|
+
### 主题状态与 `useGlobalData().theme` 的关系(容易踩)
|
|
1009
|
+
|
|
1010
|
+
主题名存在**两个不同位置**,互不自动同步:
|
|
1011
|
+
|
|
1012
|
+
| 来源 | 读取/写入 | storage 键 | 说明 |
|
|
1013
|
+
| ------------------------------------------------------------------------ | ------------------ | ----------- | ------------------------------------------------- |
|
|
1014
|
+
| `@zl-ui-kit/theme`(`setTheme` / `useTheme` / `enableThemePersistence`) | `useTheme().theme` | `zl-theme` | **真正驱动视觉的那一份**(改 `body[data-theme]`) |
|
|
1015
|
+
| `useGlobalData()` | `g.theme` | `$zl_theme` | 只是全局数据里的一个字段,改它不会换主题 |
|
|
1016
|
+
|
|
1017
|
+
结论:**切主题统一走 `setTheme()`**。若两处都要用,加一行单向同步即可:
|
|
1018
|
+
|
|
1019
|
+
```ts
|
|
1020
|
+
const g = useGlobalData()
|
|
1021
|
+
const { theme } = useTheme()
|
|
1022
|
+
watch(theme, (value) => (g.theme.value = value), { immediate: true })
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
### 换肤不生效?按这个顺序查
|
|
1026
|
+
|
|
1027
|
+
1. **CSS 引入顺序**:`element-plus/dist/index.css` → `@zl-ui-kit/theme/themes.css`,反过来会被 EP 默认值压掉。
|
|
1028
|
+
2. **是否只引了单主题**:只引 `theme/light` 时切到 `dark` 当然没变化(`themes.css` 才是全量)。
|
|
1029
|
+
3. **变量写在哪儿**:`scoped` 样式里写的变量只作用于该组件;要全局生效写 `body` / `:root`,只影响某块就写到那个容器的 `style` 上。
|
|
1030
|
+
4. **`--zl-*` 与 `--el-*` 是否都改了**:EP 组件读 `--el-*`,只改 `--zl-*` 时 EP 自身组件不变(内置主题两层已联动,手写覆写要两边都写)。
|
|
1031
|
+
5. **刷新后丢主题**:没调 `enableThemePersistence()`(storage: `zl-theme`)。
|
|
1032
|
+
6. **自定义主题少了菜单/侧栏变量**:`0.6.4` 前 `defineTheme` 造的主题会漏 `--zl-menu-*` / `--zl-layout-*` 与 `--el-color-error`,升级即可。
|
|
851
1033
|
|
|
852
1034
|
### L3 构建时生成主题(深度定制,规划中)
|
|
853
1035
|
|
|
@@ -916,9 +1098,7 @@ import { useRequest, useGlobalData, useDict /* … */ } from '@zl-ui-kit/composa
|
|
|
916
1098
|
- **内置插件自动装载**,通过 `options` 开启(无需 import):
|
|
917
1099
|
- **loading**:`loadingDelay`(ms,延迟显示 loading,避免闪烁) / `loadingKeep`(ms,最短保持时间)
|
|
918
1100
|
- **ready**:`ready: Ref<boolean>`,为假时拦截请求,为真后自动 `run`(适合依赖前置条件就绪后再请求)
|
|
919
|
-
|
|
920
|
-
| --- | --- |
|
|
921
|
-
- **refreshDeps**:`refreshDeps: WatchSource | WatchSource[]`,依赖变化自动 `refresh`;可用 `refreshDepsAction` 自定义动作。
|
|
1101
|
+
- **refreshDeps**:`refreshDeps: WatchSource | WatchSource[]`,依赖变化自动 `refresh`;可用 `refreshDepsAction` 自定义动作
|
|
922
1102
|
与 `manual` 不冲突——`manual: true` 只表示「挂载时不自动发请求」,依赖变化照样会重查(唯一例外是从未 `run` 过的请求,没有可复用参数,会跳过)
|
|
923
1103
|
- **download**:`outputFile: MaybeRefOrGetter<string>`,`service` 返回 `Blob`(非 JSON)时自动下载保存
|
|
924
1104
|
- **自定义插件**:`defineUseRequestPlugin(plugin)` 返回 `PluginImplementType`,经 `useRequest(service, options, [myPlugin])` 第三参注入,可实现 `onBefore / onRequest / onSuccess / onError / onFinally / onCancel / onMutate` 钩子。
|
|
@@ -968,13 +1148,8 @@ g.resetUser() // 登出:清 user / roles / permissions / token
|
|
|
968
1148
|
|
|
969
1149
|
#### 12.1.3 字典与国际化
|
|
970
1150
|
|
|
971
|
-
| | |
|
|
972
|
-
| --- | --- |
|
|
973
|
-
|
|
974
1151
|
- `useDictStore`(全局字典 store,基于 Vue3 `createGlobalState` 单例):`dictStore`(缓存 `Record<key, DictItem[]>`)、`loadingKeys`、`setDictSource(source|null)`、`getDictSource()`、`ensureDict(key, localSource?)`。同一 key 仅在缓存未命中且未在加载时触发一次加载,结果缓存复用。
|
|
975
1152
|
- `useDict(key, options?)` → `ComputedRef<DictItem[]>`(附带 `.label: Record<value,label>`):读 `useDictStore` 并解析。数据解析优先级:组件级 `options.data` → 局部 `useDictProvider({ source })` → 全局 `setDictSource(source)`。`DictItem = { label, value, icon?, type? }`(亦可用 `type DictItem` 导入)。
|
|
976
|
-
| | | |
|
|
977
|
-
| --- | --- | --- |
|
|
978
1153
|
- `setDictSource(source | null)`:全局注册字典数据源(应用入口调用一次)。`source` 为静态表 `Record<string, DictItem[]>` 或函数 `(key) => DictItem[] | Promise<DictItem[]>`;传 `null` 清空。`getDictSource()` 可读取当前值。
|
|
979
1154
|
- `useDictProvider(source)`:子树根提供局部字典数据源(覆盖全局)。
|
|
980
1155
|
- `useLocale(options?, loader?)` → `{ i18n, locale, isI18nKeyVisible }`:创建与全局语言联动的 vue-i18n 实例;`loader(locale)` 按需返回 `{ localeMessages, elLocaleMessages }`(业务包 + Element Plus locale)。`elLocaleMessages` 写入全局数据后,**必须**由 `ZlI18nProvider` 经 `<el-config-provider>` 挂载到 Element Plus 才生效(分页 / 日期选择器等内置组件才本地化)。详见第 13 章。
|
|
@@ -1067,8 +1242,6 @@ api.get('/resources', { params: { pageNum: 1, pageSize: 10 } })
|
|
|
1067
1242
|
- `fileSave`(re-export `file-saver` 的 `saveAs`)。
|
|
1068
1243
|
- `joinFilePrefix(path, prefix = '/_file')`:拼接文件服务前缀路径。
|
|
1069
1244
|
- `downloadFileByUrl(url, prefix?)`:创建临时 `<a>` 触发浏览器下载。
|
|
1070
|
-
| | | | | |
|
|
1071
|
-
| --- | --- | --- | --- | --- |
|
|
1072
1245
|
- `fileUrlPreviewType(path)` → `'image' | 'pdf' | 'word' | 'ppt' | 'excel'`(按扩展名判断)。
|
|
1073
1246
|
- `formatFilesize(size, { precision = 2, units })`:文件大小格式化(B/KB/MB/GB)。
|
|
1074
1247
|
|
|
@@ -2522,6 +2695,8 @@ import { ZlI18nProvider } from '@zl-ui-kit/components'
|
|
|
2522
2695
|
| --------- | ---------- | --------------------------------- | ---- |
|
|
2523
2696
|
| `default` | — | `<template #default>…</template>` | — |
|
|
2524
2697
|
|
|
2698
|
+
**完整示例**:见 §1 简介与包结构 › 1.2.2 App.vue:根组件包一层 ZlI18nProvider
|
|
2699
|
+
|
|
2525
2700
|
#### `ZlIconHover`
|
|
2526
2701
|
|
|
2527
2702
|
<sub>入口 `@zl-ui-kit/components` · 源码 `packages/components/src/components/ZlIconHover/index.vue`</sub>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zl-ui-kit/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ZL UI 业务组件库(Element Plus 体系,Zl 前缀)——首批:Icon/AutoTooltip/Tag/CornerTag/Text/Title/Copy/Empty/Pagination/DictTag",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"file-type": "^20.4.1",
|
|
40
40
|
"dt-sql-parser": "^4.3.1",
|
|
41
41
|
"sql-formatter": "^15.4.2",
|
|
42
|
-
"@zl-ui-kit/
|
|
43
|
-
"@zl-ui-kit/
|
|
44
|
-
"@zl-ui-kit/
|
|
42
|
+
"@zl-ui-kit/utils": "0.7.1",
|
|
43
|
+
"@zl-ui-kit/icons": "0.7.1",
|
|
44
|
+
"@zl-ui-kit/composables": "0.7.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@vueuse/core": "^12.3.0",
|
|
@@ -98,10 +98,10 @@
|
|
|
98
98
|
"@vue-office/pdf": "^2.0.10",
|
|
99
99
|
"@vue-office/pptx": "1.0.1",
|
|
100
100
|
"echarts": "^5.6.0",
|
|
101
|
-
"@jichuang/vite-config": "1.0.0",
|
|
102
101
|
"@jichuang/eslint-config": "1.0.0",
|
|
103
|
-
"@
|
|
104
|
-
"@jichuang/tsconfig": "1.0.0"
|
|
102
|
+
"@jichuang/vite-config": "1.0.0",
|
|
103
|
+
"@jichuang/tsconfig": "1.0.0",
|
|
104
|
+
"@zl-ui-kit/theme": "0.7.1"
|
|
105
105
|
},
|
|
106
106
|
"repository": {
|
|
107
107
|
"type": "git",
|