Vue3+Quasar分步表单验证:单/多q-form选型咨询
Vue 3 + Quasar 分步表单验证:单/多q-form方案都可行
两种方案都能实现分步验证,具体选哪种看你的代码结构和需求:
一、单个q-form实现分步验证
把所有步骤的表单控件都放在同一个q-form下,通过验证当前步骤的字段集合来实现分步校验。这种方式适合字段之间有联动、需要统一提交的场景。
实现思路
- 给每个步骤的表单字段添加专属的验证规则
- 监听q-stepper的
@step切换事件,在切换前验证当前步骤的所有字段 - 验证通过才允许切换步骤,否则阻止跳转并提示错误
代码示例
<template> <q-form ref="formRef" class="q-pa-md"> <q-stepper ref="stepperRef" v-model="currentStep" @step="onStepChange" linear > <!-- 步骤1:基础信息 --> <q-step name="step1" title="基础信息"> <q-input v-model="formData.name" label="姓名" :rules="[requiredRule, minLengthRule]" /> <q-input v-model="formData.email" label="邮箱" :rules="[requiredRule, emailRule]" /> <q-btn label="下一步" @click="stepperRef.next()" /> </q-step> <!-- 步骤2:详细信息 --> <q-step name="step2" title="详细信息"> <q-input v-model="formData.phone" label="手机号" :rules="[requiredRule, phoneRule]" /> <q-select v-model="formData.city" label="城市" :options="cities" :rules="[requiredRule]" /> <q-btn label="上一步" @click="stepperRef.previous()" /> <q-btn label="下一步" @click="stepperRef.next()" /> </q-step> <!-- 步骤3:确认提交 --> <q-step name="step3" title="确认提交"> <div class="q-pa-md"> <p>姓名:{{ formData.name }}</p> <p>邮箱:{{ formData.email }}</p> <p>手机号:{{ formData.phone }}</p> <p>城市:{{ formData.city }}</p> </div> <q-btn label="上一步" @click="stepperRef.previous()" /> <q-btn label="提交" color="primary" @click="onSubmit" /> </q-step> </q-stepper> </q-form> </template> <script setup> import { ref, defineRules } from 'vue' import { useQuasar } from 'quasar' const $q = useQuasar() const formRef = ref(null) const stepperRef = ref(null) const currentStep = ref('step1') // 表单数据 const formData = ref({ name: '', email: '', phone: '', city: '' }) // 验证规则 const { requiredRule, minLengthRule, emailRule } = defineRules({ requiredRule: val => val?.trim() || '必填项', minLengthRule: val => val?.length >= 2 || '至少输入2个字符', emailRule: val => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val) || '请输入有效邮箱' }) // 自定义手机号规则 const phoneRule = val => /^1[3-9]\d{9}$/.test(val) || '请输入有效手机号' // 城市选项 const cities = ref(['北京', '上海', '广州', '深圳']) // 步骤切换时验证当前步骤字段 const onStepChange = async (newStep, oldStep) => { // 只验证离开的步骤(从旧步骤到新步骤) let fieldsToValidate = [] if (oldStep === 'step1') { fieldsToValidate = ['name', 'email'] } else if (oldStep === 'step2') { fieldsToValidate = ['phone', 'city'] } const isValid = await formRef.value.validate(fieldsToValidate) if (!isValid) { $q.notify({ type: 'negative', message: '当前步骤信息填写有误,请检查' }) // 阻止步骤切换 return false } } // 最终提交 const onSubmit = async () => { const isValid = await formRef.value.validate() if (isValid) { // 提交逻辑 $q.notify({ type: 'positive', message: '提交成功' }) } } </script>
二、多个q-form实现分步验证
每个步骤对应一个独立的q-form,每个表单的验证逻辑完全隔离。这种方式适合步骤之间无关联、代码需要模块化拆分的场景。
实现思路
- 给每个步骤单独嵌套
q-form - 切换步骤前,调用当前步骤
q-form的validate()方法 - 验证通过再允许切换,每个表单的状态独立管理
代码示例
<template> <q-stepper ref="stepperRef" v-model="currentStep" @step="onStepChange" linear class="q-pa-md" > <!-- 步骤1:基础信息 --> <q-step name="step1" title="基础信息"> <q-form ref="form1Ref"> <q-input v-model="form1.name" label="姓名" :rules="[requiredRule, minLengthRule]" /> <q-input v-model="form1.email" label="邮箱" :rules="[requiredRule, emailRule]" /> <q-btn label="下一步" @click="stepperRef.next()" /> </q-form> </q-step> <!-- 步骤2:详细信息 --> <q-step name="step2" title="详细信息"> <q-form ref="form2Ref"> <q-input v-model="form2.phone" label="手机号" :rules="[requiredRule, phoneRule]" /> <q-select v-model="form2.city" label="城市" :options="cities" :rules="[requiredRule]" /> <q-btn label="上一步" @click="stepperRef.previous()" /> <q-btn label="下一步" @click="stepperRef.next()" /> </q-form> </q-step> <!-- 步骤3:确认提交 --> <q-step name="step3" title="确认提交"> <div class="q-pa-md"> <p>姓名:{{ form1.name }}</p> <p>邮箱:{{ form1.email }}</p> <p>手机号:{{ form2.phone }}</p> <p>城市:{{ form2.city }}</p> </div> <q-btn label="上一步" @click="stepperRef.previous()" /> <q-btn label="提交" color="primary" @click="onSubmit" /> </q-step> </q-stepper> </template> <script setup> import { ref, defineRules } from 'vue' import { useQuasar } from 'quasar' const $q = useQuasar() const stepperRef = ref(null) const currentStep = ref('step1') // 步骤1表单数据 const form1 = ref({ name: '', email: '' }) const form1Ref = ref(null) // 步骤2表单数据 const form2 = ref({ phone: '', city: '' }) const form2Ref = ref(null) // 验证规则 const { requiredRule, minLengthRule, emailRule } = defineRules({ requiredRule: val => val?.trim() || '必填项', minLengthRule: val => val?.length >= 2 || '至少输入2个字符', emailRule: val => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val) || '请输入有效邮箱' }) const phoneRule = val => /^1[3-9]\d{9}$/.test(val) || '请输入有效手机号' const cities = ref(['北京', '上海', '广州', '深圳']) // 步骤切换验证 const onStepChange = async (newStep, oldStep) => { let currentFormRef = null if (oldStep === 'step1') { currentFormRef = form1Ref.value } else if (oldStep === 'step2') { currentFormRef = form2Ref.value } if (currentFormRef) { const isValid = await currentFormRef.validate() if (!isValid) { $q.notify({ type: 'negative', message: '当前步骤信息填写有误,请检查' }) return false } } } // 合并数据提交 const onSubmit = () => { const fullData = { ...form1.value, ...form2.value } // 提交逻辑 $q.notify({ type: 'positive', message: '提交成功' }) } </script>
总结
- 单个q-form:适合字段联动、统一管理表单状态的场景,最终提交时只需要一次全量验证
- 多个q-form:适合步骤独立、代码拆分更清晰的场景,每个步骤的验证互不干扰,提交时需要合并各步骤数据
内容的提问来源于stack exchange,提问作者Abdou303
相关产品推荐
相关产品推荐

