knt-shared 1.0.0 → 1.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.
Files changed (46) hide show
  1. package/README.md +390 -135
  2. package/dist/components/Description/BasicDescription.vue.d.ts +63 -0
  3. package/dist/components/Description/BasicDescription.vue.d.ts.map +1 -0
  4. package/dist/components/Description/index.d.ts +5 -0
  5. package/dist/components/Description/index.d.ts.map +1 -0
  6. package/dist/components/Description/types.d.ts +97 -0
  7. package/dist/components/Description/types.d.ts.map +1 -0
  8. package/dist/components/Description/useDescription.d.ts +10 -0
  9. package/dist/components/Description/useDescription.d.ts.map +1 -0
  10. package/dist/components/Form/componentMap.d.ts +691 -5
  11. package/dist/components/Form/componentMap.d.ts.map +1 -1
  12. package/dist/components/Form/types.d.ts +6 -3
  13. package/dist/components/Form/types.d.ts.map +1 -1
  14. package/dist/components/Form/useForm.d.ts.map +1 -1
  15. package/dist/components/Modal/BasicModal.vue.d.ts +118 -0
  16. package/dist/components/Modal/BasicModal.vue.d.ts.map +1 -0
  17. package/dist/components/Modal/index.d.ts +5 -0
  18. package/dist/components/Modal/index.d.ts.map +1 -0
  19. package/dist/components/Modal/types.d.ts +163 -0
  20. package/dist/components/Modal/types.d.ts.map +1 -0
  21. package/dist/components/Modal/useModal.d.ts +10 -0
  22. package/dist/components/Modal/useModal.d.ts.map +1 -0
  23. package/dist/components/Modal/useModalInner.d.ts +10 -0
  24. package/dist/components/Modal/useModalInner.d.ts.map +1 -0
  25. package/dist/components/Table/BasicTable.vue.d.ts +123 -0
  26. package/dist/components/Table/BasicTable.vue.d.ts.map +1 -0
  27. package/dist/components/Table/index.d.ts +7 -0
  28. package/dist/components/Table/index.d.ts.map +1 -0
  29. package/dist/components/Table/types.d.ts +337 -0
  30. package/dist/components/Table/types.d.ts.map +1 -0
  31. package/dist/components/Table/useTable.d.ts +23 -0
  32. package/dist/components/Table/useTable.d.ts.map +1 -0
  33. package/dist/components/index.d.ts +3 -0
  34. package/dist/components/index.d.ts.map +1 -1
  35. package/dist/index.cjs.js +2845 -121
  36. package/dist/index.cjs.js.map +1 -1
  37. package/dist/index.esm.js +2847 -123
  38. package/dist/index.esm.js.map +1 -1
  39. package/dist/style.css +98 -0
  40. package/dist/utils/debounce.d.ts +23 -0
  41. package/dist/utils/debounce.d.ts.map +1 -0
  42. package/dist/utils/index.d.ts +1 -0
  43. package/dist/utils/index.d.ts.map +1 -1
  44. package/package.json +12 -11
  45. package/dist/components/Form/BasicForm.vue.d.ts +0 -117
  46. package/dist/components/Form/BasicForm.vue.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,259 +1,514 @@
1
1
  # knt-shared
2
2
 
3
- KNT共享组件库和工具函数(基于 Vue3 + @arco-design/web-vue)
3
+ KNT 共享组件库和工具函数(基于 Vue3 + @arco-design/web-vue)
4
4
 
5
5
  参考 [Vben Admin](https://doc.vvbin.cn/components/introduction.html) 的设计思路实现
6
6
 
7
- ## 安装
7
+ ## ✨ 特性
8
+
9
+ - 🎨 **二次封装** - 基于 Arco Design Vue 进行二次封装,提供更便捷的使用方式
10
+ - 📦 **开箱即用** - 高质量的 Vue3 组件,简单配置即可使用
11
+ - 🔧 **函数式调用** - 支持通过 Hooks 进行组件注册和控制
12
+ - 🎯 **TypeScript** - 完整的 TypeScript 类型支持
13
+ - 🔄 **动态配置** - 支持动态修改组件属性和数据
14
+ - 📱 **响应式** - 完整的响应式布局支持
15
+
16
+ ## 📦 安装
8
17
 
9
18
  ```bash
10
19
  npm install knt-shared
20
+ # 或
21
+ pnpm install knt-shared
22
+ # 或
23
+ yarn add knt-shared
24
+ ```
25
+
26
+ ## 🔨 依赖要求
27
+
28
+ ```json
29
+ {
30
+ "vue": "^3.4.0",
31
+ "@arco-design/web-vue": "^2.50.0"
32
+ }
11
33
  ```
12
34
 
13
- ## 使用
35
+ ## 📚 组件列表
14
36
 
15
37
  ### Description 详情组件
16
38
 
39
+ 用于展示详细信息的组件,支持自定义渲染、动态控制字段显示等功能。
40
+
41
+ **基础使用:**
42
+
17
43
  ```vue
18
44
  <template>
19
- <Description
45
+ <BasicDescription
20
46
  title="用户信息"
21
- :items="descriptionItems"
22
47
  :column="3"
23
- bordered
48
+ :data="userData"
49
+ :schema="schema"
24
50
  />
25
51
  </template>
26
52
 
27
53
  <script setup lang="ts">
28
- import { Description } from 'knt-shared';
29
- import type { DescriptionItem } from 'knt-shared';
30
-
31
- const descriptionItems: DescriptionItem[] = [
32
- { label: '姓名', value: '张三' },
33
- { label: '年龄', value: 28 },
34
- { label: '邮箱', value: 'zhangsan@example.com' },
35
- { label: '地址', value: '北京市朝阳区', span: 2 },
54
+ import { BasicDescription } from 'knt-shared';
55
+ import type { DescItem } from 'knt-shared';
56
+
57
+ const userData = {
58
+ username: 'zhangsan',
59
+ nickName: '张三',
60
+ age: 25,
61
+ email: 'zhangsan@example.com',
62
+ };
63
+
64
+ const schema: DescItem[] = [
65
+ { field: 'username', label: '用户名' },
66
+ { field: 'nickName', label: '昵称' },
67
+ { field: 'age', label: '年龄' },
68
+ { field: 'email', label: '邮箱' },
36
69
  ];
37
70
  </script>
38
71
  ```
39
72
 
40
- ### Form 表单组件
73
+ **使用 Hook:**
41
74
 
42
75
  ```vue
43
76
  <template>
44
- <Form
45
- ref="formRef"
46
- :model="formData"
47
- :rules="rules"
48
- @submit="handleSubmit"
49
- >
50
- <a-form-item field="name" label="姓名">
51
- <a-input v-model="formData.name" placeholder="请输入姓名" />
52
- </a-form-item>
53
- <a-form-item field="email" label="邮箱">
54
- <a-input v-model="formData.email" placeholder="请输入邮箱" />
55
- </a-form-item>
56
- <a-form-item>
57
- <a-button type="primary" html-type="submit">提交</a-button>
58
- <a-button @click="handleReset">重置</a-button>
59
- </a-form-item>
60
- </Form>
77
+ <BasicDescription @register="register" />
61
78
  </template>
62
79
 
63
80
  <script setup lang="ts">
64
- import { ref } from 'vue';
65
- import { Form } from 'knt-shared';
66
-
67
- const formRef = ref();
68
- const formData = ref({
69
- name: '',
70
- email: '',
81
+ import { BasicDescription, useDescription } from 'knt-shared';
82
+
83
+ const [register, { setDescriptionProps }] = useDescription({
84
+ title: '用户信息',
85
+ column: 3,
86
+ data: { username: 'zhangsan', nickName: '张三' },
87
+ schema: [
88
+ { field: 'username', label: '用户名' },
89
+ { field: 'nickName', label: '昵称' },
90
+ ],
71
91
  });
92
+ </script>
93
+ ```
72
94
 
73
- const rules = {
74
- name: [{ required: true, message: '请输入姓名' }],
75
- email: [
76
- { required: true, message: '请输入邮箱' },
77
- { type: 'email', message: '邮箱格式不正确' },
78
- ],
79
- };
95
+ ### Form 表单组件
96
+
97
+ 动态表单组件,支持 schema 配置、自动组件映射、动态控制等功能。
98
+
99
+ **基础使用:**
100
+
101
+ ```vue
102
+ <template>
103
+ <BasicForm
104
+ :schemas="formSchemas"
105
+ :labelCol="{ span: 6 }"
106
+ :wrapperCol="{ span: 18 }"
107
+ @submit="handleSubmit"
108
+ />
109
+ </template>
110
+
111
+ <script setup lang="ts">
112
+ import { BasicForm } from 'knt-shared';
113
+ import type { FormSchema } from 'knt-shared';
114
+
115
+ const formSchemas: FormSchema[] = [
116
+ {
117
+ field: 'name',
118
+ label: '姓名',
119
+ component: 'Input',
120
+ required: true,
121
+ },
122
+ {
123
+ field: 'email',
124
+ label: '邮箱',
125
+ component: 'Input',
126
+ required: true,
127
+ rules: [{ type: 'email', message: '邮箱格式不正确' }],
128
+ },
129
+ {
130
+ field: 'age',
131
+ label: '年龄',
132
+ component: 'InputNumber',
133
+ },
134
+ ];
80
135
 
81
136
  const handleSubmit = (values: Record<string, any>) => {
82
137
  console.log('提交数据:', values);
83
138
  };
139
+ </script>
140
+ ```
84
141
 
85
- const handleReset = () => {
86
- formRef.value?.resetFields();
142
+ **使用 Hook:**
143
+
144
+ ```vue
145
+ <template>
146
+ <BasicForm @register="register" />
147
+ </template>
148
+
149
+ <script setup lang="ts">
150
+ import { BasicForm, useForm } from 'knt-shared';
151
+
152
+ const [register, { setFieldsValue, validate }] = useForm({
153
+ schemas: formSchemas,
154
+ });
155
+
156
+ // 设置表单值
157
+ const setValues = () => {
158
+ setFieldsValue({ name: '张三', age: 25 });
159
+ };
160
+
161
+ // 验证表单
162
+ const submit = async () => {
163
+ const values = await validate();
164
+ console.log(values);
87
165
  };
88
166
  </script>
89
167
  ```
90
168
 
91
169
  ### Table 表格组件
92
170
 
171
+ 高级表格组件,支持自动请求数据、搜索表单、操作列、自定义渲染等功能。
172
+
173
+ **基础使用:**
174
+
93
175
  ```vue
94
176
  <template>
95
- <Table
96
- ref="tableRef"
177
+ <BasicTable
97
178
  :columns="columns"
98
- :data="tableData"
99
- :loading="loading"
179
+ :dataSource="tableData"
100
180
  :pagination="{ pageSize: 10 }"
101
- @page-change="handlePageChange"
102
181
  />
103
182
  </template>
104
183
 
105
184
  <script setup lang="ts">
106
- import { ref } from 'vue';
107
- import { Table } from 'knt-shared';
108
- import type { TableColumnData } from '@arco-design/web-vue';
185
+ import { BasicTable } from 'knt-shared';
186
+ import type { BasicColumn } from 'knt-shared';
109
187
 
110
- const tableRef = ref();
111
- const loading = ref(false);
112
- const tableData = ref([
188
+ const columns: BasicColumn[] = [
189
+ { title: '姓名', dataIndex: 'name' },
190
+ { title: '年龄', dataIndex: 'age' },
191
+ { title: '邮箱', dataIndex: 'email' },
192
+ ];
193
+
194
+ const tableData = [
113
195
  { id: 1, name: '张三', age: 25, email: 'zhangsan@example.com' },
114
196
  { id: 2, name: '李四', age: 30, email: 'lisi@example.com' },
115
- ]);
197
+ ];
198
+ </script>
199
+ ```
200
+
201
+ **使用 request 自动加载数据:**
116
202
 
117
- const columns: TableColumnData[] = [
203
+ ```vue
204
+ <template>
205
+ <BasicTable
206
+ :columns="columns"
207
+ :request="loadData"
208
+ :searchFormConfig="{ schemas: searchSchemas }"
209
+ />
210
+ </template>
211
+
212
+ <script setup lang="ts">
213
+ import { BasicTable } from 'knt-shared';
214
+
215
+ const columns = [
118
216
  { title: '姓名', dataIndex: 'name' },
119
217
  { title: '年龄', dataIndex: 'age' },
120
- { title: '邮箱', dataIndex: 'email' },
121
218
  ];
122
219
 
123
- const handlePageChange = (page: number) => {
124
- console.log('页码变化:', page);
125
- // 加载数据
220
+ const searchSchemas = [
221
+ { field: 'name', label: '姓名', component: 'Input' },
222
+ ];
223
+
224
+ const loadData = async (params: any) => {
225
+ const response = await fetchData(params);
226
+ return {
227
+ data: response.list,
228
+ total: response.total,
229
+ };
126
230
  };
231
+ </script>
232
+ ```
127
233
 
128
- // 使用 request 属性自动加载数据
129
- const tableWithRequest = {
234
+ **使用 Hook:**
235
+
236
+ ```vue
237
+ <template>
238
+ <BasicTable @register="register" />
239
+ </template>
240
+
241
+ <script setup lang="ts">
242
+ import { BasicTable, useTable } from 'knt-shared';
243
+
244
+ const [register, { reload, setTableData }] = useTable({
130
245
  columns,
131
- request: async (params: Record<string, any>) => {
132
- // 调用 API
133
- const response = await fetchData(params);
134
- return {
135
- data: response.list,
136
- total: response.total,
137
- };
138
- },
246
+ request: loadData,
247
+ });
248
+
249
+ // 重新加载数据
250
+ const refresh = () => {
251
+ reload();
139
252
  };
140
253
  </script>
141
254
  ```
142
255
 
143
256
  ### Modal 模态框组件
144
257
 
258
+ 模态框组件,支持拖拽、全屏、异步操作、数据传递等功能。
259
+
260
+ **基础使用:**
261
+
145
262
  ```vue
146
263
  <template>
147
264
  <div>
148
- <a-button @click="openModal">打开模态框</a-button>
149
- <Modal
150
- v-model:visible="visible"
151
- title="编辑信息"
152
- @ok="handleOk"
153
- @cancel="handleCancel"
154
- >
155
- <a-form :model="formData">
156
- <a-form-item label="姓名">
157
- <a-input v-model="formData.name" />
158
- </a-form-item>
159
- </a-form>
160
- </Modal>
265
+ <a-button @click="openModal(true)">打开模态框</a-button>
266
+ <MyModal @register="register" />
161
267
  </div>
162
268
  </template>
163
269
 
164
270
  <script setup lang="ts">
165
- import { ref } from 'vue';
166
- import { Modal } from 'knt-shared';
271
+ import { useModal } from 'knt-shared';
272
+ import MyModal from './MyModal.vue';
167
273
 
168
- const visible = ref(false);
169
- const formData = ref({ name: '' });
274
+ const [register, { openModal }] = useModal();
275
+ </script>
276
+ ```
170
277
 
171
- const openModal = () => {
172
- visible.value = true;
173
- };
278
+ **模态框组件定义:**
174
279
 
175
- const handleOk = () => {
176
- console.log('确定', formData.value);
177
- visible.value = false;
178
- };
280
+ ```vue
281
+ <!-- MyModal.vue -->
282
+ <template>
283
+ <BasicModal v-bind="$attrs" title="编辑信息" @ok="handleOk">
284
+ <a-form :model="formData">
285
+ <a-form-item label="姓名">
286
+ <a-input v-model="formData.name" />
287
+ </a-form-item>
288
+ </a-form>
289
+ </BasicModal>
290
+ </template>
179
291
 
180
- const handleCancel = () => {
181
- console.log('取消');
182
- };
292
+ <script setup lang="ts">
293
+ import { BasicModal, useModalInner } from 'knt-shared';
294
+ import { reactive } from 'vue';
295
+
296
+ const formData = reactive({ name: '' });
297
+
298
+ const [register, { closeModal, changeOkLoading }] = useModalInner((data) => {
299
+ // 接收传递的数据
300
+ if (data) {
301
+ formData.name = data.name;
302
+ }
303
+ });
183
304
 
184
- // 使用 ref 控制模态框
185
- const modalRef = ref();
186
- modalRef.value?.open(); // 打开
187
- modalRef.value?.close(); // 关闭
305
+ const handleOk = async () => {
306
+ changeOkLoading(true);
307
+ try {
308
+ // 异步操作
309
+ await saveData(formData);
310
+ closeModal();
311
+ } finally {
312
+ changeOkLoading(false);
313
+ }
314
+ };
188
315
  </script>
189
316
  ```
190
317
 
191
- ### 工具函数
318
+ **传递数据:**
319
+
320
+ ```typescript
321
+ // 打开模态框并传递数据
322
+ const [register, { openModal }] = useModal();
323
+ openModal(true, { name: '张三' });
324
+ ```
192
325
 
193
- ```ts
194
- import { formatDate, formatNumber, isValidEmail } from 'knt-shared';
326
+ ## 🔧 工具函数
195
327
 
196
- // 格式化日期
197
- const dateStr = formatDate(new Date(), 'YYYY-MM-DD');
328
+ ### 验证工具
198
329
 
199
- // 格式化数字
200
- const numStr = formatNumber(1234567); // "1,234,567"
330
+ ```typescript
331
+ import { isValidEmail, isValidPhone, isValidUrl, isValidIdCard } from 'knt-shared';
201
332
 
202
333
  // 验证邮箱
203
- const isValid = isValidEmail('test@example.com');
334
+ isValidEmail('test@example.com'); // true
335
+
336
+ // 验证手机号(中国大陆)
337
+ isValidPhone('13800138000'); // true
338
+
339
+ // 验证 URL
340
+ isValidUrl('https://example.com'); // true
341
+
342
+ // 验证身份证号(中国大陆18位)
343
+ isValidIdCard('110101199001011234'); // true
204
344
  ```
205
345
 
206
- ### Hooks (Composition API)
346
+ ### 防抖工具
347
+
348
+ ```typescript
349
+ import { debounce } from 'knt-shared';
350
+
351
+ // 创建防抖函数
352
+ const debouncedFn = debounce((value: string) => {
353
+ console.log('搜索:', value);
354
+ }, 300);
355
+
356
+ // 使用
357
+ debouncedFn('关键词');
358
+ ```
359
+
360
+ ## 🪝 Hooks (Composition API)
361
+
362
+ ### useDebounce - 防抖
207
363
 
208
364
  ```vue
209
365
  <template>
210
366
  <div>
211
- <input v-model="inputValue" />
212
- <p>防抖值: {{ debouncedValue }}</p>
367
+ <a-input v-model="inputValue" placeholder="输入搜索关键词" />
368
+ <p>防抖后的值: {{ debouncedValue }}</p>
213
369
  </div>
214
370
  </template>
215
371
 
216
372
  <script setup lang="ts">
217
373
  import { ref } from 'vue';
218
- import { useDebounce, useLocalStorage, useToggle } from 'knt-shared';
374
+ import { useDebounce } from 'knt-shared';
219
375
 
220
376
  const inputValue = ref('');
221
377
  const debouncedValue = useDebounce(inputValue, 500);
378
+ </script>
379
+ ```
380
+
381
+ ### useToggle - 布尔值切换
382
+
383
+ ```vue
384
+ <template>
385
+ <div>
386
+ <p>状态: {{ isOpen }}</p>
387
+ <a-button @click="toggle">切换</a-button>
388
+ <a-button @click="setTrue">打开</a-button>
389
+ <a-button @click="setFalse">关闭</a-button>
390
+ </div>
391
+ </template>
222
392
 
223
- const [stored, setStored] = useLocalStorage('key', 'default');
393
+ <script setup lang="ts">
394
+ import { useToggle } from 'knt-shared';
224
395
 
225
- const [isOpen, toggle, open, close] = useToggle(false);
396
+ const [isOpen, toggle, setTrue, setFalse] = useToggle(false);
226
397
  </script>
227
398
  ```
228
399
 
229
- ## 开发
400
+ ### useLocalStorage - 本地存储
401
+
402
+ ```vue
403
+ <script setup lang="ts">
404
+ import { useLocalStorage } from 'knt-shared';
405
+
406
+ const [stored, setStored] = useLocalStorage('myKey', 'defaultValue');
407
+
408
+ // 读取值
409
+ console.log(stored.value);
410
+
411
+ // 设置值
412
+ setStored('newValue');
413
+ </script>
414
+ ```
415
+
416
+ ### 组件 Hooks
417
+
418
+ - **useForm** - 表单控制
419
+ - **useTable** - 表格控制
420
+ - **useModal** - 模态框外部控制
421
+ - **useModalInner** - 模态框内部控制
422
+ - **useDescription** - 详情组件控制
423
+
424
+ ## 🛠️ 开发
425
+
426
+ ### 安装依赖
230
427
 
231
428
  ```bash
232
- # 安装依赖
233
- npm install
429
+ pnpm install
430
+ ```
431
+
432
+ ### 构建
234
433
 
235
- # 构建
236
- npm run build
434
+ ```bash
435
+ # 构建库
436
+ pnpm run build
237
437
 
238
438
  # 开发模式(监听文件变化)
239
- npm run dev
439
+ pnpm run dev
240
440
  ```
241
441
 
242
- ## Playground 测试环境
243
-
244
- 项目包含一个 playground 目录,用于测试和演示组件:
442
+ ### 发布
245
443
 
246
444
  ```bash
247
- cd playground
248
- npm install
249
- npm run dev
445
+ pnpm run prepublishOnly
446
+ pnpm publish
250
447
  ```
251
448
 
252
- 访问 http://localhost:3000 查看所有组件的测试和演示。
449
+ ## 🎮 Playground 测试环境
253
450
 
254
- ## 发布
451
+ 项目包含一个 `playground` 目录,用于测试和演示所有组件:
255
452
 
256
453
  ```bash
257
- npm publish
454
+ cd playground
455
+ pnpm install
456
+ pnpm run dev
258
457
  ```
259
458
 
459
+ 访问 http://localhost:5173 查看所有组件的测试和演示。
460
+
461
+ ### Playground 包含的示例
462
+
463
+ **Description 组件:**
464
+ - 基础示例
465
+ - 自定义渲染
466
+ - 动态控制
467
+
468
+ **Form 组件:**
469
+ - 基础表单
470
+ - 使用 Hook 配置
471
+ - 性能测试
472
+
473
+ **Table 组件:**
474
+ - 基础表格
475
+ - 搜索表格
476
+ - 操作列
477
+ - 自定义渲染
478
+ - 使用 Hook
479
+
480
+ **Modal 组件:**
481
+ - 基础弹窗
482
+ - 数据传递
483
+ - 异步操作
484
+ - 自定义底部
485
+ - Loading 状态
486
+ - 内部控制
487
+
488
+ ## 📖 文档
489
+
490
+ 每个组件都包含详细的文档:
491
+
492
+ - **Description**: `src/components/Description/README.md`
493
+ - **Form**: `src/components/Form/修复总结.md`
494
+ - **Table**: `src/components/Table/TABLE.md`
495
+ - **Modal**: `src/components/Modal/MODAL.md`
496
+
497
+ ## 🤝 贡献
498
+
499
+ 欢迎提交 Issue 和 Pull Request!
500
+
501
+ ## 📄 License
502
+
503
+ MIT
504
+
505
+ ## 👨‍💻 作者
506
+
507
+ hss
508
+
509
+ ## 🔗 相关链接
510
+
511
+ - [GitHub Repository](https://github.com/Noah-Neverland/knt-shard)
512
+ - [Arco Design Vue](https://arco.design/vue)
513
+ - [Vben Admin](https://doc.vvbin.cn/components/introduction.html)
514
+