@xmszm/core 0.0.1 → 0.0.3

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 (77) hide show
  1. package/README.md +187 -0
  2. package/dist/index.cjs +2 -2
  3. package/dist/index.mjs +1431 -1170
  4. package/dist/plugin/vite/initRouteMeta.cjs +1 -0
  5. package/dist/plugin/vite/initRouteMeta.mjs +13 -0
  6. package/dist/style.css +1 -1
  7. package/docs/.vitepress/config.mjs +91 -0
  8. package/docs/components/config-options.md +125 -0
  9. package/docs/components/dataform.md +176 -23
  10. package/docs/components/datatable.md +58 -39
  11. package/docs/components/dialog.md +158 -19
  12. package/docs/components/options.md +44 -15
  13. package/docs/components/query.md +68 -14
  14. package/docs/components/utils.md +124 -16
  15. package/docs/guide/changelog.md +81 -0
  16. package/docs/guide/config.md +415 -0
  17. package/docs/guide/demo.md +2 -2
  18. package/docs/guide/local-development.md +109 -0
  19. package/docs/guide/quickstart.md +40 -11
  20. package/docs/index.md +3 -3
  21. package/docs/usage.md +30 -6
  22. package/examples/README.md +46 -0
  23. package/examples/index.html +14 -0
  24. package/examples/package.json +25 -0
  25. package/examples/pnpm-lock.yaml +1569 -0
  26. package/examples/pnpm-workspace.yaml +3 -0
  27. package/examples/src/AdminSystem.vue +870 -0
  28. package/examples/src/App.vue +330 -0
  29. package/examples/src/Introduction.vue +307 -0
  30. package/examples/src/main.js +22 -0
  31. package/examples/src/utils/permission.js +16 -0
  32. package/examples/src/utils/request.js +10 -0
  33. package/examples/vite.config.js +41 -0
  34. package/package.json +13 -4
  35. package/src/dialog/commonDialog.tsx +285 -0
  36. package/src/dialog/useCommonDialog.ts +41 -0
  37. package/src/dialog/utils/{dialog.js → dialog.ts} +2 -0
  38. package/src/directives/auto-register.ts +57 -0
  39. package/src/directives/permission.ts +67 -0
  40. package/src/enum/sort.tsx +45 -0
  41. package/src/form/DataForm.vue +34 -52
  42. package/src/index.ts +58 -0
  43. package/src/list/{useList.jsx → useList.tsx} +49 -14
  44. package/src/options/{Options.jsx → Options.tsx} +86 -72
  45. package/src/options/defaultOptions.tsx +656 -0
  46. package/src/plugin/index.ts +20 -0
  47. package/src/query/CommonQuery.vue +65 -90
  48. package/src/table/DataTable.vue +82 -95
  49. package/src/table/opr/{DataColumnCollet.jsx → DataColumnCollet.tsx} +18 -8
  50. package/src/table/opr/useDataColumn.tsx +226 -0
  51. package/src/table/opr/{useDataColumnButton.jsx → useDataColumnButton.tsx} +13 -6
  52. package/src/table/opr/{useDataColumnPop.jsx → useDataColumnPop.tsx} +13 -5
  53. package/src/table/opr/useQRCode.ts +40 -0
  54. package/src/utils/{array.js → array.ts} +4 -6
  55. package/src/utils/config.ts +192 -0
  56. package/src/utils/dialog.ts +110 -0
  57. package/src/utils/{object.js → object.ts} +1 -0
  58. package/src/utils/upload.ts +53 -0
  59. package/types/auto-imports.d.ts +78 -0
  60. package/types/components.d.ts +402 -0
  61. package/types/index.d.ts +145 -7
  62. package/types/plugin/vite/initRouteMeta.d.ts +23 -0
  63. package/types/src.d.ts +55 -0
  64. package/types/vue-shim.d.ts +9 -0
  65. package/examples/demo.vue +0 -224
  66. package/src/dialog/commonDialog.jsx +0 -230
  67. package/src/enum/sort.jsx +0 -31
  68. package/src/index.js +0 -46
  69. package/src/options/defaultOptions.jsx +0 -580
  70. package/src/table/opr/useDataColumn.jsx +0 -196
  71. package/src/utils/upload.js +0 -46
  72. /package/src/enum/{options.js → options.ts} +0 -0
  73. /package/src/plugin/vite/{initRouteMeta.js → initRouteMeta.ts} +0 -0
  74. /package/src/store/utils/{index.js → index.ts} +0 -0
  75. /package/src/table/utils/{ellipsis.js → ellipsis.ts} +0 -0
  76. /package/src/utils/{auth.js → auth.ts} +0 -0
  77. /package/src/utils/{time.js → time.ts} +0 -0
@@ -0,0 +1,41 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+ import vueJsx from '@vitejs/plugin-vue-jsx'
4
+ import path from 'path'
5
+
6
+ // 插件:重定向 @xmszm/core 中的 @/ 路径到项目 src
7
+ const redirectExternalImports = () => {
8
+ return {
9
+ name: 'redirect-external-imports',
10
+ resolveId(id, importer) {
11
+ // 如果是从 @xmszm/core 导入的 @/ 路径,重定向到项目 src
12
+ if (importer && importer.includes('@xmszm/core') && id.startsWith('@/')) {
13
+ const resolvedPath = path.resolve(__dirname, 'src', id.replace('@/', ''))
14
+ return resolvedPath
15
+ }
16
+ return null
17
+ },
18
+ }
19
+ }
20
+
21
+ export default defineConfig({
22
+ base: '/core/examples/',
23
+ plugins: [vue(), vueJsx(), redirectExternalImports()],
24
+ resolve: {
25
+ alias: {
26
+ '@': path.resolve(__dirname, 'src'),
27
+ '@xmszm/core': path.resolve(__dirname, '..'),
28
+ '@xmszm/core/dist/style.css': path.resolve(__dirname, '../dist/style.css'),
29
+ },
30
+ dedupe: ['vue'],
31
+ },
32
+ build: {
33
+ outDir: 'dist',
34
+ assetsDir: 'assets',
35
+ },
36
+ server: {
37
+ port: 3000,
38
+ open: true
39
+ }
40
+ })
41
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmszm/core",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "naiveui core 组件与工具库",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.cjs",
@@ -18,8 +18,15 @@
18
18
  ".": {
19
19
  "import": "./dist/index.mjs",
20
20
  "require": "./dist/index.cjs",
21
+ "style": "./dist/style.css",
21
22
  "types": "./types/index.d.ts"
22
23
  },
24
+ "./plugin/vite/initRouteMeta": {
25
+ "import": "./dist/plugin/vite/initRouteMeta.mjs",
26
+ "require": "./dist/plugin/vite/initRouteMeta.cjs",
27
+ "types": "./types/plugin/vite/initRouteMeta.d.ts"
28
+ },
29
+ "./dist/style.css": "./dist/style.css",
23
30
  "./package.json": "./package.json"
24
31
  },
25
32
  "files": [
@@ -45,6 +52,8 @@
45
52
  "vue-router": "^4.2.0"
46
53
  },
47
54
  "devDependencies": {
55
+ "@types/node": "^20.0.0",
56
+ "@unocss/vite": "^66.5.10",
48
57
  "@vicons/ionicons5": "^0.13.0",
49
58
  "@vitejs/plugin-vue": "^5.1.2",
50
59
  "@vitejs/plugin-vue-jsx": "^4.0.1",
@@ -53,12 +62,12 @@
53
62
  "lodash-es": "^4.17.21",
54
63
  "naive-ui": "^2.38.0",
55
64
  "rimraf": "^6.0.1",
65
+ "typescript": "^5.0.0",
66
+ "unocss": "^66.5.10",
67
+ "unplugin-auto-import": "^20.3.0",
56
68
  "vite": "^5.4.0",
57
69
  "vitepress": "^1.2.3",
58
70
  "vue": "^3.3.0",
59
71
  "vue-router": "^4.2.0"
60
- },
61
- "dependencies": {
62
- "npm": "^11.7.0"
63
72
  }
64
73
  }
@@ -0,0 +1,285 @@
1
+ import { NButton, NSpace, useDialog, createDiscreteApi } from 'naive-ui'
2
+ import type { DialogApi } from 'naive-ui'
3
+ import { reactive, ref, unref, defineComponent } from 'vue'
4
+ import type { Ref, VNode } from 'vue'
5
+ import type { CommonDialogOptions, DialogAction } from '../../types/components'
6
+ import type { CommonDialogResult } from '../../types'
7
+ import DataForm from '../form/DataForm.vue'
8
+ import { dialogDefaultOption } from './utils/dialog'
9
+ import './style/commonDialog.less'
10
+
11
+ // 声明全局 $dialog 变量(外部可能注入)
12
+ declare global {
13
+ // eslint-disable-next-line no-var
14
+ var $dialog: DialogApi | undefined
15
+ }
16
+
17
+ // 全局缓存 dialog 实例,避免重复创建离散 API
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ let globalDialogInstance: any = null
20
+ let discreteDialogFactory: { dialog: any } | null = null
21
+
22
+ function getDialogInstanceOnce(): any {
23
+ if (globalDialogInstance)
24
+ return globalDialogInstance
25
+
26
+ // 1. 检查全局 $dialog
27
+ if (typeof $dialog !== 'undefined' && $dialog) {
28
+ globalDialogInstance = $dialog
29
+ return globalDialogInstance
30
+ }
31
+
32
+ // 2. 组件上下文中尝试 useDialog(若无上下文会抛错)
33
+ try {
34
+ const dialog = useDialog()
35
+ if (dialog) {
36
+ globalDialogInstance = dialog
37
+ return globalDialogInstance
38
+ }
39
+ }
40
+ catch (e) {
41
+ // 忽略,继续尝试离散 API
42
+ }
43
+
44
+ // 3. 使用离散 API,且只创建一次
45
+ if (!discreteDialogFactory) {
46
+ const { dialog } = createDiscreteApi(['dialog'])
47
+ discreteDialogFactory = { dialog }
48
+ }
49
+ globalDialogInstance = discreteDialogFactory.dialog
50
+ return globalDialogInstance
51
+ }
52
+
53
+ /**
54
+ * 集成填写表单功能的弹窗
55
+ * @param param - 弹窗配置选项
56
+ * @param dialogProps - 传递给 NDialog 的属性
57
+ * @returns 弹窗控制对象 {cancel, setValue, model, modeEnum}
58
+ */
59
+ export function commonDialogMethod(
60
+ {
61
+ title = '',
62
+ noTitle = false,
63
+ titleFull = null,
64
+ options = [],
65
+ mode = 'add',
66
+ modeEnum = {},
67
+ labelField = 'label',
68
+ isNo = true,
69
+ formProps = {},
70
+ interfaceFn = null,
71
+ interfaceFnCancel = null,
72
+ valueData,
73
+ read,
74
+ isRead,
75
+ action = null,
76
+ contentStyle = {},
77
+ actionProps = {},
78
+ }: CommonDialogOptions = {
79
+ title: '自定义弹窗',
80
+ noTitle: false,
81
+ action: [],
82
+ options: [],
83
+ read: false,
84
+ isRead: false,
85
+ valueData: {},
86
+ },
87
+ dialogProps: Record<string, any> | null = null,
88
+ ): CommonDialogResult {
89
+ // 优先使用外部注册的 $dialog;再尝试组件上下文 useDialog;再退回离散 API(仅全局创建一次)
90
+ const dialogInstance = getDialogInstanceOnce()
91
+
92
+ const defaultModeEnum: Record<string, { sub?: string; read?: boolean }> = {
93
+ none: { sub: '', read: false },
94
+ create: { sub: '创建', read: false },
95
+ add: { sub: '添加', read: false },
96
+ edit: { sub: '编辑', read: false },
97
+ view: { sub: '查看', read: true },
98
+ export: { sub: '导出', read: false },
99
+ import: { sub: '导入', read: false },
100
+ delete: { sub: '删除', read: false },
101
+ copy: { sub: '复制', read: false },
102
+ ...modeEnum,
103
+ }
104
+ const formRef: Ref<any> = ref()
105
+ const actionLoading = reactive<boolean[]>([])
106
+ const model = ref({ ...valueData })
107
+ const defaultActionProps = {
108
+ justify: 'end' as 'end',
109
+ wrapItem: false,
110
+ style: {
111
+ width: '100%',
112
+ },
113
+ }
114
+
115
+ const defaultButtonStyle = {
116
+ width: '120px',
117
+ }
118
+ const defaultAction: DialogAction[] = [
119
+ {
120
+ label: '取消',
121
+ props: {
122
+ type: 'primary',
123
+ ghost: true,
124
+ },
125
+ onClick: ({ cancel }) => {
126
+ if (interfaceFnCancel) {
127
+ interfaceFnCancel(unref(model), {
128
+ close: cancel,
129
+ })
130
+ } else {
131
+ cancel()
132
+ }
133
+ },
134
+ },
135
+ {
136
+ label: '确定',
137
+ valid: true,
138
+ onClick: async ({ cancel, hideLoading }) =>
139
+ interfaceFn
140
+ ? await interfaceFn(unref(model), {
141
+ close: cancel,
142
+ hideLoading,
143
+ })
144
+ : cancel(),
145
+ },
146
+ ];
147
+
148
+ (Array.isArray(action) ? action : defaultAction).forEach((v, i) => {
149
+ actionLoading[i] = false
150
+ })
151
+ const titleRender = typeof titleFull === 'function'
152
+ ? () => titleFull(defaultModeEnum[mode]?.sub || '')
153
+ : titleFull
154
+
155
+ // 使用 ref 存储 dialog 实例,以便在函数中访问
156
+ const dialogRef: Ref<any> = ref()
157
+
158
+ function cancel(): void {
159
+ console.log('取消', model.value)
160
+ dialogRef.value?.destroy()
161
+ }
162
+
163
+ async function validate(arr: string[] = []): Promise<void> {
164
+ console.log('开启验证')
165
+ await formRef.value?.valid()
166
+ }
167
+
168
+ async function comfirm(fn?: () => any): Promise<any> {
169
+ return fn && fn()
170
+ }
171
+
172
+ const renderAction = !(read ?? isRead)
173
+ ? typeof action === 'function'
174
+ ? () => action({ formRef, data: unref(model), d: dialogRef.value, close: cancel })
175
+ : () => (
176
+ <NSpace
177
+ {...defaultActionProps}
178
+ {...actionProps}
179
+ style={{
180
+ ...defaultActionProps?.style,
181
+ ...(actionProps?.style || {}),
182
+ }}
183
+ >
184
+ {(Array.isArray(action) ? action : defaultAction).map((v, i) =>
185
+ v?.render
186
+ ? (
187
+ v?.render?.()
188
+ )
189
+ : (
190
+ <NButton
191
+ type="primary"
192
+ ghost={v.mode === 'cancel'}
193
+ {...(v?.props || {})}
194
+ {...(actionProps?.buttonProps || {})}
195
+ style={{ ...defaultButtonStyle, ...(v?.style || {}) }}
196
+ loading={actionLoading[i]}
197
+ onClick={async () => {
198
+ if (v.mode === 'cancel') {
199
+ dialogRef.value?.destroy()
200
+ }
201
+ else {
202
+ const showLoading = () => (actionLoading[i] = true)
203
+ const hideLoading = () => (actionLoading[i] = false)
204
+ if (v?.loading)
205
+ showLoading()
206
+ try {
207
+ console.log('model', unref(model))
208
+
209
+ if (v?.valid)
210
+ await validate()
211
+ console.log(v?.valid)
212
+ if (v?.valid || v?.loading)
213
+ showLoading()
214
+ await v?.onClick?.({
215
+ model: unref(model),
216
+ comfirm,
217
+ cancel,
218
+ validate,
219
+ showLoading,
220
+ hideLoading,
221
+ })
222
+ }
223
+ catch (e) {
224
+ console.log(e)
225
+ }
226
+ finally {
227
+ if (v?.valid || v?.loading)
228
+ hideLoading()
229
+ }
230
+ }
231
+ }}
232
+ >
233
+ {v.label || ''}
234
+ </NButton>
235
+ ),
236
+ )}
237
+ </NSpace>
238
+ )
239
+ : null
240
+
241
+ const d = dialogInstance.create({
242
+ type: 'info',
243
+ ...dialogDefaultOption,
244
+ ...(!noTitle
245
+ ? { title: titleRender || (defaultModeEnum[mode]?.sub ?? '') + title }
246
+ : {}),
247
+ style: {
248
+ width: '500px',
249
+ },
250
+ content: () => (
251
+ <DataForm
252
+ ref={(v: any) => {
253
+ formRef.value = v
254
+ }}
255
+ options={options}
256
+ v-model:value={model}
257
+ isNo={isNo}
258
+ read={read ?? isRead}
259
+ labelField={labelField}
260
+ formProps={formProps}
261
+ contentStyle={contentStyle}
262
+ dialog
263
+ />
264
+ ),
265
+ action: renderAction,
266
+ // ...readButton.value,
267
+ ...dialogProps,
268
+ class: `core-dialog ${(read ?? isRead) ? 'core-dialog-read' : ''} ${dialogProps?.class || ''}`,
269
+ })
270
+
271
+ // 将 dialog 实例存储到 ref 中
272
+ dialogRef.value = d
273
+
274
+ // onBeforeUnmount(() => {
275
+ // console.log('commomDialog end')
276
+ // cancel()
277
+ // })
278
+
279
+ return {
280
+ cancel,
281
+ setValue: (v: any, str?: string) => str ? (model.value[str] = v) : (model.value = { ...model.value, ...v }),
282
+ model: unref(model),
283
+ modeEnum: defaultModeEnum
284
+ };
285
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * useCommonDialog Hook
3
+ * 在组件中使用 commonDialogMethod 的便捷方式
4
+ */
5
+ import { useDialog } from 'naive-ui'
6
+ import { commonDialogMethod } from './commonDialog'
7
+ import { registerDialogInstance } from '../utils/config'
8
+
9
+ /**
10
+ * 使用 commonDialog 的 Hook
11
+ * @returns {Function} openDialog 函数
12
+ *
13
+ * @example
14
+ * import { useCommonDialog } from '@xmszm/core'
15
+ *
16
+ * export default defineComponent({
17
+ * setup() {
18
+ * const openDialog = useCommonDialog()
19
+ *
20
+ * const handleEdit = () => {
21
+ * openDialog({
22
+ * title: '编辑',
23
+ * options: [...],
24
+ * })
25
+ * }
26
+ *
27
+ * return { handleEdit }
28
+ * }
29
+ * })
30
+ */
31
+ export function useCommonDialog() {
32
+ const dialog = useDialog()
33
+
34
+ // 注册 dialog 实例到全局配置,这样 commonDialogMethod 可以直接使用
35
+ registerDialogInstance(dialog)
36
+
37
+ return (options, dialogProps) => {
38
+ return commonDialogMethod(options, dialogProps)
39
+ }
40
+ }
41
+
@@ -1,3 +1,5 @@
1
+ import { computed, unref } from 'vue'
2
+
1
3
  export const dialogDefaultOption = {
2
4
  showIcon: false,
3
5
  autoFocus: false,
@@ -0,0 +1,57 @@
1
+ /**
2
+ * 自动注册指令
3
+ * 在导入库时自动注册所有指令,无需手动配置
4
+ */
5
+ import { permissionDirective } from './permission'
6
+
7
+ // 全局应用实例缓存
8
+ let globalApp = null
9
+
10
+ /**
11
+ * 注册所有指令到应用实例
12
+ * @param {Object} app - Vue 应用实例
13
+ */
14
+ export function registerDirectives(app) {
15
+ if (!app) return
16
+
17
+ // 缓存应用实例
18
+ globalApp = app
19
+
20
+ // 只注册内部的 corePermission 指令
21
+ // 外部如果需要 v-permission,可以自己注册,与内部无关
22
+ if (!app._context.directives?.corePermission) {
23
+ app.directive('corePermission', permissionDirective)
24
+ }
25
+ }
26
+
27
+ /**
28
+ * 尝试自动注册指令
29
+ * 通过 getCurrentInstance 获取应用实例并注册
30
+ */
31
+ export function autoRegisterDirectives() {
32
+ try {
33
+ // 动态导入 vue,避免在构建时出错
34
+ const vue = typeof require !== 'undefined' ? require('vue') : null
35
+ if (!vue) return false
36
+
37
+ const { getCurrentInstance } = vue
38
+ const instance = getCurrentInstance?.()
39
+
40
+ if (instance?.appContext?.app) {
41
+ registerDirectives(instance.appContext.app)
42
+ return true
43
+ }
44
+ } catch (e) {
45
+ // 忽略错误,可能不在组件上下文中
46
+ }
47
+
48
+ return false
49
+ }
50
+
51
+ /**
52
+ * 获取全局应用实例
53
+ */
54
+ export function getGlobalApp() {
55
+ return globalApp
56
+ }
57
+
@@ -0,0 +1,67 @@
1
+ import { checkPermission } from '../utils/config'
2
+
3
+ /**
4
+ * 权限指令
5
+ * 根据权限标识控制元素的显示/隐藏
6
+ *
7
+ * @example
8
+ * <div v-corePermission="'user:edit'">编辑按钮</div>
9
+ * <div v-corePermission="['user:edit', 'user:view']">需要编辑或查看权限</div>
10
+ */
11
+ export const permissionDirective = {
12
+ mounted(el, binding) {
13
+ const permission = binding.value
14
+
15
+ if (!permission) {
16
+ // 如果没有权限标识,默认显示
17
+ return
18
+ }
19
+
20
+ // 支持字符串或数组
21
+ const permissions = Array.isArray(permission) ? permission : [permission]
22
+
23
+ // 检查是否有任一权限
24
+ const hasPermission = permissions.some(p => checkPermission(p))
25
+
26
+ if (!hasPermission) {
27
+ // 没有权限时隐藏元素
28
+ el.style.display = 'none'
29
+ // 保存原始 display 值,以便后续恢复
30
+ el._originalDisplay = el.style.display || ''
31
+ }
32
+ },
33
+
34
+ updated(el, binding) {
35
+ const permission = binding.value
36
+
37
+ if (!permission) {
38
+ // 恢复显示
39
+ if (el._originalDisplay !== undefined) {
40
+ el.style.display = el._originalDisplay || ''
41
+ } else {
42
+ el.style.display = ''
43
+ }
44
+ return
45
+ }
46
+
47
+ const permissions = Array.isArray(permission) ? permission : [permission]
48
+ const hasPermission = permissions.some(p => checkPermission(p))
49
+
50
+ if (!hasPermission) {
51
+ el.style.display = 'none'
52
+ } else {
53
+ // 恢复显示
54
+ if (el._originalDisplay !== undefined) {
55
+ el.style.display = el._originalDisplay || ''
56
+ } else {
57
+ el.style.display = ''
58
+ }
59
+ }
60
+ },
61
+
62
+ unmounted(el) {
63
+ // 清理
64
+ delete el._originalDisplay
65
+ },
66
+ }
67
+
@@ -0,0 +1,45 @@
1
+ import { h } from 'vue'
2
+ import { ChevronDown, ChevronUp, Code } from '@vicons/ionicons5'
3
+
4
+ interface OrderEnumItem {
5
+ title: string
6
+ value: boolean | null
7
+ Icon: any
8
+ fn: (listQuery: any, key?: string) => void
9
+ }
10
+
11
+ interface OrderEnum {
12
+ ascend: OrderEnumItem
13
+ descend: OrderEnumItem
14
+ false: OrderEnumItem
15
+ }
16
+
17
+ export const orderEnum: OrderEnum = {
18
+ ascend: {
19
+ title: '升序',
20
+ value: true,
21
+ Icon: h(ChevronUp),
22
+ fn: (listQuery: any, key: string) => {
23
+ listQuery.desc = true
24
+ listQuery.sortFieldName = key
25
+ },
26
+ },
27
+ descend: {
28
+ title: '降序',
29
+ value: false,
30
+ Icon: h(ChevronDown),
31
+ fn: (listQuery: any) => {
32
+ listQuery.sortFieldName = ''
33
+ listQuery.desc = true
34
+ },
35
+ },
36
+ false: {
37
+ title: '默认',
38
+ value: null,
39
+ Icon: h(Code, { style: 'transform:rotateZ(90deg)' }),
40
+ fn: (listQuery: any) => {
41
+ listQuery.desc = false
42
+ listQuery.sortFieldName = ''
43
+ },
44
+ },
45
+ }
@@ -1,47 +1,29 @@
1
- <script setup>
1
+ <script setup lang="ts">
2
2
  import { NForm } from 'naive-ui'
3
- import { ref, unref } from 'vue'
3
+ import { ref, unref, computed } from 'vue'
4
+ import type { DataFormProps, DataFormExpose } from '../../types/components'
4
5
 
5
- import Options from '../options/Options.jsx'
6
- import {initRules} from '../dialog/utils/dialog.js'
7
- import { toArray } from 'core'
8
- const props = defineProps({
9
- isNo: {
10
- type: Boolean,
11
- default: () => true
12
- },
13
- read: {
14
- type: Boolean,
15
- default: () => false
16
- },
17
- labelField: {
18
- type: String,
19
- default: () => 'label'
20
- },
21
- contentStyle: {
22
- type: Object,
23
- default: () => ({})
24
- },
25
- options: {
26
- type: Array,
27
- default: () => []
28
- },
29
- rules: {
30
- type: Object,
31
- default: () => ({})
32
- },
33
- formProps: {
34
- type: Object,
35
- default: () => ({})
36
- },
37
- formItemProps: {
38
- type: Object,
39
- default: () => ({})
40
- },
41
- dialog: {
42
- type: Boolean,
43
- default: () => false
44
- }
6
+ import Options from '../options/Options'
7
+ import { initRules } from '../dialog/utils/dialog'
8
+ import { toArray } from '../utils/array'
9
+ import { registerDirectives } from '../directives/auto-register'
10
+ import { getCurrentInstance } from 'vue'
11
+
12
+ // 自动注册指令
13
+ const instance = getCurrentInstance()
14
+ if (instance?.appContext?.app) {
15
+ registerDirectives(instance.appContext.app)
16
+ }
17
+ const props = withDefaults(defineProps<DataFormProps>(), {
18
+ isNo: true,
19
+ read: false,
20
+ labelField: 'label',
21
+ contentStyle: () => ({}),
22
+ options: () => [],
23
+ rules: () => ({}),
24
+ formProps: () => ({}),
25
+ formItemProps: () => ({}),
26
+ dialog: false,
45
27
  })
46
28
  const _options = computed(() => props.options)
47
29
  // ====== 复制 initRules 逻辑 ======
@@ -68,27 +50,27 @@ const autoRules = computed(() => {
68
50
  })
69
51
  console.log(autoRules.value);
70
52
 
71
- defineExpose({
53
+ defineExpose<DataFormExpose>({
72
54
  formRef,
73
55
  getRule: () => autoRules.value,
74
- valid: (keyCode = []) =>{
75
- console.log('?? valid',keyCode);
76
- return new Promise((resolve, reject) => {
56
+ valid: (keyCode: string[] = []) => {
57
+ console.log('?? valid', keyCode)
58
+ return new Promise<void>((resolve, reject) => {
77
59
  const arrCode = toArray(keyCode)
78
- formRef.value?.validate((v) => {
60
+ formRef.value?.validate((v: any) => {
79
61
  if (v) return reject(v)
80
62
  resolve()
81
- },(v)=> arrCode.length ? arrCode.includes(v?.key) : true)
63
+ }, (v: any) => arrCode.length ? arrCode.includes(v?.key) : true)
82
64
  })
83
65
  },
84
- confirm: (fn) =>
85
- new Promise((resolve, reject) => {
86
- formRef.value?.validate((v) => {
66
+ confirm: (fn?: (model: any) => void) =>
67
+ new Promise<any>((resolve, reject) => {
68
+ formRef.value?.validate((v: any) => {
87
69
  if (v) return reject(v)
88
70
  fn && fn(unref(_model))
89
71
  resolve(unref(_model))
90
72
  })
91
- })
73
+ }),
92
74
  })
93
75
  </script>
94
76