阅读 435

单页面表单改造成分步骤的多页面表单

需求

原有的多个模块的表单在同一个页面里面一次性输入。现在需求将同一个页面改成多步多页面来做展示以及交互。这里主要记录的多步骤校验功能的逻辑。。

改造前的页面结构

原功能-1.png

改造后的页面结构

新需求的功能实现.png

代码实现分析

将原有的页面页面结构切分成多个form封装成组件

<div v-show="step === 1">
  <first-form ref="firstForm"/>
</div>
<div v-show="step ===  2">
  <second-form ref="secondForm" />
</div>
<div v-show="step === 3">
  <third-form ref="thirdForm" />
</div>
复制代码

各个步骤进行组件封装,并且对组件内部el-formvalidate方法进行二次封装

<template>
  <section class="first-form">
    <el-form
      label-width="190px"
      :rules="rules"
      :model="ruleForm"
      @submit.native.prevent
    >
      <el-form-item prop="field1" label="字段1">
        <el-input v-model.trim="ruleForm.field1" />
      </el-form-item>

      <el-form-item prop="field2" label="字段2">
        <el-input v-model="ruleForm.field2" />
      </el-form-item>
    </el-form>
  </section>
</template>
<script>
export default {
  data() {
    return {
      ruleForm: { field1: '', field2: '', },
      rules: {
        field1: [{ required: true, this.editFlag,message:  '请输入',trigger: 'change'}],
      },
    }
  },
  methods: {
    validate() {
      return new Promise(res => {
        this.$refs.ruleForm.validate(async valid => res(valid))
      })
    },
  }
}
</script>
复制代码

当前以第一步作为例子

每个步骤的方法封装

async checkFirstStep() {
    try {
      if (!(await this.$refs.firstForm.validate())) await this.checkFail('第一步填错了!')
    } catch (e) {
      return Promise.reject(1)
    }
},
// 以下第二步 第三步 与第一步类似
async checkSecondStep() {
    try {
      if (!(await this.$refs.secondForm.validate())) await this.checkFail('第二步填错了!')
    } catch (e) {
      return Promise.reject(2)
    }
}
async checkThirdStep() {
    try {
      if (!(await this.$refs.thirdForm.validate())) await this.checkFail('第三步填错了!')
    } catch (e) {
      return Promise.reject(3)
    }
}
// 校验错误走的公共方法
async checkFail(message) {
    if (message) this.$message.error(message)
    return Promise.reject()
}
复制代码

const p = Promise.reject(3);
// 等同于
const p = new Promise((resolve, reject) => reject(3))
es6.ruanyifeng.com/#docs/promi…

【下一步】按钮点击校验逻辑

async nextStep() {
    try {
      switch (this.step) {
        case 1:
          await this.checkFirstStep()
          break
        case 2:
          await this.checkSecondStep()
          break
        case 3:
          await this.checkThirdStep()
          // 将页面数据带到 下一个 页面
          await this.setNextPageData()
          break
      }
      this.step++
    } catch (e) {
      console.error(e)
    }
},
复制代码

【创建】按钮功能实现

async confirmTap() {
    try {
      // 各个步骤开始校验
      await this.checkFirstStep()
      await this.checkSecondStep()
      await this.checkThirdStep()
      // 前几步校验都过了 跳到下单页
      await this.setOrderDetail()
      this.step = this.stepList.length
    } catch (e) {
      if (typeof e !== 'number') return
      // 定位到 错误页面的相关选项
      this.step = e
    }
}, 
复制代码
  • checkXxxxStep方法中校验验没有通过中封装了一个 reject,同时 reject抛出当前具体步骤
  • 在该方法内部 await 来判定校验是否正确
  • 如果错误 catch来做具体跳转
文章分类
前端
文章标签