@vrojs/element-plus 0.0.1 → 0.0.2

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 (60) hide show
  1. package/package.json +3 -3
  2. package/src/index.ts +5 -0
  3. package/src/locale/lang/zh-cn.ts +24 -0
  4. package/src/style/deps.ts +5 -0
  5. package/src/style/index.scss +5 -0
  6. package/src/vro-el-config-provider/types.ts +1 -1
  7. package/src/vro-el-radio-group/README.md +83 -0
  8. package/src/vro-el-radio-group/index.ts +16 -0
  9. package/src/vro-el-radio-group/style/css.ts +2 -0
  10. package/src/vro-el-radio-group/style/deps.ts +2 -0
  11. package/src/vro-el-radio-group/style/index.scss +1 -0
  12. package/src/vro-el-radio-group/style/index.ts +2 -0
  13. package/src/vro-el-radio-group/types.ts +29 -0
  14. package/src/vro-el-radio-group/vro-el-radio-group.vue +34 -0
  15. package/src/vro-el-schema-filter/README.md +146 -0
  16. package/src/vro-el-schema-filter/index.ts +16 -0
  17. package/src/vro-el-schema-filter/style/css.ts +3 -0
  18. package/src/vro-el-schema-filter/style/deps.ts +4 -0
  19. package/src/vro-el-schema-filter/style/index.scss +20 -0
  20. package/src/vro-el-schema-filter/style/index.ts +2 -0
  21. package/src/vro-el-schema-filter/types.ts +31 -0
  22. package/src/vro-el-schema-filter/vro-el-schema-filter.vue +64 -0
  23. package/src/vro-el-schema-form/README.md +207 -0
  24. package/src/vro-el-schema-form/defineVroElSchemaFormCreateField.ts +12 -0
  25. package/src/vro-el-schema-form/defineVroElSchemaFormFieldTrigger.ts +9 -0
  26. package/src/vro-el-schema-form/index.ts +20 -0
  27. package/src/vro-el-schema-form/style/css.ts +9 -0
  28. package/src/vro-el-schema-form/style/deps.ts +20 -0
  29. package/src/vro-el-schema-form/style/index.scss +4 -0
  30. package/src/vro-el-schema-form/style/index.ts +2 -0
  31. package/src/vro-el-schema-form/types.ts +171 -0
  32. package/src/vro-el-schema-form/useVroElSchemaForm.ts +48 -0
  33. package/src/vro-el-schema-form/vro-el-schema-form.vue +177 -0
  34. package/src/vro-el-schema-form/vroElSchemaFormFieldManager.ts +59 -0
  35. package/src/vro-el-schema-form-dialog/README.md +114 -5
  36. package/src/vro-el-schema-form-dialog/function-call.ts +11 -3
  37. package/src/vro-el-schema-form-dialog/index.ts +6 -1
  38. package/src/vro-el-schema-form-dialog/injection.ts +10 -0
  39. package/src/vro-el-schema-form-dialog/style/css.ts +2 -0
  40. package/src/vro-el-schema-form-dialog/style/deps.ts +4 -0
  41. package/src/vro-el-schema-form-dialog/style/index.scss +4 -1
  42. package/src/vro-el-schema-form-dialog/types.ts +70 -2
  43. package/src/vro-el-schema-form-dialog/useVroElSchemaFormDialog.ts +52 -0
  44. package/src/vro-el-schema-form-dialog/vro-el-schema-form-dialog.vue +119 -9
  45. package/src/vro-el-tags/README.md +73 -0
  46. package/src/vro-el-tags/index.ts +16 -0
  47. package/src/vro-el-tags/style/css.ts +2 -0
  48. package/src/vro-el-tags/style/deps.ts +3 -0
  49. package/src/vro-el-tags/style/index.scss +1 -0
  50. package/src/vro-el-tags/style/index.ts +2 -0
  51. package/src/vro-el-tags/types.ts +21 -0
  52. package/src/vro-el-tags/vro-el-tags.vue +69 -0
  53. package/src/vro-el-tree/README.md +85 -0
  54. package/src/vro-el-tree/index.ts +16 -0
  55. package/src/vro-el-tree/style/css.ts +2 -0
  56. package/src/vro-el-tree/style/deps.ts +1 -0
  57. package/src/vro-el-tree/style/index.scss +3 -0
  58. package/src/vro-el-tree/style/index.ts +2 -0
  59. package/src/vro-el-tree/types.ts +38 -0
  60. package/src/vro-el-tree/vro-el-tree.vue +78 -0
@@ -0,0 +1,207 @@
1
+ # VroElSchemaForm
2
+
3
+ ### 介绍
4
+
5
+ 基于 `ElForm` 的 schema 表单封装。组件通过 `schema` 描述字段、布局、校验和事件,适合快速搭建中后台表单,同时保留 Element Plus Form、Row、Col、FormItem 的透传能力。
6
+
7
+ ## 代码演示
8
+
9
+ ### 基础用法
10
+
11
+ ```html
12
+ <template>
13
+ <vro-el-schema-form
14
+ ref="refVroElSchemaForm"
15
+ :schema="schema"
16
+ :form-props="{ labelWidth: '90px' }"
17
+ :col-props="{ span: 12 }"
18
+ />
19
+ <el-button type="primary" :loading="loading" @click="trigger">提交</el-button>
20
+ </template>
21
+
22
+ <script setup lang="ts">
23
+ import { ref } from 'vue'
24
+ import { useVroElSchemaForm, type VroElSchemaFormInstance } from '@vrojs/element-plus'
25
+
26
+ const refVroElSchemaForm = ref<VroElSchemaFormInstance>()
27
+ const { schema, loading, trigger } = useVroElSchemaForm(
28
+ {
29
+ username: {
30
+ label: '用户名',
31
+ value: '',
32
+ is: 'ElInput',
33
+ rules: [{ required: true, message: '请填写用户名', trigger: 'blur' }],
34
+ },
35
+ role: {
36
+ label: '角色',
37
+ value: '',
38
+ is: 'VroElSelect',
39
+ options: [
40
+ { label: '管理员', value: 'admin' },
41
+ { label: '运营', value: 'operator' },
42
+ ],
43
+ },
44
+ },
45
+ async (data) => {
46
+ console.log(data)
47
+ },
48
+ {
49
+ instanceRef: refVroElSchemaForm,
50
+ },
51
+ )
52
+ </script>
53
+ ```
54
+
55
+ ### 动态显示
56
+
57
+ ```ts
58
+ const schema = {
59
+ accountType: {
60
+ label: '账号类型',
61
+ value: 'personal',
62
+ is: 'VroElRadioGroup',
63
+ options: [
64
+ { label: '个人', value: 'personal' },
65
+ { label: '企业', value: 'company' },
66
+ ],
67
+ },
68
+ realName: {
69
+ label: '姓名',
70
+ value: '',
71
+ is: 'ElInput',
72
+ hidden: (_, __, metadata) => metadata.accountType.value !== 'personal',
73
+ },
74
+ companyName: {
75
+ label: '企业名称',
76
+ value: '',
77
+ is: 'ElInput',
78
+ hidden: (_, __, metadata) => metadata.accountType.value !== 'company',
79
+ },
80
+ }
81
+ ```
82
+
83
+ ### 字段插槽
84
+
85
+ 字段的 `slots` 配置用于把外部同名插槽转发给实际渲染组件。
86
+
87
+ ```html
88
+ <vro-el-schema-form :schema="schema">
89
+ <template #prepend>
90
+ <span>https://</span>
91
+ </template>
92
+ </vro-el-schema-form>
93
+ ```
94
+
95
+ ```ts
96
+ const schema = {
97
+ website: {
98
+ label: '网址',
99
+ value: '',
100
+ is: 'ElInput',
101
+ slots: {
102
+ prepend: 'prepend',
103
+ },
104
+ },
105
+ }
106
+ ```
107
+
108
+ ## API
109
+
110
+ ### 属性 Props
111
+
112
+ <table>
113
+ <tbody>
114
+ <tr>
115
+ <td>名称</td>
116
+ <td>类型</td>
117
+ <td>默认值</td>
118
+ </tr>
119
+ <tr v-for="(item, key) in vroElSchemaFormProps" :key="key">
120
+ <td>{{ key }}</td>
121
+ <td>{{ parseType(item.type || item) }}</td>
122
+ <td>{{ reserve(item.default, '-') }}</td>
123
+ </tr>
124
+ </tbody>
125
+ </table>
126
+
127
+ ### 插槽 Slots
128
+
129
+ <table>
130
+ <tbody>
131
+ <tr>
132
+ <td>名称</td>
133
+ <td>说明</td>
134
+ </tr>
135
+ <tr>
136
+ <td>default</td>
137
+ <td>表单尾部内容,会渲染在 ElRow 内部</td>
138
+ </tr>
139
+ <tr>
140
+ <td>schema 字段 slots 配置中的 key</td>
141
+ <td>转发给字段组件的插槽,插槽参数为 { item }</td>
142
+ </tr>
143
+ </tbody>
144
+ </table>
145
+
146
+ ### 实例方法
147
+
148
+ <table>
149
+ <tbody>
150
+ <tr>
151
+ <td>名称</td>
152
+ <td>说明</td>
153
+ </tr>
154
+ <tr>
155
+ <td>form</td>
156
+ <td>ElForm 实例</td>
157
+ </tr>
158
+ <tr>
159
+ <td>validate</td>
160
+ <td>校验表单和支持 validate 的字段组件</td>
161
+ </tr>
162
+ <tr>
163
+ <td>validateField</td>
164
+ <td>校验指定字段</td>
165
+ </tr>
166
+ <tr>
167
+ <td>resetFields</td>
168
+ <td>重置表单字段</td>
169
+ </tr>
170
+ <tr>
171
+ <td>extractValues</td>
172
+ <td>提取 schema 字段值和支持 extractValues 的字段组件值</td>
173
+ </tr>
174
+ <tr>
175
+ <td>trigger</td>
176
+ <td>触发支持 trigger 的字段组件</td>
177
+ </tr>
178
+ </tbody>
179
+ </table>
180
+
181
+ ### 事件 Events
182
+
183
+ <table>
184
+ <tbody>
185
+ <tr>
186
+ <td>名称</td>
187
+ <td>参数</td>
188
+ <td>说明</td>
189
+ </tr>
190
+ <tr>
191
+ <td>change-field</td>
192
+ <td>{ key, value }</td>
193
+ <td>字段 change 时触发</td>
194
+ </tr>
195
+ <tr>
196
+ <td>input-field</td>
197
+ <td>{ key, value }</td>
198
+ <td>字段 input 时触发</td>
199
+ </tr>
200
+ </tbody>
201
+ </table>
202
+
203
+ <script setup lang="ts">
204
+ import { reserve } from '@daysnap/utils'
205
+ import { VroElSchemaForm, vroElSchemaFormProps } from '.'
206
+ import { parseType } from '../utils'
207
+ </script>
@@ -0,0 +1,12 @@
1
+ import type { VroElSchemaFormSchemaField } from './types'
2
+
3
+ export function defineVroElSchemaFormCreateField<
4
+ T extends (...args: any[]) => VroElSchemaFormSchemaField,
5
+ >(generator: T) {
6
+ return (options: Partial<VroElSchemaFormSchemaField> = {}, ...args: Parameters<T>) => {
7
+ return {
8
+ ...generator(...args),
9
+ ...options,
10
+ } as VroElSchemaFormSchemaField
11
+ }
12
+ }
@@ -0,0 +1,9 @@
1
+ export function defineVroElSchemaFormFieldTrigger(
2
+ request: (ctx: {
3
+ confirm: (...args: any[]) => void
4
+ hide: (reason?: any) => void
5
+ block: () => void
6
+ }) => any,
7
+ ) {
8
+ return request
9
+ }
@@ -0,0 +1,20 @@
1
+ import { withInstall } from '@vrojs/base'
2
+
3
+ import Component from './vro-el-schema-form.vue'
4
+
5
+ export * from './defineVroElSchemaFormCreateField'
6
+ export * from './defineVroElSchemaFormFieldTrigger'
7
+ export * from './types'
8
+ export * from './useVroElSchemaForm'
9
+ export * from './vroElSchemaFormFieldManager'
10
+
11
+ export const VroElSchemaForm = withInstall<typeof Component>(Component)
12
+ export default VroElSchemaForm
13
+
14
+ export type VroElSchemaFormInstance = InstanceType<typeof VroElSchemaForm>
15
+
16
+ declare module 'vue' {
17
+ export interface GlobalComponents {
18
+ VroElSchemaForm: typeof VroElSchemaForm
19
+ }
20
+ }
@@ -0,0 +1,9 @@
1
+ import '../../style/base.scss'
2
+ import '../../vro-el-checkbox-group/style/css'
3
+ import '../../vro-el-file-upload/style/css'
4
+ import '../../vro-el-image-upload/style/css'
5
+ import '../../vro-el-radio-group/style/css'
6
+ import '../../vro-el-select/style/css'
7
+ import '../../vro-el-tags/style/css'
8
+ import '../../vro-el-tree/style/css'
9
+ import './index.scss'
@@ -0,0 +1,20 @@
1
+ import '../../vro-el-checkbox-group/style/deps'
2
+ import '../../vro-el-file-upload/style/deps'
3
+ import '../../vro-el-image-upload/style/deps'
4
+ import '../../vro-el-radio-group/style/deps'
5
+ import '../../vro-el-select/style/deps'
6
+ import '../../vro-el-tags/style/deps'
7
+ import '../../vro-el-tree/style/deps'
8
+ import 'element-plus/es/components/cascader/style/css'
9
+ import 'element-plus/es/components/checkbox-group/style/css'
10
+ import 'element-plus/es/components/col/style/css'
11
+ import 'element-plus/es/components/date-picker/style/css'
12
+ import 'element-plus/es/components/divider/style/css'
13
+ import 'element-plus/es/components/form-item/style/css'
14
+ import 'element-plus/es/components/form/style/css'
15
+ import 'element-plus/es/components/input-number/style/css'
16
+ import 'element-plus/es/components/input/style/css'
17
+ import 'element-plus/es/components/radio-group/style/css'
18
+ import 'element-plus/es/components/row/style/css'
19
+ import 'element-plus/es/components/select/style/css'
20
+ import 'element-plus/es/components/tree-select/style/css'
@@ -0,0 +1,4 @@
1
+ .vro-el-schema-form {
2
+ display: block;
3
+ width: 100%;
4
+ }
@@ -0,0 +1,2 @@
1
+ import './deps'
2
+ import './css'
@@ -0,0 +1,171 @@
1
+ import type { Arrayable } from '@vrojs/base'
2
+ import {
3
+ type ColProps,
4
+ type FormItemProps,
5
+ type FormItemRule,
6
+ type FormProps,
7
+ type RowProps,
8
+ } from 'element-plus'
9
+ import { type ExtractPropTypes, type PropType, type Raw } from 'vue'
10
+
11
+ export interface VroElSchemaFormSchemaField {
12
+ /**
13
+ * 字段渲染组件,支持内置注册名、外部注册名或组件对象。
14
+ */
15
+ is?:
16
+ | 'ElInput'
17
+ | 'ElSelect'
18
+ | 'ElRadioGroup'
19
+ | 'ElCheckboxGroup'
20
+ | 'ElDatePicker'
21
+ | 'ElInputNumber'
22
+ | 'ElTreeSelect'
23
+ | 'ElCascader'
24
+ | 'ElDivider'
25
+ | 'VroElSelect'
26
+ | 'VroElCheckboxGroup'
27
+ | 'VroElRadioGroup'
28
+ | 'VroElImageUpload'
29
+ | 'VroElFileUpload'
30
+ | 'VroElTags'
31
+ | 'VroElTree'
32
+ | Raw<object>
33
+ | (string & {})
34
+
35
+ /**
36
+ * 表单项标签文本。
37
+ */
38
+ label?: string
39
+
40
+ /**
41
+ * 字段当前值。
42
+ */
43
+ value?: any
44
+
45
+ /**
46
+ * 字段默认值,供外部工具生成初始值时使用。
47
+ */
48
+ defaultValue?: any
49
+
50
+ /**
51
+ * 字段重置值,重置的时候使用。
52
+ */
53
+ resetValue?: any
54
+
55
+ /**
56
+ * 透传给字段组件的属性。
57
+ */
58
+ props?: Record<string, any>
59
+
60
+ /**
61
+ * 字段选项列表,常用于选择器、单选、多选等组件。
62
+ */
63
+ options?: any
64
+
65
+ /**
66
+ * 选项展示文本字段名。
67
+ */
68
+ labelKey?: string
69
+
70
+ /**
71
+ * 选项绑定值字段名。
72
+ */
73
+ valueKey?: string
74
+
75
+ /**
76
+ * 当前字段栅格配置,会与组件级 colProps 合并。
77
+ */
78
+ colProps?: Partial<ColProps>
79
+
80
+ /**
81
+ * 当前字段表单项配置,会与组件级 formItemProps 合并。
82
+ */
83
+ formItemProps?: Partial<FormItemProps>
84
+
85
+ /**
86
+ * 从字段值转换提交值。
87
+ */
88
+ get?: (value: any, filed: VroElSchemaFormSchemaField, metadata: VroElSchemaFormSchema) => any
89
+
90
+ /**
91
+ * 将外部数据写入字段。
92
+ */
93
+ set?: (source: any, field: VroElSchemaFormSchemaField, metadata: VroElSchemaFormSchema) => void
94
+
95
+ /**
96
+ * 是否隐藏字段,支持根据当前字段和完整 schema 动态判断。
97
+ */
98
+ hidden?:
99
+ | boolean
100
+ | ((value: any, filed: VroElSchemaFormSchemaField, metadata: VroElSchemaFormSchema) => boolean)
101
+
102
+ /**
103
+ * 字段校验规则,透传给 ElForm rules。
104
+ */
105
+ rules?:
106
+ | Arrayable<FormItemRule>
107
+ | ((
108
+ value: any,
109
+ field: VroElSchemaFormSchemaField,
110
+ metadata: VroElSchemaFormSchema,
111
+ ) => Arrayable<FormItemRule>)
112
+
113
+ /**
114
+ * 字段 change 事件回调。
115
+ */
116
+ onChange?: (value: any, field: VroElSchemaFormSchemaField, metadata: VroElSchemaFormSchema) => any
117
+
118
+ /**
119
+ * 字段 input 事件回调。
120
+ */
121
+ onInput?: (value: any, field: VroElSchemaFormSchemaField, metadata: VroElSchemaFormSchema) => any
122
+
123
+ [key: string]: any
124
+ }
125
+
126
+ export type VroElSchemaFormSchema = Record<string, VroElSchemaFormSchemaField>
127
+ export type VroElSchemaFormFormProps = Partial<Omit<FormProps, 'model' | 'rules'>>
128
+
129
+ export const vroElSchemaFormProps = {
130
+ /**
131
+ * 透传给 ElForm 的属性,不包含 model 和 rules。
132
+ */
133
+ formProps: {
134
+ type: Object as PropType<VroElSchemaFormFormProps>,
135
+ default: () => ({}),
136
+ },
137
+
138
+ /**
139
+ * 透传给 ElRow 的属性。
140
+ */
141
+ rowProps: {
142
+ type: Object as PropType<Partial<RowProps>>,
143
+ default: () => ({}),
144
+ },
145
+
146
+ /**
147
+ * 透传给 ElCol 的默认属性,字段级 colProps 优先级更高。
148
+ */
149
+ colProps: {
150
+ type: Object as PropType<Partial<ColProps>>,
151
+ default: () => ({}),
152
+ },
153
+
154
+ /**
155
+ * 透传给 ElFormItem 的默认属性,字段级 formItemProps 优先级更高。
156
+ */
157
+ formItemProps: {
158
+ type: Object as PropType<Partial<FormItemProps>>,
159
+ default: () => ({}),
160
+ },
161
+
162
+ /**
163
+ * 表单字段 schema 配置。
164
+ */
165
+ schema: {
166
+ type: Object as PropType<VroElSchemaFormSchema>,
167
+ default: () => ({}),
168
+ },
169
+ }
170
+
171
+ export type VroElSchemaFormProps = ExtractPropTypes<typeof vroElSchemaFormProps>
@@ -0,0 +1,48 @@
1
+ import banana from '@daysnap/banana'
2
+ import { isFunction } from '@daysnap/utils'
3
+ import { useAsyncTask } from '@vrojs/use'
4
+ import { reactive, type Ref, ref } from 'vue'
5
+
6
+ import type { VroElSchemaFormInstance } from '.'
7
+ import type { VroElSchemaFormSchema } from './types'
8
+
9
+ export function useVroElSchemaForm<T extends (data: any) => Promise<any>>(
10
+ rawSchema: (() => VroElSchemaFormSchema) | VroElSchemaFormSchema,
11
+ task?: T,
12
+ options: {
13
+ initialValue?: Record<string, any>
14
+ instanceRef?: Ref<VroElSchemaFormInstance | undefined>
15
+ } = {},
16
+ ) {
17
+ const { instanceRef, initialValue } = options
18
+ const schema = reactive(isFunction(rawSchema) ? rawSchema() : rawSchema)
19
+
20
+ const refVroElSchemaForm = instanceRef ?? ref<VroElSchemaFormInstance>()
21
+
22
+ const { loading, trigger } = useAsyncTask(
23
+ async () => {
24
+ if (!refVroElSchemaForm.value) {
25
+ return
26
+ }
27
+ try {
28
+ await refVroElSchemaForm.value.validate()
29
+ } catch {
30
+ throw ''
31
+ }
32
+ const data = await refVroElSchemaForm.value.extractValues()
33
+ await task?.(data)
34
+ },
35
+ { throwError: true },
36
+ )
37
+
38
+ if (initialValue) {
39
+ banana.assignment(initialValue, schema as any)
40
+ }
41
+
42
+ return {
43
+ schema,
44
+ refVroElSchemaForm,
45
+ loading,
46
+ trigger,
47
+ }
48
+ }
@@ -0,0 +1,177 @@
1
+ <template>
2
+ <el-form
3
+ v-bind="elFormProps"
4
+ ref="refForm"
5
+ class="vro-el-schema-form"
6
+ :model="model"
7
+ :rules="rules"
8
+ >
9
+ <el-row :gutter="16" v-bind="rowProps">
10
+ <el-col v-for="(item, key) in metadata" :key="key" v-bind="{ ...colProps, ...item.colProps }">
11
+ <el-form-item
12
+ :label="item.label"
13
+ :prop="key"
14
+ v-bind="{ ...formItemProps, ...item.formItemProps }"
15
+ >
16
+ <component
17
+ v-model="item.value"
18
+ v-bind="mapping?.[key]?.props"
19
+ :is="mapping?.[key]?.is"
20
+ ref="refComponents"
21
+ @change="handleChange(key, $event)"
22
+ @input="handleInput(key, $event)"
23
+ >
24
+ <template v-for="(slot, key) in item.slots" #[slot] :key="slot">
25
+ <slot :name="key" :item="item" />
26
+ </template>
27
+ </component>
28
+ </el-form-item>
29
+ </el-col>
30
+ <slot></slot>
31
+ </el-row>
32
+ </el-form>
33
+ </template>
34
+
35
+ <script setup lang="ts">
36
+ import banana from '@daysnap/banana'
37
+ import { filterEmptyValue, isFunction, isString } from '@daysnap/utils'
38
+ import { ElCol, ElForm, ElFormItem, ElRow } from 'element-plus'
39
+ import { computed, ref, useTemplateRef, watchEffect } from 'vue'
40
+
41
+ import { useLocale } from '../locale'
42
+ import { datePickerValueFormat } from '../utils'
43
+ import { defineVroElSchemaFormFieldTrigger } from './defineVroElSchemaFormFieldTrigger'
44
+ import { vroElSchemaFormProps, type VroElSchemaFormSchema } from './types'
45
+ import { vroElSchemaFormFieldManager } from './vroElSchemaFormFieldManager'
46
+
47
+ defineOptions({ name: 'VroElSchemaForm' })
48
+
49
+ const emit = defineEmits(['change-field', 'input-field'])
50
+ const props = defineProps(vroElSchemaFormProps)
51
+
52
+ const elFormProps = computed(() => {
53
+ return {
54
+ validateOnRuleChange: false,
55
+ ...props.formProps,
56
+ }
57
+ })
58
+
59
+ const { locale } = useLocale()
60
+
61
+ // 规则
62
+ const rules = ref<Record<string, any>>({})
63
+ const model = ref<Record<string, any>>({})
64
+ const metadata = ref<VroElSchemaFormSchema>({})
65
+
66
+ watchEffect(() => {
67
+ const { schema } = props
68
+ metadata.value = {}
69
+ Object.entries(schema).forEach(([key, item]) => {
70
+ // eslint-disable-next-line prefer-const
71
+ let { hidden, value, rules: itemRules, is } = item
72
+
73
+ if (isFunction(hidden)) {
74
+ hidden = hidden(value, item, schema)
75
+ }
76
+ if (!is) {
77
+ hidden = true
78
+ }
79
+ if (!hidden) {
80
+ model.value[key] = value
81
+ metadata.value[key] = item
82
+ }
83
+
84
+ if (isFunction(rules)) {
85
+ rules.value = rules(value, item, schema)
86
+ }
87
+ rules.value[key] = itemRules
88
+ })
89
+ })
90
+
91
+ const mapping = computed(() => {
92
+ return Object.entries(metadata.value).reduce<Record<string, any>>((res, [key, item]) => {
93
+ // eslint-disable-next-line prefer-const
94
+ let { props = {}, is, options, labelKey, valueKey } = item
95
+ if (isString(is)) {
96
+ const data = vroElSchemaFormFieldManager.get(is)
97
+ if (data) {
98
+ let loc: Record<string, any> = {}
99
+ if (isString(is)) {
100
+ loc = (locale.value.el['schemaForm'] as any)[is]
101
+ }
102
+
103
+ if (is === 'ElDatePicker') {
104
+ props.valueFormat = datePickerValueFormat[props?.type ?? 'date']
105
+ }
106
+ is = data.is
107
+ props = Object.assign(
108
+ {},
109
+ data.props,
110
+ loc,
111
+ filterEmptyValue({ options, labelKey, valueKey }),
112
+ props,
113
+ )
114
+
115
+ if (props.disabled) {
116
+ props.placeholder = '-'
117
+ if (is === 'ElDatePicker') {
118
+ props.startPlaceholder = '-'
119
+ props.endPlaceholder = '-'
120
+ }
121
+ }
122
+ }
123
+ }
124
+ res[key] = { is, props }
125
+ return res
126
+ }, {})
127
+ })
128
+
129
+ // 事件
130
+ const handleChange = async (key: string, value: any) => {
131
+ emit('change-field', { key, value })
132
+ await props.schema[key]?.onChange?.(value, props.schema[key], props.schema)
133
+ }
134
+ const handleInput = async (key: string, value: any) => {
135
+ emit('input-field', { key, value })
136
+ await props.schema[key]?.onInput?.(value, props.schema[key], props.schema)
137
+ }
138
+
139
+ // 校验
140
+ const refComponents = useTemplateRef<any[]>('refComponents')
141
+ const refForm = useTemplateRef('refForm')
142
+ const validate = async () => {
143
+ const instances = refComponents.value?.filter((item) => isFunction(item.validate)) ?? []
144
+ await Promise.all([refForm.value, ...instances].map((item) => item?.validate()))
145
+ }
146
+
147
+ // 获取值 这里返回异步函数 为以后可能会做校验做准备
148
+ const extractValues = async () => {
149
+ const instances = refComponents.value?.filter((item) => isFunction(item.extractValues)) ?? []
150
+ const results = await Promise.all<Record<string, any>[]>(
151
+ instances.map((item) => item.extractValues()),
152
+ )
153
+ results.push(banana.extract(props.schema as any))
154
+ return results.filter(Boolean).reduce<Record<string, any>>((res, item) => {
155
+ return { ...res, ...item }
156
+ }, {})
157
+ }
158
+
159
+ // 触发执行子组件的 trigger 事件
160
+ const trigger = defineVroElSchemaFormFieldTrigger(async (ctx) => {
161
+ const instances = refComponents.value?.filter((item) => isFunction(item.trigger)) ?? []
162
+ await Promise.all(instances.map((item) => item.trigger(ctx)))
163
+ })
164
+
165
+ defineExpose({
166
+ get form() {
167
+ return refForm.value!
168
+ },
169
+ validate,
170
+ resetFields: () => refForm.value?.resetFields(),
171
+ trigger,
172
+ extractValues,
173
+ validateField: async (key: string) => {
174
+ return refForm.value?.validateField(key)
175
+ },
176
+ })
177
+ </script>