lvc-ui 0.1.0 → 0.1.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 +1232 -159
- package/dist/lvc-ui.js +7160 -0
- package/dist/lvc-ui.min.js +21 -0
- package/dist/odometer-theme-minimal.css +81 -0
- package/dist/odometer.min.js +2 -0
- package/package.json +53 -46
- package/LICENSE +0 -21
- package/dist/index.d.ts +0 -86
- package/dist/lvc-ui.css +0 -1
- package/dist/lvc-ui.esm.js +0 -3477
- package/dist/lvc-ui.umd.js +0 -619
package/README.md
CHANGED
|
@@ -1,159 +1,1232 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
|
141
|
-
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
1
|
+
# LvcUI
|
|
2
|
+
|
|
3
|
+
> LVC 工具库 — Vue 2.x 组件 + 工具集合(UMD 单文件打包)
|
|
4
|
+
|
|
5
|
+
一个面向大屏 / 可视化 / 后台管理场景的 Vue 2.x 组件与工具库,全部组件和工具打包为单个 UMD 文件,一次引入即可使用。
|
|
6
|
+
|
|
7
|
+
## 目录
|
|
8
|
+
|
|
9
|
+
- [安装](#安装)
|
|
10
|
+
- [快速开始](#快速开始)
|
|
11
|
+
- [组件](#组件)
|
|
12
|
+
- [lvc-button 按钮组件](#lvc-button-按钮组件)
|
|
13
|
+
- [lvc-switch 开关组件](#lvc-switch-开关组件)
|
|
14
|
+
- [lvc-odometer 数字滚动组件](#lvc-odometer-数字滚动组件)
|
|
15
|
+
- [lvc-load-more 滚动加载更多](#lvc-load-more-滚动加载更多)
|
|
16
|
+
- [lvc-select 下拉选择](#lvc-select-下拉选择)
|
|
17
|
+
- [lvc-table 表格](#lvc-table-表格)
|
|
18
|
+
- [lvc-date-picker 日期选择器](#lvc-date-picker-日期选择器)
|
|
19
|
+
- [lvc-time-picker 时间选择器](#lvc-time-picker-时间选择器)
|
|
20
|
+
- [lvc-year-picker 年份选择器](#lvc-year-picker-年份选择器)
|
|
21
|
+
- [lvc-month-picker 月份选择器](#lvc-month-picker-月份选择器)
|
|
22
|
+
- [lvc-tree 树形控件](#lvc-tree-树形控件)
|
|
23
|
+
- [lvc-dialog 对话框](#lvc-dialog-对话框)
|
|
24
|
+
- [工具](#工具)
|
|
25
|
+
- [Bus 跨窗口通讯总线](#bus-跨窗口通讯总线)
|
|
26
|
+
- [createFetch HTTP 请求封装](#createfetch-http-请求封装)
|
|
27
|
+
- [createRouter Hash 路由](#createrouter-hash-路由)
|
|
28
|
+
- [SocketClient WebSocket 客户端](#socketclient-websocket-客户端)
|
|
29
|
+
- [CanvasTopologyUtils Canvas 拓扑工具](#canvastopologyutils-canvas-拓扑工具)
|
|
30
|
+
- [px2EchartsUrils ECharts 像素适配](#px2echartsurils-echarts-像素适配)
|
|
31
|
+
- [LvcLoading 全局 Loading](#lvcloading-全局-loading)
|
|
32
|
+
- [LvcMessage 全局消息提示](#lvcmessage-全局消息提示)
|
|
33
|
+
- [lvcDialog 命令式对话框](#lvcdialog-命令式对话框)
|
|
34
|
+
- [按需引入](#按需引入)
|
|
35
|
+
- [外部依赖](#外部依赖)
|
|
36
|
+
- [构建](#构建)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 安装
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install lvc-ui
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**peerDependencies**: 需要项目已安装 Vue 2.6+ / 2.7。
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 快速开始
|
|
51
|
+
|
|
52
|
+
### ES Module(推荐)
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
import Vue from 'vue';
|
|
56
|
+
import LvcUI from 'lvc-ui';
|
|
57
|
+
|
|
58
|
+
Vue.use(LvcUI);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### CommonJS
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
const Vue = require('vue');
|
|
65
|
+
const LvcUI = require('lvc-ui');
|
|
66
|
+
|
|
67
|
+
Vue.use(LvcUI);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 浏览器 `<script>` 引入
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<!-- 必须先引入 Vue -->
|
|
74
|
+
<script src="https://unpkg.com/vue@2.7.16/dist/vue.js"></script>
|
|
75
|
+
<!-- 引入 LvcUI(压缩版) -->
|
|
76
|
+
<script src="https://unpkg.com/lvc-ui/dist/lvc-ui.min.js"></script>
|
|
77
|
+
<!-- window.Vue 存在时会自动注册所有组件,window.LvcUI 可用 -->
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
注册后即可在模板中使用所有 `lvc-*` 组件:
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<template>
|
|
84
|
+
<lvc-button type="primary" @click="onClick">点击</lvc-button>
|
|
85
|
+
<lvc-select v-model="val" :options="opts" />
|
|
86
|
+
</template>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 组件
|
|
92
|
+
|
|
93
|
+
### lvc-button 按钮组件
|
|
94
|
+
|
|
95
|
+
基础按钮,支持多种类型、朴素/圆角/圆形、加载状态、禁用、图标。
|
|
96
|
+
|
|
97
|
+
#### Props
|
|
98
|
+
|
|
99
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
100
|
+
|------|------|--------|------|
|
|
101
|
+
| type | String | `"default"` | 类型:`primary` / `success` / `warning` / `danger` / `info` / `default` |
|
|
102
|
+
| plain | Boolean | `false` | 朴素按钮(透明背景) |
|
|
103
|
+
| round | Boolean | `false` | 圆角按钮 |
|
|
104
|
+
| circle | Boolean | `false` | 圆形按钮 |
|
|
105
|
+
| disabled | Boolean | `false` | 禁用 |
|
|
106
|
+
| loading | Boolean | `false` | 加载中(显示旋转图标,禁用点击) |
|
|
107
|
+
| icon | String | `""` | 图标类名 |
|
|
108
|
+
|
|
109
|
+
#### Events
|
|
110
|
+
|
|
111
|
+
| 事件名 | 参数 | 说明 |
|
|
112
|
+
|--------|------|------|
|
|
113
|
+
| click | `event: Event` | 点击时触发(disabled/loading 时不触发) |
|
|
114
|
+
|
|
115
|
+
#### Slots
|
|
116
|
+
|
|
117
|
+
| 插槽 | 说明 |
|
|
118
|
+
|------|------|
|
|
119
|
+
| default | 按钮文本 |
|
|
120
|
+
|
|
121
|
+
#### 示例
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<lvc-button type="primary">主要按钮</lvc-button>
|
|
125
|
+
<lvc-button type="success" plain>朴素成功</lvc-button>
|
|
126
|
+
<lvc-button type="danger" round>圆角危险</lvc-button>
|
|
127
|
+
<lvc-button type="primary" loading>加载中</lvc-button>
|
|
128
|
+
<lvc-button type="info" disabled>禁用</lvc-button>
|
|
129
|
+
<lvc-button type="primary" icon="lvc-icon-edit">编辑</lvc-button>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### lvc-switch 开关组件
|
|
135
|
+
|
|
136
|
+
开关选择器,支持自定义颜色、尺寸、禁用。
|
|
137
|
+
|
|
138
|
+
#### Props
|
|
139
|
+
|
|
140
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
141
|
+
|------|------|--------|------|
|
|
142
|
+
| value | Boolean | `false` | 状态(v-model) |
|
|
143
|
+
| disabled | Boolean | `false` | 禁用 |
|
|
144
|
+
| width | Number | `34` | 宽度(px) |
|
|
145
|
+
| height | Number | `18` | 高度(px) |
|
|
146
|
+
| activeColor | String | `"#42A3D6"` | 激活背景色 |
|
|
147
|
+
| inactiveColor | String | `"#395E7C"` | 未激活背景色 |
|
|
148
|
+
| dotColor | String | `"#ffffff"` | 圆点颜色 |
|
|
149
|
+
|
|
150
|
+
#### Events
|
|
151
|
+
|
|
152
|
+
| 事件名 | 参数 | 说明 |
|
|
153
|
+
|--------|------|------|
|
|
154
|
+
| input | `value: Boolean` | v-model 同步 |
|
|
155
|
+
| change | `value: Boolean` | 状态变化 |
|
|
156
|
+
|
|
157
|
+
#### 示例
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<lvc-switch v-model="isOpen" />
|
|
161
|
+
|
|
162
|
+
<lvc-switch
|
|
163
|
+
v-model="enabled"
|
|
164
|
+
:active-color="'#00e5ff'"
|
|
165
|
+
:inactive-color="'#333'"
|
|
166
|
+
:width="40"
|
|
167
|
+
:height="22"
|
|
168
|
+
/>
|
|
169
|
+
|
|
170
|
+
<lvc-switch v-model="locked" disabled />
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### lvc-odometer 数字滚动组件
|
|
176
|
+
|
|
177
|
+
数字滚动动画组件,依赖外部 `Odometer` 库。
|
|
178
|
+
|
|
179
|
+
#### Props
|
|
180
|
+
|
|
181
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
182
|
+
|------|------|--------|------|
|
|
183
|
+
| value | Number | `0` | 当前数值(变化时触发滚动动画) |
|
|
184
|
+
| duration | Number | `1000` | 动画时长(ms) |
|
|
185
|
+
| maxAnimations | Number | `Infinity` | 最大动画次数 |
|
|
186
|
+
| unit | String | `""` | 单位文本 |
|
|
187
|
+
| unitSize | String | `"inherit"` | 单位字号 |
|
|
188
|
+
| unitPosition | String | `"right"` | 单位位置:`left` / `right` |
|
|
189
|
+
|
|
190
|
+
#### Slots
|
|
191
|
+
|
|
192
|
+
| 插槽 | 说明 |
|
|
193
|
+
|------|------|
|
|
194
|
+
| unit-left | 左侧单位(覆盖 prop) |
|
|
195
|
+
| unit-right | 右侧单位(覆盖 prop) |
|
|
196
|
+
|
|
197
|
+
#### 示例
|
|
198
|
+
|
|
199
|
+
```html
|
|
200
|
+
<!-- 需先引入 odometer 库(dist 目录已提供) -->
|
|
201
|
+
<link rel="stylesheet" href="./dist/odometer-theme-minimal.css" />
|
|
202
|
+
<script src="./dist/odometer.min.js"></script>
|
|
203
|
+
|
|
204
|
+
<lvc-odometer :value="count" :duration="1500" unit="kWh" unit-position="right" />
|
|
205
|
+
|
|
206
|
+
<lvc-odometer :value="price">
|
|
207
|
+
<template #unit-left><span style="color:#ffd700">$</span></template>
|
|
208
|
+
</lvc-odometer>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### lvc-load-more 滚动加载更多
|
|
214
|
+
|
|
215
|
+
基于 `IntersectionObserver` 的触底加载组件。
|
|
216
|
+
|
|
217
|
+
#### Props
|
|
218
|
+
|
|
219
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
220
|
+
|------|------|--------|------|
|
|
221
|
+
| loading | Boolean | `false` | 是否正在加载 |
|
|
222
|
+
| finished | Boolean | `false` | 是否已加载完毕 |
|
|
223
|
+
| distance | String | `"0px"` | 触发距离(rootMargin 底部) |
|
|
224
|
+
| container | String | `""` | 滚动容器选择器(空=视口) |
|
|
225
|
+
| loadingText | String | `"正在加载更多..."` | 加载中文本 |
|
|
226
|
+
| finishedText | String | `"没有更多数据了"` | 完成文本 |
|
|
227
|
+
|
|
228
|
+
#### Events
|
|
229
|
+
|
|
230
|
+
| 事件名 | 参数 | 说明 |
|
|
231
|
+
|--------|------|------|
|
|
232
|
+
| load | 无 | 触底且非 loading/finished 时触发 |
|
|
233
|
+
|
|
234
|
+
#### 示例
|
|
235
|
+
|
|
236
|
+
```html
|
|
237
|
+
<div class="list-container" style="height:400px;overflow-y:auto;">
|
|
238
|
+
<div v-for="item in list" :key="item.id">{{ item.name }}</div>
|
|
239
|
+
<lvc-load-more
|
|
240
|
+
:loading="loading"
|
|
241
|
+
:finished="finished"
|
|
242
|
+
container=".list-container"
|
|
243
|
+
@load="loadMore"
|
|
244
|
+
/>
|
|
245
|
+
</div>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```js
|
|
249
|
+
export default {
|
|
250
|
+
data() {
|
|
251
|
+
return { list: [], loading: false, finished: false, page: 1 };
|
|
252
|
+
},
|
|
253
|
+
methods: {
|
|
254
|
+
async loadMore() {
|
|
255
|
+
this.loading = true;
|
|
256
|
+
const data = await fetch(`/api/list?page=${this.page++}`).then(r => r.json());
|
|
257
|
+
this.list.push(...data);
|
|
258
|
+
this.loading = false;
|
|
259
|
+
if (data.length < 10) this.finished = true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### lvc-select 下拉选择
|
|
268
|
+
|
|
269
|
+
下拉选择器,支持清除、禁用项、iframe 跨窗口点击关闭。
|
|
270
|
+
|
|
271
|
+
#### Props
|
|
272
|
+
|
|
273
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
274
|
+
|------|------|--------|------|
|
|
275
|
+
| value | String \| Number | `""` | 当前值(v-model) |
|
|
276
|
+
| options | Array | `[]` | 选项数组 `{ label, value, disabled? }` |
|
|
277
|
+
| placeholder | String | `"请选择"` | 占位文本 |
|
|
278
|
+
| clearable | Boolean | `true` | 可清除 |
|
|
279
|
+
|
|
280
|
+
#### Events
|
|
281
|
+
|
|
282
|
+
| 事件名 | 参数 | 说明 |
|
|
283
|
+
|--------|------|------|
|
|
284
|
+
| input | `option: Object` \| `""` | v-model 同步(清除时为 `""`) |
|
|
285
|
+
| change | `option: Object` \| `""` | 值变化 |
|
|
286
|
+
| clear | 无 | 清除时触发 |
|
|
287
|
+
|
|
288
|
+
#### 示例
|
|
289
|
+
|
|
290
|
+
```html
|
|
291
|
+
<lvc-select v-model="selected" :options="opts" placeholder="请选择" clearable />
|
|
292
|
+
|
|
293
|
+
<script>
|
|
294
|
+
export default {
|
|
295
|
+
data() {
|
|
296
|
+
return {
|
|
297
|
+
selected: '',
|
|
298
|
+
opts: [
|
|
299
|
+
{ label: '选项一', value: '1' },
|
|
300
|
+
{ label: '选项二', value: '2' },
|
|
301
|
+
{ label: '禁用项', value: '3', disabled: true }
|
|
302
|
+
]
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
</script>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### lvc-table 表格
|
|
312
|
+
|
|
313
|
+
数据表格,支持斑马纹、选择列、列排序、自定义单元格(作用域插槽)。
|
|
314
|
+
|
|
315
|
+
#### Props
|
|
316
|
+
|
|
317
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
318
|
+
|------|------|--------|------|
|
|
319
|
+
| data | Array | `[]` | 行数据 |
|
|
320
|
+
| columns | Array | `[]` | 列配置 |
|
|
321
|
+
| stripe | Boolean | `true` | 斑马纹 |
|
|
322
|
+
| selection | Boolean | `false` | 显示选择列 |
|
|
323
|
+
|
|
324
|
+
#### columns 配置
|
|
325
|
+
|
|
326
|
+
| 字段 | 类型 | 说明 |
|
|
327
|
+
|------|------|------|
|
|
328
|
+
| label | String | 列标题 |
|
|
329
|
+
| prop | String | 数据字段名 |
|
|
330
|
+
| width | String\|Number | 列宽 |
|
|
331
|
+
| align | String | 对齐:`left` / `center` / `right` |
|
|
332
|
+
| sortable | Boolean | 可排序 |
|
|
333
|
+
|
|
334
|
+
#### Events
|
|
335
|
+
|
|
336
|
+
| 事件名 | 参数 | 说明 |
|
|
337
|
+
|--------|------|------|
|
|
338
|
+
| selection-change | `rows: Array` | 选择变化 |
|
|
339
|
+
| sort-change | `{ prop, order }` | 排序变化(`order`: `asc`/`desc`/`""`) |
|
|
340
|
+
|
|
341
|
+
#### Scoped Slots
|
|
342
|
+
|
|
343
|
+
| 插槽名 | 作用域 | 用途 |
|
|
344
|
+
|--------|--------|------|
|
|
345
|
+
| `header-{prop}` | `{ column }` | 自定义表头 |
|
|
346
|
+
| `{prop}` | `{ row, index }` | 自定义单元格 |
|
|
347
|
+
|
|
348
|
+
#### 示例
|
|
349
|
+
|
|
350
|
+
```html
|
|
351
|
+
<lvc-table
|
|
352
|
+
:data="tableData"
|
|
353
|
+
:columns="columns"
|
|
354
|
+
selection
|
|
355
|
+
@selection-change="onSel"
|
|
356
|
+
@sort-change="onSort"
|
|
357
|
+
>
|
|
358
|
+
<template #status="{ row }">
|
|
359
|
+
<span :style="{ color: row.status === '在线' ? '#0f0' : '#f00' }">{{ row.status }}</span>
|
|
360
|
+
</template>
|
|
361
|
+
</lvc-table>
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
```js
|
|
365
|
+
export default {
|
|
366
|
+
data() {
|
|
367
|
+
return {
|
|
368
|
+
tableData: [
|
|
369
|
+
{ id: 1, name: '设备A', status: '在线' },
|
|
370
|
+
{ id: 2, name: '设备B', status: '离线' }
|
|
371
|
+
],
|
|
372
|
+
columns: [
|
|
373
|
+
{ label: 'ID', prop: 'id', sortable: true, width: '80' },
|
|
374
|
+
{ label: '名称', prop: 'name' },
|
|
375
|
+
{ label: '状态', prop: 'status', align: 'center' }
|
|
376
|
+
]
|
|
377
|
+
};
|
|
378
|
+
},
|
|
379
|
+
methods: {
|
|
380
|
+
onSel(rows) { console.log('选中:', rows); },
|
|
381
|
+
onSort({ prop, order }) { console.log('排序:', prop, order); }
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
### lvc-date-picker 日期选择器
|
|
389
|
+
|
|
390
|
+
日期/日期时间/范围选择器,支持单面板/双面板、时间选择、范围 hover 预览。
|
|
391
|
+
|
|
392
|
+
#### Props
|
|
393
|
+
|
|
394
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
395
|
+
|------|------|--------|------|
|
|
396
|
+
| value | String \| Array | `""` | 当前值(范围模式为数组) |
|
|
397
|
+
| type | String | `"date"` | 类型,见下 |
|
|
398
|
+
| rangeSeparator | String | `"至"` | 范围分隔符 |
|
|
399
|
+
| singlePanel | Boolean | `false` | 范围模式单面板 |
|
|
400
|
+
|
|
401
|
+
#### type 取值
|
|
402
|
+
|
|
403
|
+
| type | 说明 |
|
|
404
|
+
|------|------|
|
|
405
|
+
| `date` | 单日期 |
|
|
406
|
+
| `datetime` | 单日期+时间 |
|
|
407
|
+
| `daterange` | 日期范围 |
|
|
408
|
+
| `datetimerange` | 日期时间范围 |
|
|
409
|
+
| `datetimestartorend` | 同一天起止时间 |
|
|
410
|
+
|
|
411
|
+
#### Events
|
|
412
|
+
|
|
413
|
+
| 事件名 | 参数 | 说明 |
|
|
414
|
+
|--------|------|------|
|
|
415
|
+
| input | `value` | v-model 同步 |
|
|
416
|
+
| confirm | `value` | 点「确定」时触发 |
|
|
417
|
+
|
|
418
|
+
#### 示例
|
|
419
|
+
|
|
420
|
+
```html
|
|
421
|
+
<!-- 单日期 -->
|
|
422
|
+
<lvc-date-picker v-model="date" type="date" />
|
|
423
|
+
|
|
424
|
+
<!-- 日期时间 -->
|
|
425
|
+
<lvc-date-picker v-model="datetime" type="datetime" />
|
|
426
|
+
|
|
427
|
+
<!-- 日期时间范围(双面板) -->
|
|
428
|
+
<lvc-date-picker v-model="range" type="datetimerange" />
|
|
429
|
+
|
|
430
|
+
<!-- 日期范围(单面板) -->
|
|
431
|
+
<lvc-date-picker v-model="range" type="daterange" :single-panel="true" />
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
### lvc-time-picker 时间选择器
|
|
437
|
+
|
|
438
|
+
时间选择器(时:分),支持 24:00 特殊值。
|
|
439
|
+
|
|
440
|
+
#### Props
|
|
441
|
+
|
|
442
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
443
|
+
|------|------|--------|------|
|
|
444
|
+
| value | String | `"00:00"` | 时间 `HH:mm`(v-model) |
|
|
445
|
+
| disabled | Boolean | `false` | 禁用 |
|
|
446
|
+
|
|
447
|
+
#### Events
|
|
448
|
+
|
|
449
|
+
| 事件名 | 参数 | 说明 |
|
|
450
|
+
|--------|------|------|
|
|
451
|
+
| input | `time: String` | v-model 同步 |
|
|
452
|
+
| change | `time: String` | 确认选择时触发 |
|
|
453
|
+
|
|
454
|
+
#### 示例
|
|
455
|
+
|
|
456
|
+
```html
|
|
457
|
+
<lvc-time-picker v-model="time" />
|
|
458
|
+
|
|
459
|
+
<lvc-time-picker v-model="endTime" disabled />
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### lvc-year-picker 年份选择器
|
|
465
|
+
|
|
466
|
+
年份/年份范围选择器。
|
|
467
|
+
|
|
468
|
+
#### Props
|
|
469
|
+
|
|
470
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
471
|
+
|------|------|--------|------|
|
|
472
|
+
| value | String \| Array | `""` | 当前值(范围模式为数组) |
|
|
473
|
+
| yearRange | Number | `5` | 面板前后年份范围(共 `yearRange*2+1` 个) |
|
|
474
|
+
| type | String | `"year"` | `year` / `yearrange` |
|
|
475
|
+
| rangeSeparator | String | `"至"` | 范围分隔符 |
|
|
476
|
+
|
|
477
|
+
#### Events
|
|
478
|
+
|
|
479
|
+
| 事件名 | 参数 | 说明 |
|
|
480
|
+
|--------|------|------|
|
|
481
|
+
| input | `value` | v-model 同步 |
|
|
482
|
+
| confirm | `value` | 点「确定」时触发 |
|
|
483
|
+
| change | `value` | 点「确定」时触发 |
|
|
484
|
+
|
|
485
|
+
#### 示例
|
|
486
|
+
|
|
487
|
+
```html
|
|
488
|
+
<lvc-year-picker v-model="year" type="year" />
|
|
489
|
+
|
|
490
|
+
<lvc-year-picker v-model="yearRange" type="yearrange" :year-range="5" />
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
### lvc-month-picker 月份选择器
|
|
496
|
+
|
|
497
|
+
月份/月份范围选择器。
|
|
498
|
+
|
|
499
|
+
#### Props
|
|
500
|
+
|
|
501
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
502
|
+
|------|------|--------|------|
|
|
503
|
+
| value | String \| Array | `""` | 格式 `YYYY-MM`(范围模式为数组) |
|
|
504
|
+
| type | String | `"month"` | `month` / `monthrange` |
|
|
505
|
+
| rangeSeparator | String | `"至"` | 范围分隔符 |
|
|
506
|
+
| singlePlaceholder | String | `"请选择月份"` | 单选占位符 |
|
|
507
|
+
| startPlaceholder | String | `"开始月份"` | 范围起始占位符 |
|
|
508
|
+
| endPlaceholder | String | `"结束月份"` | 范围结束占位符 |
|
|
509
|
+
|
|
510
|
+
#### Events
|
|
511
|
+
|
|
512
|
+
| 事件名 | 参数 | 说明 |
|
|
513
|
+
|--------|------|------|
|
|
514
|
+
| input | `value` | v-model 同步 |
|
|
515
|
+
| confirm | `value` | 点「确定」时触发 |
|
|
516
|
+
|
|
517
|
+
#### 示例
|
|
518
|
+
|
|
519
|
+
```html
|
|
520
|
+
<lvc-month-picker v-model="month" type="month" />
|
|
521
|
+
|
|
522
|
+
<lvc-month-picker v-model="monthRange" type="monthrange" />
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
### lvc-tree 树形控件
|
|
528
|
+
|
|
529
|
+
递归树,支持节点选择、展开/折叠、三态复选框、过滤、勾选数量限制。
|
|
530
|
+
|
|
531
|
+
#### Props
|
|
532
|
+
|
|
533
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
534
|
+
|------|------|--------|------|
|
|
535
|
+
| data | Array | `[]` | 树形数据 |
|
|
536
|
+
| selectedId | String \| Number | `null` | 当前选中节点 ID |
|
|
537
|
+
| defaultExpandAll | Boolean | `false` | 默认展开所有节点 |
|
|
538
|
+
| showCheckbox | Boolean | `false` | 显示复选框 |
|
|
539
|
+
| defaultCheckedKeys | Array | `[]` | 默认勾选的 key |
|
|
540
|
+
| maxCheck | Number | `0` | 最多勾选叶子数(0=不限) |
|
|
541
|
+
| filterNodeMethod | Function | `null` | 过滤方法 `(text, node) => Boolean` |
|
|
542
|
+
| autoExpandOnFilter | Boolean | `true` | 过滤时自动展开匹配节点 |
|
|
543
|
+
|
|
544
|
+
#### 节点数据结构
|
|
545
|
+
|
|
546
|
+
```js
|
|
547
|
+
{
|
|
548
|
+
id: String|Number, // 必填
|
|
549
|
+
label: String, // 必填
|
|
550
|
+
icon: String, // 可选: 'folder'|'meter'|'data'|'device'|'default'
|
|
551
|
+
expanded: Boolean, // 可选: 初始展开
|
|
552
|
+
children: Array // 可选: 子节点
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
#### Events
|
|
557
|
+
|
|
558
|
+
| 事件名 | 参数 | 说明 |
|
|
559
|
+
|--------|------|------|
|
|
560
|
+
| select | `node: Object` | 节点选中(showCheckbox 模式下不触发) |
|
|
561
|
+
| toggle | `{ node, expanded }` | 展开/折叠 |
|
|
562
|
+
| check-change | `{ node, checked, indeterminate, checkedKeys, checkedNodes }` | 复选框变化 |
|
|
563
|
+
| max-check-exceeded | `{ max, actual }` | 超过 maxCheck 限制 |
|
|
564
|
+
| filter-change | `text: String` | 过滤文本变化 |
|
|
565
|
+
|
|
566
|
+
#### Methods(通过 ref 调用)
|
|
567
|
+
|
|
568
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
569
|
+
|--------|------|--------|------|
|
|
570
|
+
| filter | `text: String` | - | 过滤(会清空勾选) |
|
|
571
|
+
| getCheckedKeys | - | `Array` | 获取勾选的 key |
|
|
572
|
+
| setCheckedKeys | `keys: Array` | - | 设置勾选 |
|
|
573
|
+
| getHalfCheckedKeys | - | `Array` | 获取半选 key |
|
|
574
|
+
|
|
575
|
+
#### 示例
|
|
576
|
+
|
|
577
|
+
```html
|
|
578
|
+
<lvc-tree
|
|
579
|
+
ref="tree"
|
|
580
|
+
:data="treeData"
|
|
581
|
+
:selected-id="selectedId"
|
|
582
|
+
show-checkbox
|
|
583
|
+
:max-check="20"
|
|
584
|
+
:filter-node-method="filterFn"
|
|
585
|
+
@select="onSelect"
|
|
586
|
+
@check-change="onCheck"
|
|
587
|
+
/>
|
|
588
|
+
|
|
589
|
+
<script>
|
|
590
|
+
export default {
|
|
591
|
+
data() {
|
|
592
|
+
return {
|
|
593
|
+
treeData: [
|
|
594
|
+
{
|
|
595
|
+
id: 1, label: '根节点', icon: 'folder', children: [
|
|
596
|
+
{ id: 2, label: '子节点1', icon: 'meter' },
|
|
597
|
+
{ id: 3, label: '子节点2', icon: 'data' }
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
],
|
|
601
|
+
selectedId: null
|
|
602
|
+
};
|
|
603
|
+
},
|
|
604
|
+
methods: {
|
|
605
|
+
filterFn(text, node) {
|
|
606
|
+
return node.label.includes(text);
|
|
607
|
+
},
|
|
608
|
+
onSelect(node) { console.log('选中:', node); },
|
|
609
|
+
onCheck({ checkedKeys }) { console.log('勾选:', checkedKeys); },
|
|
610
|
+
getChecked() {
|
|
611
|
+
return this.$refs.tree.getCheckedKeys();
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
</script>
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
### lvc-dialog 对话框
|
|
621
|
+
|
|
622
|
+
模态对话框,支持模板用法和命令式 API。
|
|
623
|
+
|
|
624
|
+
#### Props
|
|
625
|
+
|
|
626
|
+
| 名称 | 类型 | 默认值 | 说明 |
|
|
627
|
+
|------|------|--------|------|
|
|
628
|
+
| visible | Boolean | `false` | 是否显示(`.sync`) |
|
|
629
|
+
| title | String | `"提示"` | 标题 |
|
|
630
|
+
| content | String | `""` | 内容文本(被默认插槽覆盖时无效) |
|
|
631
|
+
| width | String | `"44.32vmin"` | 宽度 |
|
|
632
|
+
| confirmText | String | `"确定"` | 确认按钮文本 |
|
|
633
|
+
| cancelText | String | `"取消"` | 取消按钮文本 |
|
|
634
|
+
| showCancel | Boolean | `true` | 显示取消按钮 |
|
|
635
|
+
| showClose | Boolean | `true` | 显示关闭按钮 |
|
|
636
|
+
| showFooter | Boolean | `true` | 显示底部按钮区 |
|
|
637
|
+
| closeOnClickModal | Boolean | `true` | 点击遮罩关闭 |
|
|
638
|
+
|
|
639
|
+
#### Events
|
|
640
|
+
|
|
641
|
+
| 事件名 | 参数 | 说明 |
|
|
642
|
+
|--------|------|------|
|
|
643
|
+
| update:visible | `false` | `.sync` 同步 |
|
|
644
|
+
| close | - | 关闭 |
|
|
645
|
+
| cancel | - | 取消 |
|
|
646
|
+
| confirm | - | 确认(不自动关闭,由父级控制) |
|
|
647
|
+
|
|
648
|
+
#### Slots
|
|
649
|
+
|
|
650
|
+
| 插槽 | 说明 |
|
|
651
|
+
|------|------|
|
|
652
|
+
| default | 自定义主体内容 |
|
|
653
|
+
|
|
654
|
+
#### 示例(模板用法)
|
|
655
|
+
|
|
656
|
+
```html
|
|
657
|
+
<lvc-dialog :visible.sync="visible" title="编辑" @confirm="onConfirm">
|
|
658
|
+
<p>自定义内容</p>
|
|
659
|
+
</lvc-dialog>
|
|
660
|
+
|
|
661
|
+
<script>
|
|
662
|
+
export default {
|
|
663
|
+
data() { return { visible: false }; },
|
|
664
|
+
methods: {
|
|
665
|
+
onConfirm() {
|
|
666
|
+
// 处理确认逻辑
|
|
667
|
+
this.visible = false;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
</script>
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
命令式用法见 [lvcDialog 命令式对话框](#lvcdialog-命令式对话框)。
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
## 工具
|
|
679
|
+
|
|
680
|
+
### Bus 跨窗口通讯总线
|
|
681
|
+
|
|
682
|
+
跨 iframe / 跨标签页的事件总线,支持 request-response 模式。
|
|
683
|
+
|
|
684
|
+
#### 特性
|
|
685
|
+
- 跨 iframe:`postMessage` 广播
|
|
686
|
+
- 跨标签页:`BroadcastChannel` + `localStorage` 双通道
|
|
687
|
+
- 支持 request-response
|
|
688
|
+
|
|
689
|
+
#### API
|
|
690
|
+
|
|
691
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
692
|
+
|--------|------|--------|------|
|
|
693
|
+
| on | `event, fn` | - | 监听事件 |
|
|
694
|
+
| off | `event, fn?` | - | 移除监听(不传 fn 清空该事件全部) |
|
|
695
|
+
| once | `event, fn` | - | 监听一次 |
|
|
696
|
+
| emit | `event, data` | - | 触发事件 |
|
|
697
|
+
| request | `event, data, timeout=5000` | `Promise` | 请求-响应(超时 reject `"timeout"`) |
|
|
698
|
+
|
|
699
|
+
#### 示例
|
|
700
|
+
|
|
701
|
+
```js
|
|
702
|
+
import { Bus } from 'lvc-ui';
|
|
703
|
+
|
|
704
|
+
// 监听
|
|
705
|
+
Bus.on('refresh', () => loadData());
|
|
706
|
+
|
|
707
|
+
// 监听并返回数据(供 request 调用)
|
|
708
|
+
Bus.on('getUser', () => ({ name: 'admin', role: 'root' }));
|
|
709
|
+
|
|
710
|
+
// 触发
|
|
711
|
+
Bus.emit('refresh', { id: 1 });
|
|
712
|
+
|
|
713
|
+
// 请求-响应
|
|
714
|
+
const user = await Bus.request('getUser');
|
|
715
|
+
console.log(user); // { name: 'admin', role: 'root' }
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
---
|
|
719
|
+
|
|
720
|
+
### createFetch HTTP 请求封装
|
|
721
|
+
|
|
722
|
+
基于 `fetch` 的 HTTP 客户端工厂,支持拦截器、重试、缓存、去重、轮询、loading 监听。
|
|
723
|
+
|
|
724
|
+
#### 工厂函数
|
|
725
|
+
|
|
726
|
+
```js
|
|
727
|
+
import { createFetch } from 'lvc-ui';
|
|
728
|
+
|
|
729
|
+
const http = createFetch({
|
|
730
|
+
baseURL: '/api',
|
|
731
|
+
timeout: 10000,
|
|
732
|
+
retries: 1,
|
|
733
|
+
getToken: () => localStorage.getItem('myToken')
|
|
734
|
+
});
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
#### 全局配置
|
|
738
|
+
|
|
739
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
740
|
+
|------|------|--------|------|
|
|
741
|
+
| baseURL | String | `""` | 基础 URL |
|
|
742
|
+
| headers | Object | `{ "Content-Type": "application/json" }` | 默认请求头 |
|
|
743
|
+
| timeout | Number | `10000` | 超时(ms) |
|
|
744
|
+
| retries | Number | `1` | 重试次数 |
|
|
745
|
+
| retryDelay | Number | `500` | 重试延迟 |
|
|
746
|
+
| cache | Number | `0` | GET 缓存时间(ms),0=不缓存 |
|
|
747
|
+
| credentials | String | `"same-origin"` | fetch credentials |
|
|
748
|
+
| responseType | String | `"json"` | `json`/`text`/`blob` |
|
|
749
|
+
| concurrency | Number | `Infinity` | 最大并发 |
|
|
750
|
+
| dedupe | Boolean | `true` | 相同请求去重 |
|
|
751
|
+
| debounce | Number | `200` | 去抖(ms),0=不去抖 |
|
|
752
|
+
| getToken | Function | `() => localStorage.getItem("emstoken")` | 取 token |
|
|
753
|
+
| refreshToken | AsyncFunction | - | 刷新 token |
|
|
754
|
+
| onRefreshFail | Function | - | 刷新失败回调 |
|
|
755
|
+
| onError | Function | - | 错误回调 |
|
|
756
|
+
| showLog | Boolean | `false` | 打印日志 |
|
|
757
|
+
|
|
758
|
+
#### 实例方法
|
|
759
|
+
|
|
760
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
761
|
+
|--------|------|--------|------|
|
|
762
|
+
| get | `url, opts={}` | `Promise` | GET |
|
|
763
|
+
| post | `url, body, opts={}` | `Promise` | POST |
|
|
764
|
+
| put | `url, body, opts={}` | `Promise` | PUT |
|
|
765
|
+
| delete | `url, opts={}` | `Promise` | DELETE |
|
|
766
|
+
| request | `options` | `Promise` | 通用请求 |
|
|
767
|
+
| poll | `url, payload={}, options={}` | `poller` | 启动轮询 |
|
|
768
|
+
| stopAllPoll | - | - | 停止所有轮询 |
|
|
769
|
+
| createCancelToken | - | `{ signal, cancel }` | 创建可取消 token |
|
|
770
|
+
| onLoading | `cb` | `unsubscribe` | 监听 loading 计数 |
|
|
771
|
+
| setToken | `token \| null` | - | 设置/清除 token |
|
|
772
|
+
| interceptors | - | - | 拦截器 `{ request, response }` |
|
|
773
|
+
|
|
774
|
+
#### 轮询示例
|
|
775
|
+
|
|
776
|
+
```js
|
|
777
|
+
const poller = http.poll('/metrics', {}, {
|
|
778
|
+
interval: 3000,
|
|
779
|
+
callback: (data) => console.log('metrics:', data)
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
poller.on('error', err => console.error(err));
|
|
783
|
+
|
|
784
|
+
// 停止
|
|
785
|
+
poller.stop();
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
#### 拦截器示例
|
|
789
|
+
|
|
790
|
+
```js
|
|
791
|
+
http.interceptors.request.handlers.push({
|
|
792
|
+
fulfilled: (config) => {
|
|
793
|
+
config.headers['X-Custom'] = 'value';
|
|
794
|
+
return config;
|
|
795
|
+
},
|
|
796
|
+
rejected: (err) => {}
|
|
797
|
+
});
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
---
|
|
801
|
+
|
|
802
|
+
### createRouter Hash 路由
|
|
803
|
+
|
|
804
|
+
轻量级 Hash 路由,支持前置守卫、嵌套层级、登录鉴权。
|
|
805
|
+
|
|
806
|
+
#### 工厂函数
|
|
807
|
+
|
|
808
|
+
```js
|
|
809
|
+
import { createRouter } from 'lvc-ui';
|
|
810
|
+
|
|
811
|
+
const router = createRouter({
|
|
812
|
+
routes: {
|
|
813
|
+
home: { path: '#/home', meta: { requiresAuth: true } },
|
|
814
|
+
settings: '#/settings',
|
|
815
|
+
about: { path: '#/about' }
|
|
816
|
+
},
|
|
817
|
+
default: 'home',
|
|
818
|
+
level: 1
|
|
819
|
+
});
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
#### 配置
|
|
823
|
+
|
|
824
|
+
| 字段 | 类型 | 说明 |
|
|
825
|
+
|------|------|------|
|
|
826
|
+
| routes | Object | 路由表 `{ name: "path" \| { path, meta } }` |
|
|
827
|
+
| default | String | 默认路由名 |
|
|
828
|
+
| level | Number | 路由层级(hash 第几段) |
|
|
829
|
+
| loginPage | String | 登录页跳转地址 |
|
|
830
|
+
|
|
831
|
+
#### router 方法
|
|
832
|
+
|
|
833
|
+
| 方法名 | 参数 | 说明 |
|
|
834
|
+
|--------|------|------|
|
|
835
|
+
| init | `vm` | 初始化(绑定 Vue 实例,监听 hashchange) |
|
|
836
|
+
| push | `name` | 跳转 |
|
|
837
|
+
| beforeEach | `fn` | 注册前置守卫 `fn(to, from, next)` |
|
|
838
|
+
| resolve | - | 解析当前 hash |
|
|
839
|
+
|
|
840
|
+
#### 守卫 next 行为
|
|
841
|
+
- `next()` / `next(undefined)`:放行
|
|
842
|
+
- `next(false)`:中止
|
|
843
|
+
- `next("routeName")`:重定向
|
|
844
|
+
|
|
845
|
+
#### 示例
|
|
846
|
+
|
|
847
|
+
```js
|
|
848
|
+
router.init(this);
|
|
849
|
+
|
|
850
|
+
router.beforeEach((to, from, next) => {
|
|
851
|
+
console.log('跳转:', from, '->', to);
|
|
852
|
+
next();
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
router.push('settings');
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
---
|
|
859
|
+
|
|
860
|
+
### SocketClient WebSocket 客户端
|
|
861
|
+
|
|
862
|
+
带心跳、自动重连、消息分发的 WebSocket 客户端。
|
|
863
|
+
|
|
864
|
+
#### 构造函数
|
|
865
|
+
|
|
866
|
+
```js
|
|
867
|
+
import { SocketClient } from 'lvc-ui';
|
|
868
|
+
|
|
869
|
+
const ws = new SocketClient('ws://example.com/ws', {
|
|
870
|
+
heartbeatInterval: 30000,
|
|
871
|
+
reconnectInterval: 5000,
|
|
872
|
+
maxReconnectAttempts: 5,
|
|
873
|
+
pingMessage: 'ping'
|
|
874
|
+
});
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
#### 配置
|
|
878
|
+
|
|
879
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
880
|
+
|------|------|--------|------|
|
|
881
|
+
| heartbeatInterval | Number | `30000` | 心跳间隔(ms) |
|
|
882
|
+
| reconnectInterval | Number | `5000` | 重连基础间隔 |
|
|
883
|
+
| maxReconnectAttempts | Number | `5` | 最大重连次数(-1=无限) |
|
|
884
|
+
| pingMessage | String | `"ping"` | 心跳内容 |
|
|
885
|
+
|
|
886
|
+
#### 实例方法
|
|
887
|
+
|
|
888
|
+
| 方法名 | 参数 | 说明 |
|
|
889
|
+
|--------|------|------|
|
|
890
|
+
| send | `data: Object\|String` | 发送消息(未连接时入队列) |
|
|
891
|
+
| on | `eventName, callback` | 监听事件 |
|
|
892
|
+
| off | `eventName, callback?` | 移除监听 |
|
|
893
|
+
| close | - | 手动关闭(不再重连) |
|
|
894
|
+
|
|
895
|
+
#### 消息分发规则
|
|
896
|
+
|
|
897
|
+
收到消息后 `JSON.parse`,取 `resData.topic` 或 `resData.type` 作为事件名触发监听器,同时触发通用 `message` 事件。
|
|
898
|
+
|
|
899
|
+
#### 示例
|
|
900
|
+
|
|
901
|
+
```js
|
|
902
|
+
const ws = new SocketClient('ws://localhost:8080');
|
|
903
|
+
|
|
904
|
+
// 监听业务事件(由后端消息的 topic/type 字段决定)
|
|
905
|
+
ws.on('chat', (data) => {
|
|
906
|
+
console.log('收到消息:', data);
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
// 监听原始消息
|
|
910
|
+
ws.on('message', (msg) => {
|
|
911
|
+
console.log('raw:', msg);
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
// 发送
|
|
915
|
+
ws.send({ type: 'chat', text: 'hello' });
|
|
916
|
+
|
|
917
|
+
// 关闭
|
|
918
|
+
ws.close();
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
---
|
|
922
|
+
|
|
923
|
+
### CanvasTopologyUtils Canvas 拓扑工具
|
|
924
|
+
|
|
925
|
+
Canvas 拓扑图绘制工具,支持节点、连线、流光动画、图片缓存、DPR 适配。
|
|
926
|
+
|
|
927
|
+
#### 构造函数
|
|
928
|
+
|
|
929
|
+
```js
|
|
930
|
+
import { CanvasTopologyUtils } from 'lvc-ui';
|
|
931
|
+
|
|
932
|
+
const topo = new CanvasTopologyUtils('myCanvas', '#container', 1280);
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
| 参数 | 类型 | 说明 |
|
|
936
|
+
|------|------|------|
|
|
937
|
+
| canvasId | String | Canvas 元素 ID |
|
|
938
|
+
| containerSelector | String | 父容器选择器(用于尺寸适配) |
|
|
939
|
+
| baseWidth | Number | 设计稿基准宽度,默认 1280 |
|
|
940
|
+
|
|
941
|
+
#### 实例方法
|
|
942
|
+
|
|
943
|
+
| 方法名 | 参数 | 说明 |
|
|
944
|
+
|--------|------|------|
|
|
945
|
+
| init | - | 初始化画布 |
|
|
946
|
+
| s | `val: Number` | 缩放转换(设计稿 px → 实际 px) |
|
|
947
|
+
| clear | - | 清空画布 |
|
|
948
|
+
| drawNode | `x, y, r, color, label, isSub=false, labelY=15, fontS=12` | 绘制拓扑节点 |
|
|
949
|
+
| drawNodeImgText | `{ url, x, y, w, h, text, ... }` | 绘制图片+文字节点 |
|
|
950
|
+
| drawFlowLine | `points, options` | 绘制流光动画虚线 |
|
|
951
|
+
| drawDashLine | `points, options` | 绘制虚线 |
|
|
952
|
+
| drawImage | `url, x, y, w, h, isCenter=true` | 绘制图片 |
|
|
953
|
+
| drawText | `text, x, y, options` | 绘制文字 |
|
|
954
|
+
| drawCircle | `x, y, r, options` | 绘制圆 |
|
|
955
|
+
| drawPolygon | `points, options` | 绘制多边形 |
|
|
956
|
+
| drawFlowCurve | `p1, p2, offset` | 绘制流动贝塞尔连线 |
|
|
957
|
+
|
|
958
|
+
#### points 路径格式
|
|
959
|
+
- `[x, y]` → 直线
|
|
960
|
+
- `[cpX, cpY, x, y]` → 二阶贝塞尔
|
|
961
|
+
- `[cp1X, cp1Y, cp2X, cp2Y, x, y]` → 三阶贝塞尔
|
|
962
|
+
|
|
963
|
+
#### 示例
|
|
964
|
+
|
|
965
|
+
```js
|
|
966
|
+
const topo = new CanvasTopologyUtils('topoCanvas', '.topo-container', 1280);
|
|
967
|
+
topo.init();
|
|
968
|
+
|
|
969
|
+
// 绘制节点
|
|
970
|
+
topo.drawNode(100, 100, 20, '#00e5ff', '节点A');
|
|
971
|
+
topo.drawNode(300, 100, 20, '#ff9800', '节点B');
|
|
972
|
+
|
|
973
|
+
// 绘制流光连线(requestAnimationFrame 中持续更新 offset)
|
|
974
|
+
function animate() {
|
|
975
|
+
topo.clear();
|
|
976
|
+
topo.drawNode(100, 100, 20, '#00e5ff', '节点A');
|
|
977
|
+
topo.drawNode(300, 100, 20, '#ff9800', '节点B');
|
|
978
|
+
topo.drawFlowLine([[120, 100], [280, 100]], { offset: Date.now() / 30 });
|
|
979
|
+
requestAnimationFrame(animate);
|
|
980
|
+
}
|
|
981
|
+
animate();
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
---
|
|
985
|
+
|
|
986
|
+
### px2EchartsUrils ECharts 像素适配
|
|
987
|
+
|
|
988
|
+
将设计稿 px 转换为当前屏幕实际 px(模拟 vmin 逻辑,用于 ECharts 字号适配)。
|
|
989
|
+
|
|
990
|
+
#### API
|
|
991
|
+
|
|
992
|
+
```js
|
|
993
|
+
import { px2EchartsUrils } from 'lvc-ui';
|
|
994
|
+
|
|
995
|
+
px2EchartsUrils.px2Echarts(pxValue, desWidth = 1280, desHeight = 800, keep1px = true);
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
| 参数 | 类型 | 说明 |
|
|
999
|
+
|------|------|------|
|
|
1000
|
+
| pxValue | Number | 设计稿像素值 |
|
|
1001
|
+
| desWidth | Number | 设计稿宽度,默认 1280 |
|
|
1002
|
+
| desHeight | Number | 设计稿高度,默认 800 |
|
|
1003
|
+
| keep1px | Boolean | 是否对 1px 做保护,默认 true |
|
|
1004
|
+
|
|
1005
|
+
返回:保留 2 位小数的 Number。
|
|
1006
|
+
|
|
1007
|
+
#### 示例
|
|
1008
|
+
|
|
1009
|
+
```js
|
|
1010
|
+
const fontSize = px2EchartsUrils.px2Echarts(14); // 在 1920×1080 屏幕上可能返回 16.80
|
|
1011
|
+
|
|
1012
|
+
// 在 ECharts 配置中使用
|
|
1013
|
+
const option = {
|
|
1014
|
+
xAxis: {
|
|
1015
|
+
axisLabel: { fontSize: px2EchartsUrils.px2Echarts(12) }
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
### LvcLoading 全局 Loading
|
|
1023
|
+
|
|
1024
|
+
全局加载遮罩,支持单例、文本更新、过渡动画。
|
|
1025
|
+
|
|
1026
|
+
#### API
|
|
1027
|
+
|
|
1028
|
+
```js
|
|
1029
|
+
import { LvcLoading } from 'lvc-ui';
|
|
1030
|
+
|
|
1031
|
+
LvcLoading.show(options); // 显示(字符串简写: show("加载中"))
|
|
1032
|
+
LvcLoading.close(); // 关闭
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
`show()` 返回 instance 对象:
|
|
1036
|
+
|
|
1037
|
+
| 方法名 | 参数 | 说明 |
|
|
1038
|
+
|--------|------|------|
|
|
1039
|
+
| setText | `text: String` | 更新文本 |
|
|
1040
|
+
| close | - | 关闭 |
|
|
1041
|
+
|
|
1042
|
+
#### 示例
|
|
1043
|
+
|
|
1044
|
+
```js
|
|
1045
|
+
// 浏览器全局
|
|
1046
|
+
LvcLoading.show('加载中...');
|
|
1047
|
+
await fetchData();
|
|
1048
|
+
LvcLoading.close();
|
|
1049
|
+
|
|
1050
|
+
// Vue 组件内
|
|
1051
|
+
this.$lvcLoading.show({ text: '提交中' });
|
|
1052
|
+
|
|
1053
|
+
// 更新文本
|
|
1054
|
+
const inst = LvcLoading.show('处理中');
|
|
1055
|
+
inst.setText('快好了');
|
|
1056
|
+
inst.close();
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
---
|
|
1060
|
+
|
|
1061
|
+
### LvcMessage 全局消息提示
|
|
1062
|
+
|
|
1063
|
+
全局消息提示,支持 info/success/warning/error 四种类型。
|
|
1064
|
+
|
|
1065
|
+
#### API
|
|
1066
|
+
|
|
1067
|
+
```js
|
|
1068
|
+
import { LvcMessage } from 'lvc-ui';
|
|
1069
|
+
|
|
1070
|
+
LvcMessage(options); // 直接调用
|
|
1071
|
+
LvcMessage("提示文本"); // 字符串简写
|
|
1072
|
+
LvcMessage.success(options); // 成功
|
|
1073
|
+
LvcMessage.warning(options); // 警告
|
|
1074
|
+
LvcMessage.info(options); // 信息
|
|
1075
|
+
LvcMessage.error(options); // 错误
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
#### options
|
|
1079
|
+
|
|
1080
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
1081
|
+
|------|------|--------|------|
|
|
1082
|
+
| type | String | `"info"` | `info`/`success`/`warning`/`error` |
|
|
1083
|
+
| message | String | `""` | 文本 |
|
|
1084
|
+
| duration | Number | `2000` | 显示时长(ms),0=不自动关闭 |
|
|
1085
|
+
|
|
1086
|
+
#### 示例
|
|
1087
|
+
|
|
1088
|
+
```js
|
|
1089
|
+
LvcMessage.success('保存成功');
|
|
1090
|
+
LvcMessage.error({ message: '网络错误', duration: 5000 });
|
|
1091
|
+
LvcMessage.warning('请注意');
|
|
1092
|
+
LvcMessage.info('提示');
|
|
1093
|
+
|
|
1094
|
+
// Vue 组件内
|
|
1095
|
+
this.$lvcMessage.error('出错了');
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
---
|
|
1099
|
+
|
|
1100
|
+
### lvcDialog 命令式对话框
|
|
1101
|
+
|
|
1102
|
+
命令式对话框 API,无需在模板中声明,直接调用即可弹出。
|
|
1103
|
+
|
|
1104
|
+
#### API
|
|
1105
|
+
|
|
1106
|
+
```js
|
|
1107
|
+
import { lvcDialog } from 'lvc-ui';
|
|
1108
|
+
|
|
1109
|
+
lvcDialog.show(options);
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
#### options
|
|
1113
|
+
|
|
1114
|
+
| 字段 | 类型 | 说明 |
|
|
1115
|
+
|------|------|------|
|
|
1116
|
+
| title | String | 标题 |
|
|
1117
|
+
| content | String | 内容文本 |
|
|
1118
|
+
| width | String | 宽度 |
|
|
1119
|
+
| confirmText | String | 确认按钮文本 |
|
|
1120
|
+
| cancelText | String | 取消按钮文本 |
|
|
1121
|
+
| showCancel | Boolean | 显示取消按钮 |
|
|
1122
|
+
| showFooter | Boolean | 显示底部按钮区 |
|
|
1123
|
+
| closeOnClickModal | Boolean | 点击遮罩关闭 |
|
|
1124
|
+
| onConfirm | `() => Promise<Boolean\|undefined>` | 确认回调(返回 `false` 阻止关闭) |
|
|
1125
|
+
| onCancel | `Function` | 取消回调 |
|
|
1126
|
+
|
|
1127
|
+
#### 示例
|
|
1128
|
+
|
|
1129
|
+
```js
|
|
1130
|
+
import { lvcDialog } from 'lvc-ui';
|
|
1131
|
+
|
|
1132
|
+
// 简单提示
|
|
1133
|
+
lvcDialog.show({
|
|
1134
|
+
title: '提示',
|
|
1135
|
+
content: '操作成功'
|
|
1136
|
+
});
|
|
1137
|
+
|
|
1138
|
+
// 确认删除
|
|
1139
|
+
lvcDialog.show({
|
|
1140
|
+
title: '确认删除',
|
|
1141
|
+
content: '确定要删除这条记录吗?',
|
|
1142
|
+
confirmText: '删除',
|
|
1143
|
+
cancelText: '取消',
|
|
1144
|
+
onConfirm: async () => {
|
|
1145
|
+
await deleteRecord();
|
|
1146
|
+
// 返回 false 可阻止关闭
|
|
1147
|
+
},
|
|
1148
|
+
onCancel: () => console.log('cancelled')
|
|
1149
|
+
});
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
---
|
|
1153
|
+
|
|
1154
|
+
## 按需引入
|
|
1155
|
+
|
|
1156
|
+
除了 `Vue.use(LvcUI)` 全量注册外,可以单独引入工具函数和组件定义:
|
|
1157
|
+
|
|
1158
|
+
```js
|
|
1159
|
+
// 工具
|
|
1160
|
+
import { Bus, createFetch, createRouter, SocketClient, CanvasTopologyUtils, px2EchartsUrils, LvcLoading, LvcMessage, lvcDialog } from 'lvc-ui';
|
|
1161
|
+
|
|
1162
|
+
// 组件定义对象(需手动注册)
|
|
1163
|
+
import { lvcButton, LvcTree, lvcDialogComponent } from 'lvc-ui';
|
|
1164
|
+
|
|
1165
|
+
Vue.component('lvc-button', lvcButton);
|
|
1166
|
+
Vue.component('lvc-tree', LvcTree);
|
|
1167
|
+
```
|
|
1168
|
+
|
|
1169
|
+
---
|
|
1170
|
+
|
|
1171
|
+
## 外部依赖
|
|
1172
|
+
|
|
1173
|
+
| 依赖 | 说明 |
|
|
1174
|
+
|------|------|
|
|
1175
|
+
| `vue@^2.6.0 \|\| ^2.7.0` | peerDependency,必须由项目提供 |
|
|
1176
|
+
| `Odometer` | lvc-odometer 组件依赖,需在使用前引入 odometer 库全局脚本(dist 目录已提供 `odometer.min.js` 和 `odometer-theme-minimal.css`) |
|
|
1177
|
+
|
|
1178
|
+
浏览器原生 API(无需引入):`fetch`、`AbortController`、`WebSocket`、`IntersectionObserver`、`BroadcastChannel`(可选)、`localStorage`。
|
|
1179
|
+
|
|
1180
|
+
---
|
|
1181
|
+
|
|
1182
|
+
## 构建
|
|
1183
|
+
|
|
1184
|
+
```bash
|
|
1185
|
+
# 安装依赖
|
|
1186
|
+
npm install
|
|
1187
|
+
|
|
1188
|
+
# 构建(生成 dist/lvc-ui.js + dist/lvc-ui.min.js)
|
|
1189
|
+
npm run build
|
|
1190
|
+
|
|
1191
|
+
# 验证打包产物
|
|
1192
|
+
npm run verify
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
### 目录结构
|
|
1196
|
+
|
|
1197
|
+
```
|
|
1198
|
+
lvc-ui/
|
|
1199
|
+
├── src/ # 源文件
|
|
1200
|
+
│ ├── utils.js # Canvas 拓扑工具 + ECharts 像素适配
|
|
1201
|
+
│ ├── bus.js # 跨窗口通讯总线
|
|
1202
|
+
│ ├── request.js # HTTP 请求封装
|
|
1203
|
+
│ ├── router.js # Hash 路由
|
|
1204
|
+
│ ├── socket.js # WebSocket 客户端
|
|
1205
|
+
│ ├── lvcLoading.js # 全局 Loading
|
|
1206
|
+
│ ├── lvcMessage.js # 全局消息提示
|
|
1207
|
+
│ ├── lvcButton.js # 按钮组件
|
|
1208
|
+
│ ├── lvcSwitch.js # 开关组件
|
|
1209
|
+
│ ├── lvcOdometer.js # 数字滚动组件
|
|
1210
|
+
│ ├── lvcLoadMore.js # 滚动加载更多
|
|
1211
|
+
│ ├── lvcSelect.js # 下拉选择
|
|
1212
|
+
│ ├── lvcTable.js # 表格
|
|
1213
|
+
│ ├── lvcDate.js # 日期选择器
|
|
1214
|
+
│ ├── lvcTimePicker.js # 时间选择器
|
|
1215
|
+
│ ├── lvcYearPicker.min.js # 年份选择器
|
|
1216
|
+
│ ├── lvcMonthPicker.min.js # 月份选择器
|
|
1217
|
+
│ ├── lvcTree.min.js # 树形控件
|
|
1218
|
+
│ └── lvcDialog.js # 对话框
|
|
1219
|
+
├── scripts/
|
|
1220
|
+
│ ├── build.js # 构建脚本
|
|
1221
|
+
│ └── verify.js # 验证脚本
|
|
1222
|
+
├── dist/
|
|
1223
|
+
│ ├── lvc-ui.js # UMD 未压缩(215 KB)
|
|
1224
|
+
│ └── lvc-ui.min.js # UMD 压缩(128 KB)
|
|
1225
|
+
└── package.json
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
---
|
|
1229
|
+
|
|
1230
|
+
## License
|
|
1231
|
+
|
|
1232
|
+
MIT
|