| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- <!--
- * @Description: 表单渲染器,根据json生成表单
- -->
- <template>
- <div class="v-form-container">
- <Form class="v-form-model" ref="eFormModel" :model="formModel" v-bind="formModelProps">
- <Row>
- <FormRender
- v-for="(schema, index) of noHiddenList"
- :key="index"
- :schema="schema"
- :formConfig="formConfig"
- :formData="formModelNew"
- @change="handleChange"
- :setFormModel="setFormModel"
- @submit="handleSubmit"
- @reset="resetFields"
- >
- <template v-if="schema && schema.componentProps" #[`schema.componentProps!.slotName`]>
- <slot
- :name="schema.componentProps!.slotName"
- v-bind="{ formModel: formModel, field: schema.field, schema }"
- ></slot>
- </template>
- </FormRender>
- </Row>
- </Form>
- </div>
- </template>
- <script lang="ts">
- import { computed, defineComponent, PropType, provide, ref, unref } from 'vue';
- import FormRender from './components/FormRender.vue';
- import { IFormConfig, AForm } from '../../typings/v-form-component';
- import { Form, Row, Col } from 'ant-design-vue';
- import { useFormInstanceMethods } from '../../hooks/useFormInstanceMethods';
- import { IProps, IVFormMethods, useVFormMethods } from '../../hooks/useVFormMethods';
- import { useVModel } from '@vueuse/core';
- import { omit } from 'lodash-es';
- export default defineComponent({
- name: 'VFormCreate',
- components: {
- FormRender,
- Form,
- Row,
- },
- props: {
- fApi: {
- type: Object,
- },
- formModel: {
- type: Object,
- default: () => ({}),
- },
- formConfig: {
- type: Object as PropType<IFormConfig>,
- required: true,
- },
- },
- emits: ['submit', 'change', 'update:fApi', 'update:formModel'],
- setup(props, context) {
- const wrapperComp = props.formConfig.layout == 'vertical' ? Col : Row;
- const { emit } = context;
- const eFormModel = ref<AForm | null>(null);
- const formModelNew = computed({
- get: () => props.formModel,
- set: (value) => emit('update:formModel', value),
- });
- const noHiddenList = computed(() => {
- return (
- props.formConfig.schemas &&
- props.formConfig.schemas.filter((item) => item.hidden !== true)
- );
- });
- const fApi = useVModel(props, 'fApi', emit);
- const { submit, validate, clearValidate, resetFields, validateField } =
- useFormInstanceMethods<['submit', 'change', 'update:fApi', 'update:formModel']>(
- props,
- formModelNew,
- context,
- eFormModel,
- );
- const { linkOn, ...methods } = useVFormMethods<
- ['submit', 'change', 'update:fApi', 'update:formModel']
- >(
- { formConfig: props.formConfig, formData: props.formModel } as unknown as IProps,
- context,
- eFormModel,
- {
- submit,
- validate,
- validateField,
- resetFields,
- clearValidate,
- },
- );
- fApi.value = methods;
- const handleChange = (_event) => {
- const { schema, value } = _event;
- const { field } = unref(schema);
- linkOn[field!]?.forEach((formItem) => {
- formItem.update?.(value, formItem, fApi.value as IVFormMethods);
- });
- };
- /**
- * 获取表单属性
- */
- const formModelProps = computed(
- () => omit(props.formConfig, ['disabled', 'labelWidth', 'schemas']) as Recordable,
- );
- const handleSubmit = () => {
- submit();
- };
- provide('formModel', formModelNew);
- const setFormModel = (key, value) => {
- formModelNew.value[key] = value;
- };
- provide<(key: String, value: any) => void>('setFormModelMethod', setFormModel);
- // 把祖先组件的方法项注入到子组件中,子组件可通过inject获取
- return {
- eFormModel,
- submit,
- validate,
- validateField,
- resetFields,
- clearValidate,
- handleChange,
- formModelProps,
- handleSubmit,
- setFormModel,
- formModelNew,
- wrapperComp,
- noHiddenList,
- };
- },
- });
- </script>
- <style lang="less" scoped>
- .v-form-model {
- overflow: hidden;
- }
- </style>
|