index.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <!--
  2. * @Description: 表单渲染器,根据json生成表单
  3. -->
  4. <template>
  5. <div class="v-form-container">
  6. <Form class="v-form-model" ref="eFormModel" :model="formModel" v-bind="formModelProps">
  7. <Row>
  8. <FormRender
  9. v-for="(schema, index) of noHiddenList"
  10. :key="index"
  11. :schema="schema"
  12. :formConfig="formConfig"
  13. :formData="formModelNew"
  14. @change="handleChange"
  15. :setFormModel="setFormModel"
  16. @submit="handleSubmit"
  17. @reset="resetFields"
  18. >
  19. <template v-if="schema && schema.componentProps" #[`schema.componentProps!.slotName`]>
  20. <slot
  21. :name="schema.componentProps!.slotName"
  22. v-bind="{ formModel: formModel, field: schema.field, schema }"
  23. ></slot>
  24. </template>
  25. </FormRender>
  26. </Row>
  27. </Form>
  28. </div>
  29. </template>
  30. <script lang="ts">
  31. import { computed, defineComponent, PropType, provide, ref, unref } from 'vue';
  32. import FormRender from './components/FormRender.vue';
  33. import { IFormConfig, AForm } from '../../typings/v-form-component';
  34. import { Form, Row, Col } from 'ant-design-vue';
  35. import { useFormInstanceMethods } from '../../hooks/useFormInstanceMethods';
  36. import { IProps, IVFormMethods, useVFormMethods } from '../../hooks/useVFormMethods';
  37. import { useVModel } from '@vueuse/core';
  38. import { omit } from 'lodash-es';
  39. export default defineComponent({
  40. name: 'VFormCreate',
  41. components: {
  42. FormRender,
  43. Form,
  44. Row,
  45. },
  46. props: {
  47. fApi: {
  48. type: Object,
  49. },
  50. formModel: {
  51. type: Object,
  52. default: () => ({}),
  53. },
  54. formConfig: {
  55. type: Object as PropType<IFormConfig>,
  56. required: true,
  57. },
  58. },
  59. emits: ['submit', 'change', 'update:fApi', 'update:formModel'],
  60. setup(props, context) {
  61. const wrapperComp = props.formConfig.layout == 'vertical' ? Col : Row;
  62. const { emit } = context;
  63. const eFormModel = ref<AForm | null>(null);
  64. const formModelNew = computed({
  65. get: () => props.formModel,
  66. set: (value) => emit('update:formModel', value),
  67. });
  68. const noHiddenList = computed(() => {
  69. return (
  70. props.formConfig.schemas &&
  71. props.formConfig.schemas.filter((item) => item.hidden !== true)
  72. );
  73. });
  74. const fApi = useVModel(props, 'fApi', emit);
  75. const { submit, validate, clearValidate, resetFields, validateField } =
  76. useFormInstanceMethods<['submit', 'change', 'update:fApi', 'update:formModel']>(
  77. props,
  78. formModelNew,
  79. context,
  80. eFormModel,
  81. );
  82. const { linkOn, ...methods } = useVFormMethods<
  83. ['submit', 'change', 'update:fApi', 'update:formModel']
  84. >(
  85. { formConfig: props.formConfig, formData: props.formModel } as unknown as IProps,
  86. context,
  87. eFormModel,
  88. {
  89. submit,
  90. validate,
  91. validateField,
  92. resetFields,
  93. clearValidate,
  94. },
  95. );
  96. fApi.value = methods;
  97. const handleChange = (_event) => {
  98. const { schema, value } = _event;
  99. const { field } = unref(schema);
  100. linkOn[field!]?.forEach((formItem) => {
  101. formItem.update?.(value, formItem, fApi.value as IVFormMethods);
  102. });
  103. };
  104. /**
  105. * 获取表单属性
  106. */
  107. const formModelProps = computed(
  108. () => omit(props.formConfig, ['disabled', 'labelWidth', 'schemas']) as Recordable,
  109. );
  110. const handleSubmit = () => {
  111. submit();
  112. };
  113. provide('formModel', formModelNew);
  114. const setFormModel = (key, value) => {
  115. formModelNew.value[key] = value;
  116. };
  117. provide<(key: String, value: any) => void>('setFormModelMethod', setFormModel);
  118. // 把祖先组件的方法项注入到子组件中,子组件可通过inject获取
  119. return {
  120. eFormModel,
  121. submit,
  122. validate,
  123. validateField,
  124. resetFields,
  125. clearValidate,
  126. handleChange,
  127. formModelProps,
  128. handleSubmit,
  129. setFormModel,
  130. formModelNew,
  131. wrapperComp,
  132. noHiddenList,
  133. };
  134. },
  135. });
  136. </script>
  137. <style lang="less" scoped>
  138. .v-form-model {
  139. overflow: hidden;
  140. }
  141. </style>