前端 保存前繁琐的静态校验,如何化繁为简

前言

在PC端项目中,经常会遇到新增或编辑保存功能单据页面,通常由表单(header)、表体(body)、脚部(footer)三部分组成。脚部包含多个保存按钮,如存草稿、保存。然而,点击这些按钮并不立即触发接口请求,而是需要前端进行静态校验。只有在静态校验通过后,才会触发接口请求并执行后续逻辑。针对这种场景,我们需要思考如何简化繁琐的静态校验流程。

场景

  • 头部必填项校验:

类型、编号、日期

  • 表体校验必填项校验:

表体列表没有 有效值校验

表体列表数据哪项不为空就金额字段是否有值进一步校验

我们模拟了一个稍微不算复杂的场景,我们先按照我们的正常操作实现,使用vue2为例,template 我们略去

js 复制代码
<script>
export defalt {
    data(){
        return {
            form:{
                type:'',
                code:'',
                date:null
            },
            // 生成30条 空数据
            list :Array.from({length: 30},(_,i)=>{
                return {
                    rowNum: i + 1,
                    money:'',
                    name:''
                }
            })
        }
    },
    methods:{
        // 静态校验
        vaild(){
            if(!this.form.type){
                alert('请选择类型')
                return false
            }else if(!this.form.code){
                 alert('请输入编号')
                 return false
            } else if(!this.form.date){
                 alert('请选择日期')
                 return false
            } else if(!this.list.filter(i=>i.name !== '').length){
                 alert('表体没有有效数据,无法保存!')
                 return false
            } else if(!(this.list.filter(i=>i.name !== '').every(i=>i.money))){
                 alert('有效数据对应的金额没有输入')
                 return false
            } 
            return true
        },
        // 存草稿
        draft(){
            if(this.vaild()){
                // 调用保存草稿的接口
            }
        },
        // 保存
        save(){
            if(this.vaild()){
                // 调用保存的接口
            }
        }
    }
}

</script>

在我遇到的复杂项目中,vaild 部分的代码最多有几百行代码校验,最少十来行代码,其实我们这种优化只有在较为复杂的前端静态校验才能体现出优势,针对以上场景案例,我们重点是优化 静态校验vaild函数里面的校验代码,使其更加易于维护

方案

我们首先编写一个同步校验多个条件的函数,来支撑我们的优化

js 复制代码
/**
 * @description 同步验证多个条件函数
 * @param { Array } vaildList 验证列表
 * @param { Object } commonParamMap 公共参数对象
 * @param { Function } errCallBack 错误时的回调
 * @returns function
 */
function syncCheck(vaildList = [], commonParamMap = {}, errCallBack){
    return function (successCallBack){
        let ret = null
        for (let i = 0; i < vaildList.length; i++) {
            const item = vaildList[i]
            if( typeof item === 'function'){
                const result = item(commonParamMap)
                if(result) {
                    ret = result
                    break
                }
            }
        }
        if(ret){
            errCallBack && errCallBack(ret)
        } else {
            successCallBack && successCallBack()
        }
    }
}

示例

示例使用vue2为例

js 复制代码
<script>
export defalt {
    data(){
        return {
            form:{
                type:'', // 类型
                code:'', // 编号
                date:null // 日期
            },
            // 生成30条 空数据
            list :Array.from({length: 30},(_,i)=>{
                return {
                    rowNum: i + 1,
                    money:'',
                    name:''
                }
            })
        }
    },
    mounted () {
     // 保存前的校验函数
     this.vaildBeforeSave = syncCheck(
     // 校验函数数组。从上往下依次校验,哪个校验返回错位信息就终止,携带错误提示信息走到错误处理函数
     [
         ({ type })=>{
             if(!type()) return '请选择类型'
         },
         ({ code })=>{
             if(!code()) return '请输入编号'
         },
         ({ date })=>{
             if(!date()) return '请选择日期'
         },
         ({ list })=>{
             if(!list().filter(i=>i.name !== '').length) return '表体没有有效数据'
         },
         ({ list })=>{
             if(list().filter(i=>i.name !== '').every(i=>i.money))) {
                 return '有效数据对应的金额没有输入'
             }
         }
     ],
     // 校验函数数组 内部需要解构的数据,在这里进行映射,校验函数需要什么就解构什么
     {
         type:()=>this.form.type,
         code:()=>this.form.code,
         date:()=>this.form.date,
         list: ()=> this.list
     },
     // 校验列表数组一旦有错误信息返回,则会进入到这里。并返回对应的错位提示信息
     (errMsg)=>{
         alert(errMsg)
     })
    },
    methods:{
       
        // 存草稿
        draft(){
            this.vaildBeforeSave(()=>{
                 // 调用保存草稿的接口
            })
        },
        
        // 保存
        save(){
            this.vaildBeforeSave(()=>{
                 // 调用保存的接口
            })
        }
    }
}
</script>

我们通过 同步验证多个条件函数 syncCheck 把校验条件、校验函数需要的变量、校验不通过的处理进行有效的组织起来,形成一条有效且可易于维护的线路,达到我们的化繁为简

结语

我们项目中出现该场景的情况还是比较多的,希望对大家有用,如有疑问,欢迎留言,有更好的 idea,欢迎一起讨论,感谢

24年往期文章:
前端 同时多次调用同个接口,如何只触发一次而不是触发多次
前端 页面不同组件内调用相同接口导致重复调用,如何只触发一次而不是触发多次

相关推荐
勿语&22 分钟前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
黄尚圈圈24 分钟前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水1 小时前
简洁之道 - React Hook Form
前端
ok!ko3 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
正小安3 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
拉里小猪的迷弟4 小时前
设计模式-创建型-常用:单例模式、工厂模式、建造者模式
单例模式·设计模式·建造者模式·工厂模式
_.Switch5 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光5 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   5 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   5 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d