| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- <template>
- <!--
- Form 智能表单组件
-
- 功能:
- 1. 封装所有校验逻辑
- 2. 自动provide校验函数给子组件
- 3. 支持v-model双向绑定
- 4. 极简使用方式
-
- 使用方式:
- <Form :rules="fieldConfigs" v-model="formData">
- <up-table>
- <up-tr>
- <up-th>事由</up-th>
- <ValidatedTd field="reason">
- <up-input placeholder="请输入事由" />
- </ValidatedTd>
- </up-tr>
- </up-table>
- </Form>
- -->
- <view class="smart-form">
- <!-- 直接渲染子内容,不使用插槽参数 -->
- <slot></slot>
- </view>
- </template>
- <script setup>
- import { computed, provide, watch } from 'vue'
- import { useFormValidation } from '@/composables/useFormValidation'
- const props = defineProps({
- // 表单数据 - 支持v-model
- modelValue: {
- type: Object,
- default: () => ({})
- },
- // 校验规则配置
- rules: {
- type: Object,
- default: () => ({})
- }
- })
- const emit = defineEmits(['update:modelValue'])
- // 直接使用外部传入的formData,避免双向绑定的复杂性
- const formData = computed({
- get: () => props.modelValue,
- set: (value) => emit('update:modelValue', value)
- })
- // 表单校验
- const { validateField, validateForm, errors, clearErrors, getFieldConfig, setFieldConfigs } = useFormValidation(props.rules)
- // 监听 props.rules 的变化,同步更新内部配置
- watch(() => props.rules, (newRules) => {
- console.log('Form组件检测到rules变化:', newRules)
- setFieldConfigs(newRules)
- }, { deep: true, immediate: true })
- // Form组件初始化完成
- // 计算是否有错误
- const hasErrors = computed(() => {
- return Object.keys(errors.value).some(key =>
- errors.value[key] && errors.value[key].length > 0
- )
- })
- // 向子组件提供校验函数和数据
- provide('validateField', validateField)
- provide('errors', errors)
- provide('clearErrors', clearErrors)
- provide('formData', formData)
- provide('getFieldConfig', getFieldConfig)
- provide('validateForm', validateForm) // 添加这个,供外部使用
- // 移除初始化校验,让Td组件自己处理
- // Form组件provide完成
- // 暴露方法给父组件
- defineExpose({
- validateForm,
- validateField,
- errors,
- clearErrors
- })
- </script>
- <style lang="scss" scoped>
- .smart-form {
- width: 100%;
- }
- </style>
|