封装表单验证解决一站式项目需求

常规来说 思路是这样的

let Form = document.querySelector('#Form')
  Form.addEventListener('submit', function() {
      if (Form.userName.value === '') {
          alert('用户名不能为空!')
          return false
      }
      if (Form.userName.length < 6) {
          alert('用户名长度不能少于6位!')
          return false
      }
      if (Form.passWord.value === '') {
          alert('密码不能为空!')
          return false
      }
      if (Form.passWord.value.length < 6) {
          alert('密码长度不能少于6位!')
          return false
      }
      if (Form.phoneNumber.value === '') {
          alert('手机号码不能为空!')
          return false
      }
      if (!/^1(3|5|7|8|9)[0-9]{9}$/.test(Form.phoneNumber.value)) {
          alert('手机号码格式不正确!')
          return false
      }
      if (Form.email.value === '') {
          alert('邮箱地址不能为空!')
          return false
      }
      if (!/^\w+([+-.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
      $/.test(Form.email.value)) {
          alert('邮箱地址格式不正确!')
          return false
      }
  }, false)

呃:这样的方法是不是很让人low[or]烦
这里说下方法,这也是我在以后项目中的——省时省事的方法

要实现的最终结果是:

// 获取表单form元素
let Form = document.querySelector('#Form')

// 创建表单校验实例
let validator = new Validator();
// 编写校验配置
validator.add(Form.userName, 'isNonEmpty', '用户名不能为空')
validator.add(Form.userName, 'minLength:6', '用户名长度不能小于6')

// 开始校验,并接收错误信息
let errorMsg = validator.start()

// 如果有错误信息输出,说明校验未通过
if(errorMsg){
    alert(errorMsg)
    return false//阻止表单提交
}

策略模式

注意,注意,注意 重要的事说三遍
策略模式其实就是解决事情的方法,比如说我们要去旅行:

  • 可以乘坐:灰机,火车,地铁, 汽车,组团坐大巴,走路………..

我们今天要讲的策略模式也就是这个意思,它的核心思想是,将做什么和谁去做相分离。所以,一个完整的策略模式要有两个类,一个是策略类,一个是环境类(主要类),环境类接收请求,但不处理请求,它会把请求委托给策略类,让策略类去处理,而策略类的扩展是很容易的,这样,使得我们的代码易于扩展。

策略模式的组成
  • 抽象策略角色:策略类,通常由一个接口或者抽象类实现。
  • 具体策略角色:包装了相关的算法和行为。
  • 环境角色:持有一个策略类的引用,最终给客户端用的。
编写策略类
/*策略对象*/
const strategies = {
        isNonEmpty(value, errorMsg) {
            return value === '' ?
                errorMsg : void 0
        },
        minLength(value, length, errorMsg) {
            return value.length < length ?
                errorMsg : void 0
        },
        isMoblie(value, errorMsg) {
            return !/^1(3|5|7|8|9)[0-9]{9}$/.test(value) ?
                errorMsg : void 0
        },
        isEmail(value, errorMsg) {
            return !/^\w+([+-.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(value) ?
                errorMsg : void 0
        }
    }
编写Validator类
/*Validator类*/
class Validator {
    constructor() {
        this.cache = []                                 //保存校验规则
    }
    add(dom, rules) {
        for (let rule of rules) {
            let strategyAry = rule.strategy.split(':') //例如['minLength',6]
            let errorMsg = rule.errorMsg               //'用户名不能为空'
            this.cache.push(() => {
                let strategy = strategyAry.shift()     //用户挑选的strategy
                strategyAry.unshift(dom.value)         //把input的value添加进参数列表
                strategyAry.push(errorMsg)             //把errorMsg添加进参数列表,[dom.value,6,errorMsg]
                return strategies[strategy].apply(dom, strategyAry)
            })
        }
    }
    start() {
        for (let validatorFunc of this.cache) {
            let errorMsg = validatorFunc()             //开始校验,并取得校验后的返回信息
            if (errorMsg) {                            //如果有确切返回值,说明校验没有通过
                return errorMsg
            }
        }
    }
}
客户端调用代码
/*客户端调用代码*/
let Form = document.querySelector('#Form')
const validatorFunc = () => {
    let validator = new Validator()

    validator.add(Form.userName, [{
        strategy: 'isNonEmpty',
        errorMsg: '用户名不能为空!'
    }, {
        strategy: 'minLength:6',
        errorMsg: '用户名长度不能小于6位!'
    }])

    validator.add(Form.passWord, [{
        strategy: 'isNonEmpty',
        errorMsg: '密码不能为空!'
    }, {
        strategy: 'minLength:',
        errorMsg: '密码长度不能小于6位!'
    }])

    validator.add(Form.phoneNumber, [{
        strategy: 'isNonEmpty',
        errorMsg: '手机号码不能为空!'
    }, {
        strategy: 'isMoblie',
        errorMsg: '手机号码格式不正确!'
    }])

    validator.add(Form.email, [{
        strategy: 'isNonEmpty',
        errorMsg: '邮箱地址不能为空!'
    }, {
        strategy: 'isEmail',
        errorMsg: '邮箱地址格式不正确!'
    }])
    let errorMsg = validator.start()
    return errorMsg
}

Form.addEventListener('submit', function() {
    let errorMsg = validatorFunc()
    if (errorMsg) {
        alert(errorMsg)
        return false
    }
}, false)

在修改某个校验规则的时候,只需要编写或者改写少量的代码。比如我们想要将用户名输入框的校验规则改成用户名不能少于4个字符。可以看到,这时候的修改是毫不费力的。代码如下:

 validator.add(registerForm.userName, [{
        strategy: 'isNonEmpty',
        errorMsg: '用户名不能为空!'
    }, {
        strategy: 'minLength:4',
        errorMsg: '用户名长度不能小于4位!'
    }])

下面ES6的Proxy对象来实现

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

利用Proxy重构表单验证

利用proxy拦截不符合要求的数据

function validator(target, validator, errorMsg) {
    return new Proxy(target, {
        _validator: validator,
        set(target, key, value, proxy) {
            let errMsg = errorMsg
            if (value == '') {
                alert(`${errMsg[key]}不能为空!`)
                return target[key] = false
            }
            let va = this._validator[key]
            if (!!va(value)) {
                return Reflect.set(target, key, value, proxy)
            } else {
                alert(`${errMsg[key]}格式不正确`)
                return target[key] = false
            }
        }
    })
}

负责校验的逻辑代码

const validators = {
        name(value) {
            return value.length > 6
        },
        passwd(value) {
            return value.length > 6
        },
        moblie(value) {
            return /^1(3|5|7|8|9)[0-9]{9}$/.test(value)
        },
        email(value) {
            return /^\w+([+-.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(value)
        }
    }

客户端调用代码

const errorMsg = { name: '用户名', passwd: '密码', moblie: '手机号码', email: '邮箱地址' }
const vali = validator({}, validators, errorMsg)
let Form = document.querySelector('#Form')
Form.addEventListener('submit', function() {
        let validatorNext = function*() {
            yield vali.name = Form.userName.value
            yield vali.passwd = Form.passWord.value
            yield vali.moblie = Form.phoneNumber.value
            yield vali.email = Form.email.value
        }
        let validator = validatorNext()
        validator.next();
        !vali.name || validator.next(); //上一步的校验通过才执行下一步
        !vali.passwd || validator.next();
        !vali.moblie || validator.next();
    }, false)

es6语法记得 babel

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值