Skip to content

Commit

Permalink
feat: add FormSchema component and related files
Browse files Browse the repository at this point in the history
  • Loading branch information
cc-hearts committed Jan 14, 2024
1 parent f8e5d6f commit f2e63c9
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/ant-design-vue/.vitepress/theme/override-ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@
.vp-doc .ant-pagination li + li {
margin-top: 0;
}

p {
margin: 0;
}
104 changes: 104 additions & 0 deletions packages/ant-design-vue/src/components/form-schema/form-schema.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<script setup lang="ts">
import { computed, ref, unref } from 'vue'
import { FormProps } from './helper'
const props = withDefaults(defineProps<FormProps>(), {
name: 'basic',
labelCol: () => ({ span: 4 }),
schema: () => [],
defaultValue: () => ({}),
span: 3,
gutter: 12,
})
const formRef = ref()
const formState = ref<Record<PropertyKey, any>>({ ...props.defaultValue })
const getFieldsValue = () => {
return formState.value
}
const setFieldValue = (key: PropertyKey, val: any) => {
Reflect.set(formState.value, key, val)
}
const setFieldsValue = (target: Record<PropertyKey, any>) => {
Object.assign(formState.value, target)
}
const validate = async () => {
try {
await formRef.value.validate()
} catch (e) {
return [false, null]
}
return [true, formState.value]
}
const resetFields = () => {
formRef.value.resetFields()
}
const defaultSpan = computed(() => Math.floor(24 / props.span))
defineExpose({
validate,
resetFields,
setFieldValue,
getFieldsValue,
setFieldsValue,
})
</script>
<template>
<a-form
ref="formRef"
:label-col="props.labelCol"
:model="formState"
:name="props.name"
>
<a-row :gutter="props.gutter">
<template v-for="item in props.schema">
<a-col :span="item.span || defaultSpan">
<a-form-item :label="item.label" :name="item.name">
<template v-if="item.slot">
<slot :name="item.slot.name" :formState="formState" />
</template>
<template v-else-if="item.type === 'input'">
<a-input
v-model:value="formState[item.name]"
:placeholder="'请输入' + item.label"
v-bind="item.extra"
/>
</template>
<template v-else-if="item.type === 'input-number'">
<a-input-number
class="w-full"
v-model:value="formState[item.name]"
:placeholder="'请输入' + item.label"
v-bind="item.extra"
/>
</template>
<template v-else-if="item.type === 'select'">
<a-select
v-model:value="formState[item.name]"
:placeholder="'请选择' + item.label"
v-bind="item.extra"
:options="unref(item.extra?.options || [])"
>
</a-select>
</template>
<template v-else-if="item.type === 'radio'">
<a-radio-group
v-model:value="formState[item.name]"
v-bind="item.extra"
>
<template v-for="l in item.options" :key="l.value">
<a-radio :value="l.value">{{ l.label }}</a-radio>
</template>
</a-radio-group>
</template>
</a-form-item>
</a-col>
</template>
</a-row>
</a-form>
</template>
35 changes: 35 additions & 0 deletions packages/ant-design-vue/src/components/form-schema/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
interface Options {
label: string
value: any
}

export interface FormSchema {
label: string
type: string
name: string
width?: number
fixed?: 'left' | 'right'
slot?: { name: string; [props: string]: any }
extra?: { [props: string]: any }
options?: Options[]
span?: number
}

export interface FormProps {
name?: string
labelCol?: { span: number }
schema?: FormSchema[]
defaultValue?: Record<string, any>
span?: number
gutter?: number
}

export interface FormExpose {
validate: () => Promise<[boolean, Record<string, unknown>]>
getFieldsValue: <T extends Record<PropertyKey, any>>() => T
setFieldValue: (key: PropertyKey, value: any) => void
setFieldsValue: (target: Record<PropertyKey, any>) => void
resetFields: () => void
}

export const VERSION = '0.0.1'
7 changes: 7 additions & 0 deletions packages/ant-design-vue/src/components/form-schema/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import FormSchema from './form-schema.vue'
import { withInstall } from '@packages/vue-utils'
import { VERSION } from './helper.js'

withInstall(FormSchema, VERSION)

export { FormSchema }
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Ref, watch } from 'vue'
import { FormExpose } from '../helper'
import { fn } from '@cc-heart/utils/helper'

export function createSetFieldsFactory(ins: Ref<FormExpose | undefined>) {
const taskList: Array<fn> = []
let isIns = false
const flush = () => {
const task = taskList.slice()
task.forEach((fn) => {
fn instanceof Function && fn()
})
}
return async function (target: Record<string, any>) {
watch(
() => ins.value,
(val) => {
if (val && !isIns) {
isIns = true
flush()
}
},
{ immediate: true }
)

if (!ins.value) {
taskList.push(() => ins.value?.setFieldsValue(target))
} else {
ins.value.setFieldsValue(target)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { FormProps } from '../helper'

export function defineFormSchemaProps(formProps: Partial<FormProps>) {
return formProps
}
1 change: 1 addition & 0 deletions packages/ant-design-vue/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './table-pro'
export * from './form-schema'
35 changes: 35 additions & 0 deletions packages/ant-design-vue/src/docs/form-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# FormSchema

`FormSchema` 组件基于 `Form` 组件进行封装,使用 JSON Schema 描述表单的结构和验证规则,然后生成对应的表单。

## 基本使用

:::demo

```vue
<template>
<FormSchema ref="formSchemaIns" :schema="schema" />
<a-button @click="submit">提交</a-button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const formSchemaIns = ref()
const schema = [
{ label: '姓名', type: 'input', name: 'name' },
{ label: '邮箱', type: 'input', name: 'email' },
]
const submit = async () => {
const [bool, fields] = await formSchemaIns.value?.validate()
if (!bool) {
return
}
console.log(fields)
}
</script>
```

:::
1 change: 0 additions & 1 deletion scripts/cli/bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46177,7 +46177,6 @@ models.forEach(function (fromModel) {
var colorConvert = convert

ansiStyles.exports

;(function (module) {
const colorConvert$1 = colorConvert

Expand Down

0 comments on commit f2e63c9

Please sign in to comment.