useFormValidation.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import { ref, provide } from 'vue'
  2. export function useFormValidation(fieldConfigs = {}) {
  3. const errors = ref({})
  4. // 字段配置管理
  5. const configs = ref(fieldConfigs)
  6. // 获取字段配置
  7. const getFieldConfig = (fieldName) => {
  8. return configs.value[fieldName] || {}
  9. }
  10. // 设置字段配置
  11. const setFieldConfig = (fieldName, config) => {
  12. configs.value[fieldName] = config
  13. }
  14. // 批量设置字段配置
  15. const setFieldConfigs = (newConfigs) => {
  16. configs.value = { ...configs.value, ...newConfigs }
  17. }
  18. // 提供给子组件使用
  19. provide('errors', errors)
  20. provide('getFieldConfig', getFieldConfig)
  21. // 校验单个字段
  22. const validateField = (fieldName, value, rules) => {
  23. if (!rules || !Array.isArray(rules)) {
  24. return true
  25. }
  26. const fieldErrors = []
  27. for (const rule of rules) {
  28. // 必填校验
  29. if (rule.required && (!value || value === '')) {
  30. fieldErrors.push(rule.message || '此字段为必填项')
  31. break
  32. }
  33. // 如果值为空且不是必填,跳过其他校验
  34. if (!value || value === '') {
  35. continue
  36. }
  37. // 最小长度校验
  38. if (rule.min && value.length < rule.min) {
  39. fieldErrors.push(rule.message || `最少输入${rule.min}个字符`)
  40. break
  41. }
  42. // 最大长度校验
  43. if (rule.max && value.length > rule.max) {
  44. fieldErrors.push(rule.message || `最多输入${rule.max}个字符`)
  45. break
  46. }
  47. // 正则校验
  48. if (rule.pattern && !rule.pattern.test(value)) {
  49. fieldErrors.push(rule.message || '格式不正确')
  50. break
  51. }
  52. // 自定义校验函数
  53. if (rule.validator && typeof rule.validator === 'function') {
  54. const result = rule.validator(value)
  55. if (result !== true) {
  56. fieldErrors.push(result || rule.message || '校验失败')
  57. break
  58. }
  59. }
  60. }
  61. // 更新错误信息
  62. if (fieldErrors.length > 0) {
  63. errors.value[fieldName] = fieldErrors
  64. return false
  65. } else {
  66. delete errors.value[fieldName]
  67. return true
  68. }
  69. }
  70. // 提供给子组件使用
  71. provide('validateField', validateField)
  72. // 获取嵌套字段值的辅助函数
  73. const getNestedFieldValue = (formData, fieldPath) => {
  74. const pathArray = fieldPath.split('.')
  75. let value = formData
  76. for (const key of pathArray) {
  77. value = value?.[key]
  78. }
  79. return value
  80. }
  81. // 校验整个表单
  82. const validateForm = (formData, formRules) => {
  83. console.log('validateForm开始:', { formData, formRules })
  84. let isValid = true
  85. for (const fieldName in formRules) {
  86. // 支持嵌套字段路径(如 "xcd_0.qkms")
  87. const fieldValue = getNestedFieldValue(formData, fieldName)
  88. const fieldRules = formRules[fieldName].rules || formRules[fieldName]
  89. console.log(`校验字段 ${fieldName}:`, { fieldValue, fieldRules })
  90. const fieldValid = validateField(fieldName, fieldValue, fieldRules)
  91. console.log(`字段 ${fieldName} 校验结果:`, fieldValid)
  92. if (!fieldValid) {
  93. isValid = false
  94. }
  95. }
  96. console.log('validateForm结束:', isValid)
  97. return isValid
  98. }
  99. // 清除所有错误
  100. const clearErrors = () => {
  101. errors.value = {}
  102. }
  103. // 清除指定字段错误
  104. const clearFieldError = (fieldName) => {
  105. delete errors.value[fieldName]
  106. }
  107. return {
  108. errors,
  109. validateField,
  110. validateForm,
  111. clearErrors,
  112. clearFieldError,
  113. getFieldConfig,
  114. setFieldConfig,
  115. setFieldConfigs,
  116. configs
  117. }
  118. }