You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3组合式API下vee-validate编写精简表单校验代码的最佳实践

解决方案

你可以直接通过监听useForm返回的响应式values对象触发校验,不需要额外编写任何useField相关代码,实现步骤如下:

最简实现

  1. 先从useForm返回值中解构出validate全表单校验方法
  2. 深度监听values变化,搭配防抖避免输入过程频繁触发校验
import { watch, onUnmounted } from 'vue'
import { debounce } from 'lodash-es'

setup() {
    let { handleSubmit, errors, values, validate } = useForm({
      validationSchema: Invoice.validationSchema,
      initialValues: Invoice.validationSchema.getDefault(),
      validateOnMount: false,
    });

    // 300ms防抖,可根据业务需求调整时长
    const debouncedValidate = debounce(validate, 300)
    // 深度监听values所有属性变化
    watch(values, () => debouncedValidate(), { deep: true })
    // 组件卸载时取消未执行的防抖校验,避免内存泄漏
    onUnmounted(() => debouncedValidate.cancel())

    let addLine = () => {
      values.elements.push(InvoiceElement.validationSchema.getDefault());
    };

    let submitForm = handleSubmit((values) => {
      alert("form was valid and we submit data here");
    });

    return {
      values,
      errors,
      addLine,
      submitForm,
    };
  }

更高复用性的封装

可以把这套逻辑抽成通用的组合式函数,后续所有表单都不需要重复写校验相关逻辑:

// 全局通用组合式函数 composables/useModelForm.js
import { useForm } from 'vee-validate'
import { watch, onUnmounted } from 'vue'
import { debounce } from 'lodash-es'

export default function useModelForm(ModelClass, formOptions = {}) {
  const { debounceTime = 300, ...useFormOptions } = formOptions
  const formContext = useForm({
    validationSchema: ModelClass.validationSchema,
    initialValues: ModelClass.validationSchema.getDefault(),
    validateOnMount: false,
    ...useFormOptions
  })

  const { validate, values } = formContext
  const debouncedValidate = debounce(validate, debounceTime)

  watch(values, () => debouncedValidate(), { deep: true, immediate: useFormOptions.validateOnMount })
  onUnmounted(() => debouncedValidate.cancel())

  return formContext
}

之后业务表单的代码可以精简到以下程度:

setup() {
    // 只需要传入对应模型类,所有表单基础逻辑自动完成
    const { handleSubmit, errors, values } = useModelForm(Invoice)

    const addLine = () => {
      values.elements.push(InvoiceElement.validationSchema.getDefault());
    };
    const submitForm = handleSubmit((values) => {
      alert("form was valid and we submit data here");
    });

    return { values, errors, addLine, submitForm };
}

性能优化建议

如果表单字段很多,不需要每次都全表单校验,可以在watch回调中对比新旧值的变化路径,调用validate(变化字段路径)只校验修改的字段,进一步降低性能消耗。


内容的提问来源于stack exchange,提问作者David Heremans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:42:01