{"version":3,"file":"form.vue.mjs","sources":["../../../../../../packages/components/form/src/form.vue"],"sourcesContent":["<script lang=\"ts\">\n  import { computed, defineComponent, provide, reactive, toRefs, watch } from 'vue'\n  import { getComponentNamespace, getNamespace } from '../../../utils/global-config'\n  import type { Arrayable } from '../../../utils/types'\n  import { formContextKey } from './constants'\n\n  import { formProps } from './form'\n  import { filterFields } from './utils'\n\n  import type { FormItemProp } from './form-item'\n  import type {\n    FormContext,\n    FormItemContext,\n    FormValidateCallback,\n    FormValidateFailure,\n    FormValidationResult\n  } from './types'\n\n  export default defineComponent({\n    name: getComponentNamespace('Form'),\n    props: formProps,\n    emits: ['validate', 'submit'],\n    setup(props, { emit }) {\n      const ns = getNamespace('form')\n      const cls = computed(() => [\n        ns,\n        `${ns}--${props.labelPosition}`,\n        props.inline && `${ns}--inline`\n      ])\n\n      const fields: FormItemContext[] = []\n\n      // 将form-item组件挂载的验证对象保存到form中，方便通过ref直接调用验证器\n      const addField: FormContext['addField'] = (field) => {\n        fields.push(field)\n      }\n\n      // 移除校验对象 在form-item组件销毁时调用\n      const removeField: FormContext['removeField'] = (field) => {\n        if (field.prop) {\n          fields.splice(fields.indexOf(field), 1)\n        }\n      }\n\n      // 重制表单验证对象\n      const resetFields: FormContext['resetFields'] = (properties = []) => {\n        if (!props.model) {\n          console.error('请传入数据源，绑定到form上的model属性。')\n          return\n        }\n        filterFields(fields, properties).forEach((field) => field.resetField())\n      }\n\n      // 请空表单验证对象\n      const clearValidate: FormContext['clearValidate'] = (props = []) => {\n        filterFields(fields, props).forEach((field) => field.clearValidate())\n      }\n\n      const isValidatable = computed(() => {\n        const hasModel = !!props.model\n        if (!hasModel) {\n          console.log('请传入form上model数据')\n        }\n        return hasModel\n      })\n\n      // 通过props来筛选可以进行验证表单对象\n      const obtainValidateFields = (props: Arrayable<FormItemProp>) => {\n        if (fields.length === 0) return []\n        const filteredFields = filterFields(fields, props)\n        if (!filteredFields.length) {\n          console.error('请传入正确的校验属性，检查form上的rules对象和form-item上的prop属性')\n          return []\n        }\n        return filteredFields\n      }\n\n      const doValidateField = async (props: Arrayable<FormItemProp>): Promise<boolean> => {\n        if (!isValidatable.value) return false\n\n        const fields = obtainValidateFields(props)\n        // 没有验证规则 直接通过验证\n        if (fields.length === 0) return true\n\n        let validationErrors: any = {}\n        for (const field of fields) {\n          try {\n            // 全部都需要验证 不指定trigger类型\n            await field.validate('')\n          } catch (fields) {\n            // 合并所有的验证错误\n            validationErrors = {\n              ...validationErrors,\n              ...(fields as any)\n            }\n          }\n        }\n\n        if (Object.keys(validationErrors).length === 0) return true\n        return Promise.reject(validationErrors)\n      }\n\n      const validateField: FormContext['validateField'] = async (modelProps = [], callback) => {\n        try {\n          const result = await doValidateField(modelProps)\n          if (result === true) {\n            callback?.(result)\n          }\n          return result\n        } catch (e) {\n          // 验证失败\n          if (e instanceof Error) throw e\n          callback?.(false, e)\n          return false\n        }\n      }\n\n      // 验证器，可给外部提供这一方法，直接验证保存在fields中的验证对象\n      const validate = async (callback?: FormValidateCallback): FormValidationResult =>\n        validateField(undefined, callback)\n\n      watch(\n        () => props.rules,\n        () => {\n          if (props.validateOnRuleChange) {\n            validate().catch((error: FormValidateFailure) => {\n              console.log(error)\n            })\n          }\n        },\n        { deep: true }\n      )\n\n      const labelWidth = computed(() => {\n        const labelWidth = props.labelWidth\n        return labelWidth\n      })\n\n      // todo 待完善\n      const handleSubmit = (e: Event) => {\n        validate().then((res) => {\n          if (res) {\n            emit('submit', e)\n          }\n        })\n      }\n\n      provide(\n        formContextKey,\n        reactive({\n          ...toRefs(props),\n          emit,\n          resetFields,\n          clearValidate,\n          validateField,\n          addField,\n          removeField,\n\n          labelWidth\n        })\n      )\n\n      return {\n        cls,\n        validate,\n        resetFields,\n        validateField,\n        clearValidate,\n        handleSubmit\n      }\n    },\n    expose: ['validate', 'resetFields', 'validateField', 'clearValidate']\n  })\n</script>\n\n<template>\n  <form :class=\"cls\" @submit.prevent=\"handleSubmit\">\n    <slot></slot>\n  </form>\n</template>\n"],"names":["cls","_openBlock","_createElementBlock","_normalizeClass","_withModifiers"],"mappings":";;;;AAgLc,SAAA,YAAA,IAAEA,EAAAA,MAAAA,EAAG,MAAA,EAAA,MAAA,EAAA,OAAA,QAAA,EAAA;SAAGC,WAAM,EAAAC,kBAAA;AAAA,IAAA,MAAA;AAAA,IAAA;AAAA,MAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,GAAA,CAAA;AAAA,MACxB,UAAa,MAAA,CAAA,CAAA,MAAA,MAAA,CAAA,CAAA,IAAAC,aAAA,CAAA,CAAA,GAAA,SAAA,IAAA,CAAA,YAAA,IAAA,KAAA,YAAA,CAAA,GAAA,IAAA,CAAA,EAAA,CAAA,SAAA,CAAA,CAAA,CAAA;AAAA,KAAA;AAAA;;;;;;;;;;;"}