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

Vue3+Quasar分步表单验证:单/多q-form选型咨询

Vue 3 + Quasar 分步表单验证:单/多q-form方案都可行

两种方案都能实现分步验证,具体选哪种看你的代码结构和需求:

一、单个q-form实现分步验证

把所有步骤的表单控件都放在同一个q-form下,通过验证当前步骤的字段集合来实现分步校验。这种方式适合字段之间有联动、需要统一提交的场景。

实现思路

  1. 给每个步骤的表单字段添加专属的验证规则
  2. 监听q-stepper的@step切换事件,在切换前验证当前步骤的所有字段
  3. 验证通过才允许切换步骤,否则阻止跳转并提示错误

代码示例

<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,每个表单的验证逻辑完全隔离。这种方式适合步骤之间无关联、代码需要模块化拆分的场景。

实现思路

  1. 给每个步骤单独嵌套q-form
  2. 切换步骤前,调用当前步骤q-form的validate()方法
  3. 验证通过再允许切换,每个表单的状态独立管理

代码示例

<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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:14:35