@cghbcf/xp-ui 1.0.0 → 1.0.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 +923 -0
- package/dist/cghbcf-xp-ui.cjs.js +4 -0
- package/dist/cghbcf-xp-ui.es.js +1342 -0
- package/dist/style.css +1 -1
- package/package.json +6 -9
- package/dist/xp-ui.cjs.js +0 -1
- package/dist/xp-ui.es.js +0 -274
package/README.md
ADDED
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
# @cghbcf/xp-ui
|
|
2
|
+
|
|
3
|
+
> Vue3 组件库 - 基于 Vue3 + Vite 构建的现代化 UI 组件库
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- ⚡ 基于 Vue3 和 Vite,性能卓越
|
|
8
|
+
- 📦 开箱即用,无需繁琐配置
|
|
9
|
+
- 🎨 现代化设计风格,支持主题定制(浅色 / 暗黑双主题)
|
|
10
|
+
- 🎛️ 可视化主题定制面板 —— 实时修改颜色、一键导出 JSON/CSS
|
|
11
|
+
- 🌈 主色自动派生(-light / -dark / -bg / -border),无需手动配置
|
|
12
|
+
- 🔧 丰富的组件库,覆盖常用场景(Button / Input / Dialog / Card / Tabs 等 14+ 组件)
|
|
13
|
+
- 💎 完整的 CSS 变量(Design Tokens)系统,便于深度定制
|
|
14
|
+
- 💾 主题配置自动持久化到 localStorage,刷新页面不丢失
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 快速开始
|
|
19
|
+
|
|
20
|
+
### 安装
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# npm
|
|
24
|
+
npm install @cghbcf/xp-ui --save
|
|
25
|
+
|
|
26
|
+
# yarn
|
|
27
|
+
yarn add @cghbcf/xp-ui
|
|
28
|
+
|
|
29
|
+
# pnpm
|
|
30
|
+
pnpm install @cghbcf/xp-ui
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 完整引入
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import { createApp } from 'vue'
|
|
37
|
+
import App from './App.vue'
|
|
38
|
+
import XpUi from '@cghbcf/xp-ui'
|
|
39
|
+
import '@cghbcf/xp-ui/dist/style.css'
|
|
40
|
+
|
|
41
|
+
const app = createApp(App)
|
|
42
|
+
app.use(XpUi)
|
|
43
|
+
app.mount('#app')
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 按需引入
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
import { createApp } from 'vue'
|
|
50
|
+
import App from './App.vue'
|
|
51
|
+
import { XpButton, XpInput, XpDialog, XpCard, XpTabs } from '@cghbcf/xp-ui'
|
|
52
|
+
import '@cghbcf/xp-ui/dist/style.css'
|
|
53
|
+
|
|
54
|
+
const app = createApp(App)
|
|
55
|
+
app.component('XpButton', XpButton)
|
|
56
|
+
app.component('XpInput', XpInput)
|
|
57
|
+
app.mount('#app')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
也可以直接使用主题 composable:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { useTheme, applyThemeConfig, setTheme, toggleTheme } from '@cghbcf/xp-ui'
|
|
64
|
+
|
|
65
|
+
const { theme, themeConfig, initTheme, applyThemeConfig, buildCssString } = useTheme()
|
|
66
|
+
initTheme()
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 组件
|
|
72
|
+
|
|
73
|
+
### Button 按钮
|
|
74
|
+
|
|
75
|
+
按钮用于触发一个操作,如提交表单、打开对话框等。
|
|
76
|
+
|
|
77
|
+
#### 基础用法
|
|
78
|
+
|
|
79
|
+
```vue
|
|
80
|
+
<template>
|
|
81
|
+
<XpButton>Default</XpButton>
|
|
82
|
+
<XpButton type="primary">Primary</XpButton>
|
|
83
|
+
<XpButton type="success">Success</XpButton>
|
|
84
|
+
<XpButton type="warning">Warning</XpButton>
|
|
85
|
+
<XpButton type="danger">Danger</XpButton>
|
|
86
|
+
<XpButton type="info">Info</XpButton>
|
|
87
|
+
|
|
88
|
+
<XpButton type="primary" plain>Plain Primary</XpButton>
|
|
89
|
+
<XpButton type="primary" text>Text Primary</XpButton>
|
|
90
|
+
|
|
91
|
+
<XpButton size="small" type="primary">Small</XpButton>
|
|
92
|
+
<XpButton size="medium" type="primary">Medium</XpButton>
|
|
93
|
+
<XpButton size="large" type="primary">Large</XpButton>
|
|
94
|
+
|
|
95
|
+
<XpButton type="primary" disabled>Disabled</XpButton>
|
|
96
|
+
<XpButton type="primary" loading @click="handleClick">Loading</XpButton>
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<script setup>
|
|
100
|
+
const handleClick = () => {}
|
|
101
|
+
</script>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
##### Props
|
|
105
|
+
|
|
106
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
107
|
+
|------|------|--------|------|
|
|
108
|
+
| type | string | default | 按钮类型,可选值:primary / default / success / warning / danger / info |
|
|
109
|
+
| size | string | medium | 按钮尺寸,可选值:small / medium / large |
|
|
110
|
+
| plain | boolean | false | 是否朴素按钮 |
|
|
111
|
+
| text | boolean | false | 是否文字按钮 |
|
|
112
|
+
| disabled | boolean | false | 是否禁用按钮 |
|
|
113
|
+
| loading | boolean | false | 是否显示加载状态 |
|
|
114
|
+
|
|
115
|
+
##### Events
|
|
116
|
+
|
|
117
|
+
| 事件名 | 说明 | 回调参数 |
|
|
118
|
+
|--------|------|----------|
|
|
119
|
+
| click | 点击按钮时触发 | event |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### Input 输入框
|
|
124
|
+
|
|
125
|
+
用于收集用户输入信息。
|
|
126
|
+
|
|
127
|
+
#### 基础用法
|
|
128
|
+
|
|
129
|
+
```vue
|
|
130
|
+
<template>
|
|
131
|
+
<XpInput v-model="inputValue" placeholder="请输入内容" showClear />
|
|
132
|
+
|
|
133
|
+
<XpInput placeholder="Small" size="small" />
|
|
134
|
+
<XpInput placeholder="Medium" size="medium" />
|
|
135
|
+
<XpInput placeholder="Large" size="large" />
|
|
136
|
+
|
|
137
|
+
<XpInput placeholder="用户名">
|
|
138
|
+
<template #prefix>👤</template>
|
|
139
|
+
</XpInput>
|
|
140
|
+
|
|
141
|
+
<XpInput placeholder="密码">
|
|
142
|
+
<template #suffix>🔒</template>
|
|
143
|
+
</XpInput>
|
|
144
|
+
|
|
145
|
+
<XpInput placeholder="禁用状态" disabled />
|
|
146
|
+
</template>
|
|
147
|
+
|
|
148
|
+
<script setup>
|
|
149
|
+
import { ref } from 'vue'
|
|
150
|
+
const inputValue = ref('')
|
|
151
|
+
</script>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
##### Props
|
|
155
|
+
|
|
156
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
157
|
+
|------|------|--------|------|
|
|
158
|
+
| modelValue | string / number | '' | 输入框的值,支持 v-model |
|
|
159
|
+
| type | string | text | 输入框类型,可选值:text / password / number / email / tel / url |
|
|
160
|
+
| placeholder | string | '' | 占位符文本 |
|
|
161
|
+
| disabled | boolean | false | 是否禁用 |
|
|
162
|
+
| size | string | medium | 输入框尺寸,可选值:small / medium / large |
|
|
163
|
+
| maxlength | string / number | null | 最大输入长度 |
|
|
164
|
+
| showClear | boolean | false | 是否显示清空按钮 |
|
|
165
|
+
|
|
166
|
+
##### Events
|
|
167
|
+
|
|
168
|
+
| 事件名 | 说明 | 回调参数 |
|
|
169
|
+
|--------|------|----------|
|
|
170
|
+
| update:modelValue | 值改变时触发 | value |
|
|
171
|
+
| focus | 获得焦点时触发 | event |
|
|
172
|
+
| blur | 失去焦点时触发 | event |
|
|
173
|
+
| clear | 点击清空按钮时触发 | - |
|
|
174
|
+
|
|
175
|
+
##### Slots
|
|
176
|
+
|
|
177
|
+
| 插槽名 | 说明 |
|
|
178
|
+
|--------|------|
|
|
179
|
+
| prefix | 前缀内容 |
|
|
180
|
+
| suffix | 后缀内容 |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### Switch 开关
|
|
185
|
+
|
|
186
|
+
表示两种相互对立的状态间的切换。
|
|
187
|
+
|
|
188
|
+
#### 基础用法
|
|
189
|
+
|
|
190
|
+
```vue
|
|
191
|
+
<template>
|
|
192
|
+
<XpSwitch v-model="value" />
|
|
193
|
+
<XpSwitch v-model="value" size="small" />
|
|
194
|
+
<XpSwitch v-model="value" size="large" />
|
|
195
|
+
<XpSwitch :model-value="true" disabled />
|
|
196
|
+
</template>
|
|
197
|
+
|
|
198
|
+
<script setup>
|
|
199
|
+
import { ref } from 'vue'
|
|
200
|
+
const value = ref(false)
|
|
201
|
+
</script>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
##### Props
|
|
205
|
+
|
|
206
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
207
|
+
|------|------|--------|------|
|
|
208
|
+
| modelValue | boolean | false | 绑定值,支持 v-model |
|
|
209
|
+
| size | string | medium | 尺寸:small / medium / large |
|
|
210
|
+
| disabled | boolean | false | 是否禁用 |
|
|
211
|
+
|
|
212
|
+
##### Events
|
|
213
|
+
|
|
214
|
+
| 事件名 | 说明 | 回调参数 |
|
|
215
|
+
|--------|------|----------|
|
|
216
|
+
| update:modelValue | 值改变时触发 | value |
|
|
217
|
+
| change | 值改变时触发 | value |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
### Checkbox 多选框
|
|
222
|
+
|
|
223
|
+
一组备选项中进行多选。
|
|
224
|
+
|
|
225
|
+
#### 基础用法
|
|
226
|
+
|
|
227
|
+
```vue
|
|
228
|
+
<template>
|
|
229
|
+
<XpCheckbox v-model="value1">同意协议</XpCheckbox>
|
|
230
|
+
<XpCheckbox v-model="value2">接收邮件</XpCheckbox>
|
|
231
|
+
<XpCheckbox :model-value="true" disabled>已勾选(禁用)</XpCheckbox>
|
|
232
|
+
<XpCheckbox :model-value="false" disabled>未勾选(禁用)</XpCheckbox>
|
|
233
|
+
</template>
|
|
234
|
+
|
|
235
|
+
<script setup>
|
|
236
|
+
import { ref } from 'vue'
|
|
237
|
+
const value1 = ref(true)
|
|
238
|
+
const value2 = ref(false)
|
|
239
|
+
</script>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
##### Props
|
|
243
|
+
|
|
244
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
245
|
+
|------|------|--------|------|
|
|
246
|
+
| modelValue | boolean | false | 绑定值,支持 v-model |
|
|
247
|
+
| disabled | boolean | false | 是否禁用 |
|
|
248
|
+
| indeterminate | boolean | false | 是否半选状态 |
|
|
249
|
+
|
|
250
|
+
##### Events
|
|
251
|
+
|
|
252
|
+
| 事件名 | 说明 | 回调参数 |
|
|
253
|
+
|--------|------|----------|
|
|
254
|
+
| update:modelValue | 值改变时触发 | value |
|
|
255
|
+
| change | 值改变时触发 | value |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
### Radio 单选框
|
|
260
|
+
|
|
261
|
+
在一组备选项中进行单选。
|
|
262
|
+
|
|
263
|
+
#### 基础用法
|
|
264
|
+
|
|
265
|
+
```vue
|
|
266
|
+
<template>
|
|
267
|
+
<XpRadio v-model="value" value="A">选项 A</XpRadio>
|
|
268
|
+
<XpRadio v-model="value" value="B">选项 B</XpRadio>
|
|
269
|
+
<XpRadio v-model="value" value="C">选项 C</XpRadio>
|
|
270
|
+
</template>
|
|
271
|
+
|
|
272
|
+
<script setup>
|
|
273
|
+
import { ref } from 'vue'
|
|
274
|
+
const value = ref('A')
|
|
275
|
+
</script>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
##### Props
|
|
279
|
+
|
|
280
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
281
|
+
|------|------|--------|------|
|
|
282
|
+
| modelValue | string / number / boolean | '' | 绑定值 |
|
|
283
|
+
| value | string / number / boolean | '' | 选项的值 |
|
|
284
|
+
| disabled | boolean | false | 是否禁用 |
|
|
285
|
+
|
|
286
|
+
##### Events
|
|
287
|
+
|
|
288
|
+
| 事件名 | 说明 | 回调参数 |
|
|
289
|
+
|--------|------|----------|
|
|
290
|
+
| update:modelValue | 值改变时触发 | value |
|
|
291
|
+
| change | 值改变时触发 | value |
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
### Tag 标签 & Badge 徽标
|
|
296
|
+
|
|
297
|
+
Tag 用于标记和分类;Badge 用于消息数量提示。
|
|
298
|
+
|
|
299
|
+
#### 基础用法
|
|
300
|
+
|
|
301
|
+
```vue
|
|
302
|
+
<template>
|
|
303
|
+
<XpTag>Default</XpTag>
|
|
304
|
+
<XpTag type="primary">Primary</XpTag>
|
|
305
|
+
<XpTag type="success">Success</XpTag>
|
|
306
|
+
<XpTag type="warning">Warning</XpTag>
|
|
307
|
+
<XpTag type="danger">Danger</XpTag>
|
|
308
|
+
<XpTag type="info">Info</XpTag>
|
|
309
|
+
|
|
310
|
+
<XpTag round type="primary">Round</XpTag>
|
|
311
|
+
<XpTag size="small">Small</XpTag>
|
|
312
|
+
<XpTag size="large">Large</XpTag>
|
|
313
|
+
<XpTag closable>Closable</XpTag>
|
|
314
|
+
|
|
315
|
+
<XpBadge value="5">
|
|
316
|
+
<XpButton size="small">消息</XpButton>
|
|
317
|
+
</XpBadge>
|
|
318
|
+
<XpBadge value="120" type="warning">
|
|
319
|
+
<XpButton size="small">通知</XpButton>
|
|
320
|
+
</XpBadge>
|
|
321
|
+
<XpBadge isDot type="danger">
|
|
322
|
+
<XpButton size="small">新消息</XpButton>
|
|
323
|
+
</XpBadge>
|
|
324
|
+
</template>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
##### Tag Props
|
|
328
|
+
|
|
329
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
330
|
+
|------|------|--------|------|
|
|
331
|
+
| type | string | default | 类型:primary / default / success / warning / danger / info |
|
|
332
|
+
| size | string | medium | 尺寸:small / medium / large |
|
|
333
|
+
| color | string | '' | 自定义颜色(#xxx 或 rgb) |
|
|
334
|
+
| plain | boolean | false | 是否朴素样式 |
|
|
335
|
+
| round | boolean | false | 是否圆角 |
|
|
336
|
+
| closable | boolean | false | 是否可关闭 |
|
|
337
|
+
|
|
338
|
+
##### Badge Props
|
|
339
|
+
|
|
340
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
341
|
+
|------|------|--------|------|
|
|
342
|
+
| value | string / number | 0 | 显示值 |
|
|
343
|
+
| max | number | 99 | 最大值,超出显示 {max}+ |
|
|
344
|
+
| type | string | danger | 类型:primary / success / warning / danger / info |
|
|
345
|
+
| isDot | boolean | false | 是否以小圆点显示 |
|
|
346
|
+
| hidden | boolean | false | 是否隐藏徽标 |
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
### Alert 提示
|
|
351
|
+
|
|
352
|
+
用于页面中展示重要的提示信息。
|
|
353
|
+
|
|
354
|
+
#### 基础用法
|
|
355
|
+
|
|
356
|
+
```vue
|
|
357
|
+
<template>
|
|
358
|
+
<XpAlert title="这是一条成功消息" type="success" />
|
|
359
|
+
<XpAlert title="这是一条警告消息" type="warning" />
|
|
360
|
+
<XpAlert title="这是一条错误消息" type="danger" />
|
|
361
|
+
<XpAlert title="这是一条提示消息" type="info" />
|
|
362
|
+
</template>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
##### Props
|
|
366
|
+
|
|
367
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
368
|
+
|------|------|--------|------|
|
|
369
|
+
| title | string | '' | 标题 |
|
|
370
|
+
| type | string | info | 类型:success / warning / danger / info |
|
|
371
|
+
| effect | string | light | 样式:light / dark / plain |
|
|
372
|
+
| closable | boolean | true | 是否可关闭 |
|
|
373
|
+
| showIcon | boolean | true | 是否显示图标 |
|
|
374
|
+
|
|
375
|
+
##### Events
|
|
376
|
+
|
|
377
|
+
| 事件名 | 说明 | 回调参数 |
|
|
378
|
+
|--------|------|----------|
|
|
379
|
+
| close | 关闭 alert 时触发 | - |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
### Avatar 头像
|
|
384
|
+
|
|
385
|
+
用图标、图片或者字符展示用户头像。
|
|
386
|
+
|
|
387
|
+
#### 基础用法
|
|
388
|
+
|
|
389
|
+
```vue
|
|
390
|
+
<template>
|
|
391
|
+
<XpAvatar size="small">Xp</XpAvatar>
|
|
392
|
+
<XpAvatar>User</XpAvatar>
|
|
393
|
+
<XpAvatar size="large">Demo</XpAvatar>
|
|
394
|
+
<XpAvatar shape="square">Sq</XpAvatar>
|
|
395
|
+
<XpAvatar shape="square" size="large">UI</XpAvatar>
|
|
396
|
+
<XpAvatar src="https://example.com/avatar.png" alt="Avatar" />
|
|
397
|
+
</template>
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
##### Props
|
|
401
|
+
|
|
402
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
403
|
+
|------|------|--------|------|
|
|
404
|
+
| src | string | '' | 图片头像地址 |
|
|
405
|
+
| alt | string | '' | 替代文本 |
|
|
406
|
+
| shape | string | circle | 形状:circle / square |
|
|
407
|
+
| size | string | medium | 尺寸:small / medium / large |
|
|
408
|
+
| icon | string | '' | 图标 |
|
|
409
|
+
|
|
410
|
+
##### Events
|
|
411
|
+
|
|
412
|
+
| 事件名 | 说明 | 回调参数 |
|
|
413
|
+
|--------|------|----------|
|
|
414
|
+
| error | 图片加载失败时触发 | - |
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
### Progress 进度条 & Rate 评分
|
|
419
|
+
|
|
420
|
+
进度条用于展示操作进度;评分用于对事物进行评级操作。
|
|
421
|
+
|
|
422
|
+
#### 基础用法
|
|
423
|
+
|
|
424
|
+
```vue
|
|
425
|
+
<template>
|
|
426
|
+
<XpProgress :percentage="30" style="width:240px" />
|
|
427
|
+
<XpProgress :percentage="60" status="warning" style="width:240px" />
|
|
428
|
+
<XpProgress :percentage="85" status="success" style="width:240px" />
|
|
429
|
+
<XpProgress :percentage="100" status="exception" style="width:240px" />
|
|
430
|
+
|
|
431
|
+
<XpRate v-model="rate" showText />
|
|
432
|
+
</template>
|
|
433
|
+
|
|
434
|
+
<script setup>
|
|
435
|
+
import { ref } from 'vue'
|
|
436
|
+
const rate = ref(3)
|
|
437
|
+
</script>
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
##### Progress Props
|
|
441
|
+
|
|
442
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
443
|
+
|------|------|--------|------|
|
|
444
|
+
| percentage | number | 0 | 百分比(0-100) |
|
|
445
|
+
| color | string | '' | 自定义进度条颜色 |
|
|
446
|
+
| showText | boolean | true | 是否显示百分比文字 |
|
|
447
|
+
| type | string | line | 类型:line / circle |
|
|
448
|
+
| status | string | '' | 状态:success / warning / exception |
|
|
449
|
+
|
|
450
|
+
##### Rate Props
|
|
451
|
+
|
|
452
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
453
|
+
|------|------|--------|------|
|
|
454
|
+
| modelValue | number | 0 | 绑定值 |
|
|
455
|
+
| max | number | 5 | 最大分值 |
|
|
456
|
+
| color | string | #f7ba2a | 颜色 |
|
|
457
|
+
| disabled | boolean | false | 是否禁用 |
|
|
458
|
+
| showText | boolean | false | 是否显示文字 |
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
### Tooltip 提示
|
|
463
|
+
|
|
464
|
+
常用于展示鼠标 hover 时的提示信息。
|
|
465
|
+
|
|
466
|
+
#### 基础用法
|
|
467
|
+
|
|
468
|
+
```vue
|
|
469
|
+
<template>
|
|
470
|
+
<XpTooltip content="顶部提示">
|
|
471
|
+
<XpButton type="primary">Top</XpButton>
|
|
472
|
+
</XpTooltip>
|
|
473
|
+
<XpTooltip content="底部提示" placement="bottom">
|
|
474
|
+
<XpButton>Bottom</XpButton>
|
|
475
|
+
</XpTooltip>
|
|
476
|
+
<XpTooltip content="左侧提示" placement="left">
|
|
477
|
+
<XpButton type="success">Left</XpButton>
|
|
478
|
+
</XpTooltip>
|
|
479
|
+
<XpTooltip content="右侧提示" placement="right">
|
|
480
|
+
<XpButton type="warning">Right</XpButton>
|
|
481
|
+
</XpTooltip>
|
|
482
|
+
</template>
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
##### Props
|
|
486
|
+
|
|
487
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
488
|
+
|------|------|--------|------|
|
|
489
|
+
| content | string | '' | 显示的内容 |
|
|
490
|
+
| placement | string | top | 出现位置:top / bottom / left / right |
|
|
491
|
+
| trigger | string | hover | 触发方式:hover / click / manual |
|
|
492
|
+
| disabled | boolean | false | 是否禁用 |
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
### Dropdown 下拉菜单
|
|
497
|
+
|
|
498
|
+
将动作或菜单折叠到下拉菜单中。
|
|
499
|
+
|
|
500
|
+
#### 基础用法
|
|
501
|
+
|
|
502
|
+
```vue
|
|
503
|
+
<template>
|
|
504
|
+
<XpDropdown :items="items" @select="handleSelect">
|
|
505
|
+
<XpButton type="primary">下拉菜单 ▾</XpButton>
|
|
506
|
+
</XpDropdown>
|
|
507
|
+
</template>
|
|
508
|
+
|
|
509
|
+
<script setup>
|
|
510
|
+
const items = [
|
|
511
|
+
{ label: '选项一', command: 'a' },
|
|
512
|
+
{ label: '选项二', command: 'b' },
|
|
513
|
+
{ label: '选项三(禁用)', command: 'c', disabled: true },
|
|
514
|
+
{ divider: true },
|
|
515
|
+
{ label: '选项四', command: 'd' }
|
|
516
|
+
]
|
|
517
|
+
const handleSelect = (item) => {
|
|
518
|
+
console.log('选中:', item)
|
|
519
|
+
}
|
|
520
|
+
</script>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
##### Props
|
|
524
|
+
|
|
525
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
526
|
+
|------|------|--------|------|
|
|
527
|
+
| items | Array | [] | 菜单项:{ label, command, disabled, divider } |
|
|
528
|
+
| disabled | boolean | false | 是否禁用 |
|
|
529
|
+
|
|
530
|
+
##### Events
|
|
531
|
+
|
|
532
|
+
| 事件名 | 说明 | 回调参数 |
|
|
533
|
+
|--------|------|----------|
|
|
534
|
+
| select | 点击菜单项时触发 | item |
|
|
535
|
+
| command | 点击菜单项时触发(传 command) | command, item |
|
|
536
|
+
| open | 菜单打开时触发 | - |
|
|
537
|
+
| close | 菜单关闭时触发 | - |
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
### Card 卡片
|
|
542
|
+
|
|
543
|
+
将信息聚合在卡片容器中展示。
|
|
544
|
+
|
|
545
|
+
#### 基础用法
|
|
546
|
+
|
|
547
|
+
```vue
|
|
548
|
+
<template>
|
|
549
|
+
<XpCard title="卡片标题">
|
|
550
|
+
<p>这是卡片内容</p>
|
|
551
|
+
</XpCard>
|
|
552
|
+
|
|
553
|
+
<XpCard title="卡片标题">
|
|
554
|
+
<p>卡片内容区域</p>
|
|
555
|
+
<template #footer>
|
|
556
|
+
<div style="display:flex;justify-content:flex-end;gap:8px">
|
|
557
|
+
<XpButton size="small">取消</XpButton>
|
|
558
|
+
<XpButton size="small" type="primary">确定</XpButton>
|
|
559
|
+
</div>
|
|
560
|
+
</template>
|
|
561
|
+
</XpCard>
|
|
562
|
+
|
|
563
|
+
<XpCard title="卡片标题" shadow="hover">
|
|
564
|
+
<p>悬停出现阴影</p>
|
|
565
|
+
</XpCard>
|
|
566
|
+
</template>
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
##### Props
|
|
570
|
+
|
|
571
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
572
|
+
|------|------|--------|------|
|
|
573
|
+
| title | string | '' | 卡片标题 |
|
|
574
|
+
| shadow | string | always | 阴影效果:always / hover / never |
|
|
575
|
+
| bordered | boolean | true | 是否显示边框 |
|
|
576
|
+
| hover | boolean | false | 是否 hover 时上移 |
|
|
577
|
+
|
|
578
|
+
##### Slots
|
|
579
|
+
|
|
580
|
+
| 插槽名 | 说明 |
|
|
581
|
+
|--------|------|
|
|
582
|
+
| header | 自定义头部内容 |
|
|
583
|
+
| default | 卡片主体内容 |
|
|
584
|
+
| footer | 底部内容 |
|
|
585
|
+
| extra | 头部右侧内容 |
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
### Tabs 标签页
|
|
590
|
+
|
|
591
|
+
分隔内容上有关联但属于不同类别的数据集合。
|
|
592
|
+
|
|
593
|
+
#### 基础用法
|
|
594
|
+
|
|
595
|
+
```vue
|
|
596
|
+
<template>
|
|
597
|
+
<XpTabs v-model="active">
|
|
598
|
+
<XpTabPane name="tab1" title="选项一">
|
|
599
|
+
<p>这是选项一的内容。</p>
|
|
600
|
+
</XpTabPane>
|
|
601
|
+
<XpTabPane name="tab2" title="选项二">
|
|
602
|
+
<p>这是选项二的内容。</p>
|
|
603
|
+
</XpTabPane>
|
|
604
|
+
<XpTabPane name="tab3" title="选项三">
|
|
605
|
+
<p>这是选项三的内容。</p>
|
|
606
|
+
</XpTabPane>
|
|
607
|
+
</XpTabs>
|
|
608
|
+
</template>
|
|
609
|
+
|
|
610
|
+
<script setup>
|
|
611
|
+
import { ref } from 'vue'
|
|
612
|
+
const active = ref('tab1')
|
|
613
|
+
</script>
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
##### Tabs Props
|
|
617
|
+
|
|
618
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
619
|
+
|------|------|--------|------|
|
|
620
|
+
| modelValue | string / number | null | 当前激活的 name,支持 v-model |
|
|
621
|
+
|
|
622
|
+
##### TabPane Props
|
|
623
|
+
|
|
624
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
625
|
+
|------|------|--------|------|
|
|
626
|
+
| name | string / number | - | 必填,唯一标识 |
|
|
627
|
+
| title | string | '' | 标签标题 |
|
|
628
|
+
| disabled | boolean | false | 是否禁用 |
|
|
629
|
+
|
|
630
|
+
##### Tabs Events
|
|
631
|
+
|
|
632
|
+
| 事件名 | 说明 | 回调参数 |
|
|
633
|
+
|--------|------|----------|
|
|
634
|
+
| update:modelValue | 切换时触发 | name |
|
|
635
|
+
| change | 切换时触发 | name |
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
### Dialog 对话框
|
|
640
|
+
|
|
641
|
+
在保留当前页面状态的情况下,告知用户并承载相关操作。
|
|
642
|
+
|
|
643
|
+
#### 基础用法
|
|
644
|
+
|
|
645
|
+
```vue
|
|
646
|
+
<template>
|
|
647
|
+
<XpButton type="primary" @click="visible = true">打开对话框</XpButton>
|
|
648
|
+
<XpDialog
|
|
649
|
+
v-model:visible="visible"
|
|
650
|
+
title="提示"
|
|
651
|
+
@confirm="handleConfirm"
|
|
652
|
+
@cancel="handleCancel"
|
|
653
|
+
>
|
|
654
|
+
<p>这是一段弹窗内容</p>
|
|
655
|
+
</XpDialog>
|
|
656
|
+
</template>
|
|
657
|
+
|
|
658
|
+
<script setup>
|
|
659
|
+
import { ref } from 'vue'
|
|
660
|
+
const visible = ref(false)
|
|
661
|
+
const handleConfirm = () => { visible.value = false }
|
|
662
|
+
const handleCancel = () => { visible.value = false }
|
|
663
|
+
</script>
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
#### 自定义宽度
|
|
667
|
+
|
|
668
|
+
```vue
|
|
669
|
+
<template>
|
|
670
|
+
<XpDialog
|
|
671
|
+
v-model:visible="visible"
|
|
672
|
+
title="宽弹窗"
|
|
673
|
+
width="700px"
|
|
674
|
+
>
|
|
675
|
+
<p>弹窗内容</p>
|
|
676
|
+
</XpDialog>
|
|
677
|
+
</template>
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
#### 自定义按钮文字
|
|
681
|
+
|
|
682
|
+
```vue
|
|
683
|
+
<template>
|
|
684
|
+
<XpDialog
|
|
685
|
+
v-model:visible="visible"
|
|
686
|
+
title="确认删除"
|
|
687
|
+
confirm-button-text="删除"
|
|
688
|
+
cancel-button-text="我再想想"
|
|
689
|
+
>
|
|
690
|
+
<p>确定要删除这条记录吗?</p>
|
|
691
|
+
</XpDialog>
|
|
692
|
+
</template>
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
##### Props
|
|
696
|
+
|
|
697
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
698
|
+
|------|------|--------|------|
|
|
699
|
+
| visible | boolean | false | 是否显示,支持 v-model |
|
|
700
|
+
| title | string | '' | 弹窗标题 |
|
|
701
|
+
| width | string | 500px | 弹窗宽度 |
|
|
702
|
+
| confirmButtonText | string | 确定 | 确认按钮文字 |
|
|
703
|
+
| cancelButtonText | string | 取消 | 取消按钮文字 |
|
|
704
|
+
| closeOnClickModal | boolean | true | 点击遮罩层是否关闭弹窗 |
|
|
705
|
+
| showDefaultFooter | boolean | true | 是否显示默认底部按钮 |
|
|
706
|
+
|
|
707
|
+
##### Events
|
|
708
|
+
|
|
709
|
+
| 事件名 | 说明 | 回调参数 |
|
|
710
|
+
|--------|------|----------|
|
|
711
|
+
| confirm | 点击确认按钮时触发 | - |
|
|
712
|
+
| cancel | 点击取消按钮时触发 | - |
|
|
713
|
+
| close | 关闭弹窗时触发 | - |
|
|
714
|
+
| update:visible | 可见性改变时触发 | visible |
|
|
715
|
+
|
|
716
|
+
##### Slots
|
|
717
|
+
|
|
718
|
+
| 插槽名 | 说明 |
|
|
719
|
+
|--------|------|
|
|
720
|
+
| default | 弹窗主体内容 |
|
|
721
|
+
| footer | 自定义底部按钮区域 |
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
725
|
+
## 主题定制
|
|
726
|
+
|
|
727
|
+
Xp UI 内置完整的 **浅色 / 暗黑双主题** 系统,并支持 **可视化颜色定制**、**配置导入导出**,可在任意项目中按需使用。
|
|
728
|
+
|
|
729
|
+
### 主题色(Design Tokens)
|
|
730
|
+
|
|
731
|
+
组件库的所有颜色都通过 **CSS 变量** 控制,你可以在浏览器开发者工具中实时查看和调试:
|
|
732
|
+
|
|
733
|
+
| 变量名 | 说明 |
|
|
734
|
+
|--------|------|
|
|
735
|
+
| `--xp-color-primary` | 主色(品牌色) |
|
|
736
|
+
| `--xp-color-success` | 成功色 |
|
|
737
|
+
| `--xp-color-warning` | 警告色 |
|
|
738
|
+
| `--xp-color-danger` | 危险色 |
|
|
739
|
+
| `--xp-color-info` | 信息色 |
|
|
740
|
+
| `--xp-text-color-primary` | 主要文字色 |
|
|
741
|
+
| `--xp-text-color-regular` | 常规文字色 |
|
|
742
|
+
| `--xp-border-color` | 边框色 |
|
|
743
|
+
| `--xp-bg-color` | 背景色 |
|
|
744
|
+
| `--xp-fill-color` | 填充色 |
|
|
745
|
+
| `--xp-shadow-sm` / `--xp-shadow-md` / `--xp-shadow-lg` | 阴影 |
|
|
746
|
+
|
|
747
|
+
> 每个主题色还自动派生出 `-light`(30% 浅色)、`-dark`(20% 深色)、`-bg`(背景色)、`-border`(边框色),无需手动配置。
|
|
748
|
+
|
|
749
|
+
### 浅色 / 暗黑模式切换
|
|
750
|
+
|
|
751
|
+
在入口文件中调用 `initTheme()` 即可自动初始化主题(读取 localStorage 或跟随系统偏好):
|
|
752
|
+
|
|
753
|
+
```js
|
|
754
|
+
import { useTheme } from '@cghbcf/xp-ui'
|
|
755
|
+
|
|
756
|
+
const { initTheme, toggleTheme, setTheme, theme } = useTheme()
|
|
757
|
+
|
|
758
|
+
// 1. 页面加载时初始化主题(读取 localStorage)
|
|
759
|
+
initTheme()
|
|
760
|
+
|
|
761
|
+
// 2. 切换主题按钮
|
|
762
|
+
const handleToggle = () => toggleTheme()
|
|
763
|
+
|
|
764
|
+
// 3. 强制切换到指定主题
|
|
765
|
+
setTheme('dark') // 或 'light'
|
|
766
|
+
|
|
767
|
+
// 4. 响应式读取当前主题
|
|
768
|
+
console.log(theme.value) // 'light' | 'dark'
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
Vue 组件中的示例用法:
|
|
772
|
+
|
|
773
|
+
```vue
|
|
774
|
+
<template>
|
|
775
|
+
<button @click="toggleTheme">
|
|
776
|
+
当前主题:{{ theme === 'dark' ? '🌙 暗黑' : '☀️ 浅色' }}
|
|
777
|
+
</button>
|
|
778
|
+
</template>
|
|
779
|
+
|
|
780
|
+
<script setup>
|
|
781
|
+
import { useTheme } from '@cghbcf/xp-ui'
|
|
782
|
+
const { theme, toggleTheme, initTheme } = useTheme()
|
|
783
|
+
initTheme() // 在页面挂载时调用
|
|
784
|
+
</script>
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### 自定义主题色(applyThemeConfig)
|
|
788
|
+
|
|
789
|
+
通过 `applyThemeConfig` 可以一次性替换所有颜色变量,支持:
|
|
790
|
+
- 修改主色系(primary / success / warning / danger / info)
|
|
791
|
+
- 分别定制浅色和暗黑两套文本、边框、背景、填充、阴影
|
|
792
|
+
|
|
793
|
+
```js
|
|
794
|
+
import { applyThemeConfig } from '@cghbcf/xp-ui'
|
|
795
|
+
|
|
796
|
+
// 修改主色为绿色 —— 只需一个颜色值,其他衍生色自动生成
|
|
797
|
+
applyThemeConfig({
|
|
798
|
+
primary: {
|
|
799
|
+
primary: '#22c55e', // 绿色主色
|
|
800
|
+
success: '#67c23a',
|
|
801
|
+
warning: '#e6a23c',
|
|
802
|
+
danger: '#f56c6c',
|
|
803
|
+
info: '#909399'
|
|
804
|
+
}
|
|
805
|
+
})
|
|
806
|
+
|
|
807
|
+
// 完整配置:浅色 + 暗黑各一套
|
|
808
|
+
applyThemeConfig({
|
|
809
|
+
primary: {
|
|
810
|
+
primary: '#22c55e',
|
|
811
|
+
success: '#67c23a',
|
|
812
|
+
warning: '#e6a23c',
|
|
813
|
+
danger: '#f56c6c',
|
|
814
|
+
info: '#909399'
|
|
815
|
+
},
|
|
816
|
+
light: {
|
|
817
|
+
text: { primary: '#303133', regular: '#606266', secondary: '#909399', placeholder: '#c0c4cc' },
|
|
818
|
+
border: { base: '#dcdfe6', light: '#ebeef5', lighter: '#f2f6fc' },
|
|
819
|
+
bg: { base: '#ffffff', page: '#f2f3f5', soft: '#f5f7fa', overlay: 'rgba(0, 0, 0, 0.5)' },
|
|
820
|
+
fill: { base: '#f0f2f5', light: '#f5f7fa', lighter: '#fafafa' },
|
|
821
|
+
shadow: { sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', md: '0 2px 12px 0 rgba(0, 0, 0, 0.1)', lg: '0 4px 20px 0 rgba(0, 0, 0, 0.15)', overlay: '0 8px 24px 0 rgba(0, 0, 0, 0.2)' }
|
|
822
|
+
},
|
|
823
|
+
dark: {
|
|
824
|
+
text: { primary: '#e5eaf3', regular: '#cfd3dc', secondary: '#a3a6ad', placeholder: '#8d9095' },
|
|
825
|
+
border: { base: '#4c4d4f', light: '#414243', lighter: '#363637' },
|
|
826
|
+
bg: { base: '#1d1e1f', page: '#141414', soft: '#2a2b2c', overlay: 'rgba(0, 0, 0, 0.7)' },
|
|
827
|
+
fill: { base: '#303030', light: '#262727', lighter: '#1d1d1d' },
|
|
828
|
+
shadow: { sm: '0 1px 2px 0 rgba(0, 0, 0, 0.4)', md: '0 2px 12px 0 rgba(0, 0, 0, 0.45)', lg: '0 4px 20px 0 rgba(0, 0, 0, 0.5)', overlay: '0 8px 24px 0 rgba(0, 0, 0, 0.6)' }
|
|
829
|
+
}
|
|
830
|
+
})
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
> 注意:`applyThemeConfig` 会自动做**深合并**——你只需传入要修改的部分,未传的部分保持默认。
|
|
834
|
+
|
|
835
|
+
### 导出主题配置(buildCssString)
|
|
836
|
+
|
|
837
|
+
可以将当前的主题配置导出为完整的 CSS 文件,放到其他项目(非 Vue 项目也可使用):
|
|
838
|
+
|
|
839
|
+
```js
|
|
840
|
+
import { buildCssString, applyThemeConfig, getDefaultThemeConfig } from '@cghbcf/xp-ui'
|
|
841
|
+
|
|
842
|
+
// 1. 先应用你的自定义主题
|
|
843
|
+
applyThemeConfig({ primary: { primary: '#22c55e' } })
|
|
844
|
+
|
|
845
|
+
// 2. 生成 CSS(包含 :root 和 [data-theme="dark"] 两套规则)
|
|
846
|
+
const css = buildCssString({
|
|
847
|
+
primary: { primary: '#22c55e' },
|
|
848
|
+
light: { text: { primary: '#303133' } },
|
|
849
|
+
dark: { text: { primary: '#e5eaf3' } }
|
|
850
|
+
})
|
|
851
|
+
|
|
852
|
+
// 3. 写入文件(Node / Vite 构建时使用)
|
|
853
|
+
// fs.writeFileSync('dist/xp-ui-theme.css', css)
|
|
854
|
+
console.log(css)
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
也可以直接读取 `themeConfig` 响应式对象:
|
|
858
|
+
|
|
859
|
+
```js
|
|
860
|
+
const { themeConfig } = useTheme()
|
|
861
|
+
console.log(JSON.stringify(themeConfig.value, null, 2))
|
|
862
|
+
// 输出完整的主题配置,供导入/导出
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
### 导出 JSON 配置文件
|
|
866
|
+
|
|
867
|
+
导出 JSON 后可以保存到项目配置文件中,下次启动时重新导入:
|
|
868
|
+
|
|
869
|
+
```js
|
|
870
|
+
import { useTheme } from '@cghbcf/xp-ui'
|
|
871
|
+
|
|
872
|
+
const { themeConfig, applyThemeConfig, resetThemeConfig } = useTheme()
|
|
873
|
+
|
|
874
|
+
// 导出
|
|
875
|
+
const json = JSON.stringify(themeConfig.value, null, 2)
|
|
876
|
+
// 可以保存到 localStorage 或上传到服务器
|
|
877
|
+
|
|
878
|
+
// 导入(从文件 / localStorage / API 读取)
|
|
879
|
+
applyThemeConfig(JSON.parse(json))
|
|
880
|
+
|
|
881
|
+
// 恢复默认
|
|
882
|
+
resetThemeConfig()
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
### 主题 API 汇总
|
|
886
|
+
|
|
887
|
+
```js
|
|
888
|
+
import { useTheme } from '@cghbcf/xp-ui'
|
|
889
|
+
|
|
890
|
+
const {
|
|
891
|
+
theme, // 响应式 ref: 当前主题 ('light' | 'dark')
|
|
892
|
+
themeConfig, // 响应式 ref: 完整主题配置对象
|
|
893
|
+
setTheme, // 设置主题: setTheme('dark' | 'light')
|
|
894
|
+
toggleTheme, // 在 light/dark 之间切换
|
|
895
|
+
initTheme, // 初始化:读取 localStorage + 跟随系统偏好
|
|
896
|
+
applyThemeConfig, // 应用自定义主题配置(CSS 变量会立即更新)
|
|
897
|
+
resetThemeConfig, // 恢复默认配置
|
|
898
|
+
getDefaultThemeConfig, // 获取默认配置对象
|
|
899
|
+
buildCssString, // 根据配置生成 CSS 字符串
|
|
900
|
+
buildCssVars // 根据配置生成 { '--xp-color-xxx': value } 映射
|
|
901
|
+
} = useTheme()
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
### 主题持久化
|
|
905
|
+
|
|
906
|
+
`initTheme()` 和 `applyThemeConfig()` 都会自动将设置写入 `localStorage`(键名 `xp-ui-theme` 和 `xp-ui-theme-config`),下次访问时自动恢复,无需额外处理。
|
|
907
|
+
|
|
908
|
+
---
|
|
909
|
+
|
|
910
|
+
## 浏览器支持
|
|
911
|
+
|
|
912
|
+
支持所有现代浏览器:
|
|
913
|
+
|
|
914
|
+
- Chrome(推荐)
|
|
915
|
+
- Firefox
|
|
916
|
+
- Safari
|
|
917
|
+
- Edge
|
|
918
|
+
|
|
919
|
+
---
|
|
920
|
+
|
|
921
|
+
## License
|
|
922
|
+
|
|
923
|
+
MIT
|