vue3-smart-table 0.0.4 → 1.0.0
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 +1220 -245
- package/dist/index.css +1 -0
- package/dist/vue3-smart-table.cjs.js +2 -21
- package/dist/vue3-smart-table.cjs.js.map +1 -0
- package/dist/vue3-smart-table.es.js +528 -381
- package/dist/vue3-smart-table.es.js.map +1 -0
- package/dist/vue3-smart-table.umd.js +3 -0
- package/dist/vue3-smart-table.umd.js.map +1 -0
- package/package.json +19 -6
- package/src/assets/vue.svg +1 -0
- package/src/components/SmartTable/column/index.vue +175 -0
- package/src/components/SmartTable/config.ts +131 -0
- package/src/components/SmartTable/hooks/useOperationColumn.ts +136 -0
- package/src/components/SmartTable/hooks/useTableColumns.ts +143 -0
- package/src/components/SmartTable/index.vue +91 -0
- package/src/components/SmartTable/renderer.ts +173 -0
- package/src/components/SmartTable/renderers/index.ts +307 -0
- package/src/components/SmartTable/renderers/input.vue +31 -0
- package/src/components/SmartTable/renderers/inputNumber.vue +33 -0
- package/src/components/SmartTable/renderers/select.vue +41 -0
- package/src/components/SmartTable/styles/theme.css +206 -0
- package/src/components/SmartTable/types.ts +237 -0
- package/src/components/SmartTable/utils/path.ts +29 -0
- package/src/index.ts +38 -0
- package/src/types/enhanced.ts +51 -0
- package/dist/vue3-smart-table.css +0 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { ButtonProps, TableColumnCtx } from 'element-plus'
|
|
2
|
+
import { DefaultRow } from 'element-plus/es/components/table/src/table/defaults'
|
|
3
|
+
import type { Component } from 'vue'
|
|
4
|
+
|
|
5
|
+
// 导出验证函数类型
|
|
6
|
+
export type { validateRendererProps } from './renderer'
|
|
7
|
+
|
|
8
|
+
/* ======================= 基础工具类型 ======================= */
|
|
9
|
+
|
|
10
|
+
/** 支持额外参数(Element Plus 透传 props) */
|
|
11
|
+
export type WithRestProps<T> = T & {
|
|
12
|
+
[key: string]: any
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* ======================= 渲染器系统 ======================= */
|
|
16
|
+
|
|
17
|
+
/** Renderer 组件类型 */
|
|
18
|
+
export type Renderer = Component
|
|
19
|
+
|
|
20
|
+
/** 渲染器注册表接口 */
|
|
21
|
+
export interface RendererRegistry {
|
|
22
|
+
register(name: string, renderer: Renderer): void
|
|
23
|
+
registerMultiple(renderers: Record<string, Renderer>): void
|
|
24
|
+
get(name: string): Renderer | undefined
|
|
25
|
+
has(name: string): boolean
|
|
26
|
+
unregister(name: string): boolean
|
|
27
|
+
clear(): void
|
|
28
|
+
names(): string[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 全局配置接口 */
|
|
32
|
+
export interface SmartTableConfig {
|
|
33
|
+
/** 自定义渲染器 */
|
|
34
|
+
renderers?: Record<string, Renderer>
|
|
35
|
+
/** 默认分页配置 */
|
|
36
|
+
defaultPagination?: {
|
|
37
|
+
page?: number
|
|
38
|
+
size?: number
|
|
39
|
+
total?: number
|
|
40
|
+
}
|
|
41
|
+
/** 默认表格属性 */
|
|
42
|
+
defaultTableProps?: Record<string, any>
|
|
43
|
+
/** 默认列属性 */
|
|
44
|
+
defaultColumnProps?: Record<string, any>
|
|
45
|
+
/** 主题配置 */
|
|
46
|
+
theme?: {
|
|
47
|
+
primaryColor?: string
|
|
48
|
+
successColor?: string
|
|
49
|
+
warningColor?: string
|
|
50
|
+
dangerColor?: string
|
|
51
|
+
infoColor?: string
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* ======================= 操作列按钮 ======================= */
|
|
56
|
+
|
|
57
|
+
export interface ButtonConfig<R = any> {
|
|
58
|
+
permission?: string | string[]
|
|
59
|
+
label: string
|
|
60
|
+
type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
|
61
|
+
action: (row: R) => void
|
|
62
|
+
visible?: (row: R) => boolean
|
|
63
|
+
width?: number
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* ======================= Renderer ======================= */
|
|
67
|
+
|
|
68
|
+
export type RendererName =
|
|
69
|
+
| 'html'
|
|
70
|
+
| 'copy'
|
|
71
|
+
| 'img'
|
|
72
|
+
| 'dict'
|
|
73
|
+
| 'map'
|
|
74
|
+
| 'formatter'
|
|
75
|
+
| 'icon'
|
|
76
|
+
| 'input'
|
|
77
|
+
| 'input-number'
|
|
78
|
+
| 'select'
|
|
79
|
+
| 'button'
|
|
80
|
+
| 'link'
|
|
81
|
+
| 'slot'
|
|
82
|
+
|
|
83
|
+
/** renderer 对应的 renderProps */
|
|
84
|
+
export interface RendererPropsMap {
|
|
85
|
+
html: WithRestProps<{
|
|
86
|
+
style?: string
|
|
87
|
+
class?: string
|
|
88
|
+
}>
|
|
89
|
+
|
|
90
|
+
copy: WithRestProps<{
|
|
91
|
+
/** 复制按钮图标颜色 */
|
|
92
|
+
iconColor?: string
|
|
93
|
+
/** 复制按钮提示文本 */
|
|
94
|
+
copyTitle?: string
|
|
95
|
+
/** 复制成功提示 */
|
|
96
|
+
successText?: string
|
|
97
|
+
/** 复制失败提示 */
|
|
98
|
+
errorText?: string
|
|
99
|
+
}>
|
|
100
|
+
|
|
101
|
+
img: WithRestProps<{
|
|
102
|
+
/** 图片宽度 */
|
|
103
|
+
width?: string | number
|
|
104
|
+
/** 图片高度 */
|
|
105
|
+
height?: string | number
|
|
106
|
+
/** 图片适应方式 */
|
|
107
|
+
fit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down'
|
|
108
|
+
/** 预览图片列表 */
|
|
109
|
+
previewSrcList?: string[]
|
|
110
|
+
/** 无图片时的占位文本 */
|
|
111
|
+
placeholder?: string
|
|
112
|
+
/** 自定义样式 */
|
|
113
|
+
style?: string
|
|
114
|
+
}>
|
|
115
|
+
|
|
116
|
+
dict: WithRestProps<{
|
|
117
|
+
/** 字典配置 */
|
|
118
|
+
options: Array<{
|
|
119
|
+
label: string
|
|
120
|
+
value: string | number
|
|
121
|
+
listClass?: string
|
|
122
|
+
cssClass?: string
|
|
123
|
+
}>
|
|
124
|
+
/** 是否显示未匹配的值 */
|
|
125
|
+
showValue?: boolean
|
|
126
|
+
}>
|
|
127
|
+
|
|
128
|
+
map: WithRestProps<{
|
|
129
|
+
/** key-value 映射 */
|
|
130
|
+
options: Record<string | number, any>
|
|
131
|
+
}>
|
|
132
|
+
|
|
133
|
+
formatter: never // formatter 使用 ColumnConfig.formatter 函数
|
|
134
|
+
|
|
135
|
+
icon: WithRestProps<{
|
|
136
|
+
/** 自定义样式 */
|
|
137
|
+
style?: string
|
|
138
|
+
/** 图标大小(像素) */
|
|
139
|
+
size?: number
|
|
140
|
+
/** 自定义类名 */
|
|
141
|
+
class?: string
|
|
142
|
+
}>
|
|
143
|
+
|
|
144
|
+
input: WithRestProps<{
|
|
145
|
+
/** 占位文本 */
|
|
146
|
+
placeholder?: string
|
|
147
|
+
/** 输入框尺寸 */
|
|
148
|
+
size?: 'small' | 'default' | 'large'
|
|
149
|
+
/** 是否可清空 */
|
|
150
|
+
clearable?: boolean
|
|
151
|
+
}>
|
|
152
|
+
|
|
153
|
+
'input-number': WithRestProps<{
|
|
154
|
+
/** 最小值 */
|
|
155
|
+
min?: number
|
|
156
|
+
/** 最大值 */
|
|
157
|
+
max?: number
|
|
158
|
+
/** 步长 */
|
|
159
|
+
step?: number
|
|
160
|
+
/** 精度 */
|
|
161
|
+
precision?: number
|
|
162
|
+
/** 输入框尺寸 */
|
|
163
|
+
size?: 'small' | 'default' | 'large'
|
|
164
|
+
/** 是否显示增减按钮 */
|
|
165
|
+
controls?: boolean
|
|
166
|
+
}>
|
|
167
|
+
|
|
168
|
+
select: WithRestProps<{
|
|
169
|
+
/** 选项配置 */
|
|
170
|
+
options: Array<{
|
|
171
|
+
label: string
|
|
172
|
+
value: string | number
|
|
173
|
+
}>
|
|
174
|
+
/** 占位文本 */
|
|
175
|
+
placeholder?: string
|
|
176
|
+
/** 选择器尺寸 */
|
|
177
|
+
size?: 'small' | 'default' | 'large'
|
|
178
|
+
/** 是否可清空 */
|
|
179
|
+
clearable?: boolean
|
|
180
|
+
}>
|
|
181
|
+
|
|
182
|
+
button: WithRestProps<ButtonProps & {
|
|
183
|
+
/** 按钮文本 */
|
|
184
|
+
label?: string
|
|
185
|
+
/** 自定义样式 */
|
|
186
|
+
style?: string
|
|
187
|
+
/** 自定义类名 */
|
|
188
|
+
class?: string
|
|
189
|
+
}>
|
|
190
|
+
|
|
191
|
+
link: WithRestProps<{
|
|
192
|
+
/** 链接文本 */
|
|
193
|
+
label?: string
|
|
194
|
+
/** 链接地址 */
|
|
195
|
+
href: string
|
|
196
|
+
/** 是否新窗口打开 */
|
|
197
|
+
blank?: boolean
|
|
198
|
+
/** 自定义样式 */
|
|
199
|
+
style?: string
|
|
200
|
+
/** 自定义类名 */
|
|
201
|
+
class?: string
|
|
202
|
+
}>
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* ======================= 列类型 ======================= */
|
|
206
|
+
|
|
207
|
+
export type ColumnType =
|
|
208
|
+
| 'default'
|
|
209
|
+
| 'selection'
|
|
210
|
+
| 'index'
|
|
211
|
+
| 'operation'
|
|
212
|
+
|
|
213
|
+
/* ======================= ColumnConfig ======================= */
|
|
214
|
+
export interface BaseColumn<R extends DefaultRow> {
|
|
215
|
+
key: keyof R & string
|
|
216
|
+
label?: string
|
|
217
|
+
visible?: boolean
|
|
218
|
+
inControl?: boolean
|
|
219
|
+
columnProps?: Partial<TableColumnCtx<R>>
|
|
220
|
+
render?: RendererName
|
|
221
|
+
slot?: string // 插槽名称,默认用 key
|
|
222
|
+
renderProps?: Partial<RendererPropsMap[keyof RendererPropsMap]>
|
|
223
|
+
buttons?: ButtonConfig<R>[] // operation 列专用
|
|
224
|
+
maxbtn?: number // operation 列专用
|
|
225
|
+
__rows?: R[] // operation 列内部使用
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface SelectionColumn<R extends DefaultRow> extends BaseColumn<R> { type: 'selection' }
|
|
229
|
+
export interface IndexColumn<R extends DefaultRow> extends BaseColumn<R> { type: 'index' }
|
|
230
|
+
export interface OperationColumn<R extends DefaultRow> extends BaseColumn<R> { type: 'operation'; buttons: ButtonConfig<R>[] }
|
|
231
|
+
export interface DataColumn<R extends DefaultRow> extends BaseColumn<R> { type?: 'default'; formatter?: (value: any, row: R) => any }
|
|
232
|
+
|
|
233
|
+
export type ColumnConfig<R extends DefaultRow = any> =
|
|
234
|
+
| SelectionColumn<R>
|
|
235
|
+
| IndexColumn<R>
|
|
236
|
+
| OperationColumn<R>
|
|
237
|
+
| DataColumn<R>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 安全获取对象深层属性
|
|
3
|
+
* 支持 a.b.c / a.0.b
|
|
4
|
+
*/
|
|
5
|
+
export function getValueByPath(obj: any, path?: string) {
|
|
6
|
+
if (!obj || !path) return undefined
|
|
7
|
+
return path.split('.').reduce((acc, key) => acc?.[key], obj)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 安全设置对象深层属性(用于可编辑表格)
|
|
12
|
+
*/
|
|
13
|
+
export function setValueByPath(
|
|
14
|
+
obj: any,
|
|
15
|
+
path: string,
|
|
16
|
+
value: any
|
|
17
|
+
) {
|
|
18
|
+
if (!obj || !path) return
|
|
19
|
+
const keys = path.split('.')
|
|
20
|
+
const lastKey = keys.pop()!
|
|
21
|
+
|
|
22
|
+
const target = keys.reduce((acc, key) => {
|
|
23
|
+
if (!acc[key]) acc[key] = {}
|
|
24
|
+
return acc[key]
|
|
25
|
+
}, obj)
|
|
26
|
+
|
|
27
|
+
target[lastKey] = value
|
|
28
|
+
}
|
|
29
|
+
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue3 Smart Table - 主入口文件
|
|
3
|
+
*
|
|
4
|
+
* 基于 Vue 3 + Element Plus 的高可复用表格组件库
|
|
5
|
+
*/
|
|
6
|
+
import SmartTable from './components/SmartTable/index.vue'
|
|
7
|
+
|
|
8
|
+
// 导出类型
|
|
9
|
+
export * from './components/SmartTable/types'
|
|
10
|
+
|
|
11
|
+
// 导出核心功能(从 SmartTable 内部导出)
|
|
12
|
+
export {
|
|
13
|
+
getRendererManager,
|
|
14
|
+
wrapSFCComponent,
|
|
15
|
+
createFunctionalRenderer,
|
|
16
|
+
validateRendererProps
|
|
17
|
+
} from './components/SmartTable/renderer'
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
setSmartTableConfig,
|
|
21
|
+
getSmartTableConfig
|
|
22
|
+
} from './components/SmartTable/config'
|
|
23
|
+
|
|
24
|
+
// 导出内置渲染器
|
|
25
|
+
export {
|
|
26
|
+
builtInRenderers,
|
|
27
|
+
registerBuiltInRenderers,
|
|
28
|
+
createRenderer
|
|
29
|
+
} from './components/SmartTable/renderers'
|
|
30
|
+
|
|
31
|
+
// 导出类型工具
|
|
32
|
+
export { defineColumn } from './types/enhanced'
|
|
33
|
+
|
|
34
|
+
// 导出主组件
|
|
35
|
+
export { SmartTable }
|
|
36
|
+
|
|
37
|
+
// 默认导出
|
|
38
|
+
export default SmartTable
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 增强类型系统 - 提供更好的类型推断
|
|
3
|
+
*/
|
|
4
|
+
import type { ColumnConfig, RendererName } from '../components/SmartTable/types'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 提取行数据的类型
|
|
8
|
+
*/
|
|
9
|
+
export type ExtractRowType<T> = T extends ColumnConfig<infer R> ? R : never
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 根据列配置提取表格数据类型
|
|
13
|
+
*/
|
|
14
|
+
export type TableDataFromColumns<T extends ColumnConfig[]> = T extends (infer C)[]
|
|
15
|
+
? C extends ColumnConfig<infer R>
|
|
16
|
+
? R
|
|
17
|
+
: any
|
|
18
|
+
: any
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 渲染器 Props 类型推断
|
|
22
|
+
*/
|
|
23
|
+
export type InferRendererProps<T extends RendererName> =
|
|
24
|
+
T extends 'html'
|
|
25
|
+
? { style?: string; class?: string; [key: string]: any }
|
|
26
|
+
: T extends 'copy'
|
|
27
|
+
? { successText?: string; errorText?: string; iconColor?: string; [key: string]: any }
|
|
28
|
+
: T extends 'img'
|
|
29
|
+
? { width?: string | number; height?: string | number; fit?: string; previewSrcList?: string[]; [key: string]: any }
|
|
30
|
+
: T extends 'dict'
|
|
31
|
+
? { options: Array<{ label: string; value: string | number; listClass?: string; cssClass?: string }>; showValue?: boolean }
|
|
32
|
+
: T extends 'map'
|
|
33
|
+
? { options: Record<string | number, any> }
|
|
34
|
+
: T extends 'input'
|
|
35
|
+
? { placeholder?: string; size?: 'small' | 'default' | 'large'; clearable?: boolean }
|
|
36
|
+
: T extends 'select'
|
|
37
|
+
? { options: Array<{ label: string; value: string | number }>; placeholder?: string; clearable?: boolean }
|
|
38
|
+
: { [key: string]: any }
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 快捷创建列的辅助函数(类型安全简化版)
|
|
42
|
+
*/
|
|
43
|
+
export function defineColumn(
|
|
44
|
+
key: string,
|
|
45
|
+
config?: Partial<Omit<ColumnConfig, 'key'>>
|
|
46
|
+
): ColumnConfig {
|
|
47
|
+
return {
|
|
48
|
+
key,
|
|
49
|
+
...config
|
|
50
|
+
} as ColumnConfig
|
|
51
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.copy-wrapper:hover .copy-btn{display:inline-block!important}.smart-table[data-v-7c94ec39]{width:100%}
|