博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vux之x-input使用以及源码解读
阅读量:7095 次
发布时间:2019-06-28

本文共 5910 字,大约阅读时间需要 19 分钟。

前言

  1. 近期项目中使用的vux中的input,以及使用自定义校验规则和动态匹配错误提示,有时间记录下自己的使用经历和源码分析。希望大家多多指正,留言区发表自己宝贵的建议。

详解

  1. 列举中常用的几个属性的使用方法,代码如下
复制代码

官方文档有详细的解释,required属性表示此选项为必填,is-type可以绑定一个函数,作为校验,这个函数得返回一个对象。格式如下

checkValid(name) {      return {        valid: name === '三只萌新',        msg: '你不是萌新'      }    }复制代码

valid可以设置为你的校验规则,需要返回一个布尔值,msg是错误的提示信息。

vux本身写好几种校验方式,如果使用email,china-name,china-mobile这几种方式直接绑定字符串即可。
solt插槽如slot="label"用于自定义title,源码如下

{
{ inlineDesc }}
复制代码

分析:class="labelClass"动态绑定样式以对象的形式返回一个{[className]:Boolean}的格式的对象

labelClass() {      return {        'vux-cell-justify':          this.$parent.labelAlign === 'justify' ||          this.$parent.$parent.labelAlign === 'justify'      }    }复制代码

同样的方式查看他父级是否有labelAlign属性,vux-cell-justify类名对应的样式没有应用。

使用场景

场景1

假设在一个提交页面,当我们提交时判断输入框中的值是否是符合我们的要求,如果不符合,给出错误提示,如果符合提交后将输入框中的数据清空。

需求:

  • 如果还有停留在本页面我们需要将上一次的数据全部清空

问题:

  • 我们需要初始化值,但是会发现如果我们设置了required后校验还是会触发。如何让数据清空并且让校验也清空。

解决方法:

  • 文档中写了reset可以重置输入框值,清除错误信息 使用方式:
  • 在x-input外层的group标签上绑定ref来访问子组件。因此我们可以通过 this.$refs.group.$children获取到input组件集合并且可以使用组件中定义的reset方法 查看源码
  • 如果你的项目中已经安装了vux可以通过安装查找node_modules文件夹中vux安装包路径为vux/src/components/x-input/index.vue文件 reset方法源码如下:
reset(value = '') {      this.dirty = false      this.currentValue = value      this.firstError = ''      this.valid = true    }复制代码

回到我们的业务逻辑中当我们点击提交按钮时代码如下

onSubmitClick() {      if (!this.isInvalid) {        this.$refs.group.$children.forEach(child => {          child.reset()        })      } else {      // 展示提示信息        this.isShowToast = true      }复制代码

本以为这样就可以清空数据了,没想到点击按钮时数据是清空了,但是还是有报错图标显示。

通过 可以看到
valid的值为false查看vux源码查看涉及到valid代码如下

validate() { // ...省略与本次无关的校验方法if (!this.currentValue && this.required) {        this.valid = false        this.errors.required = '必填哦'        this.getError()        return        if (typeof this.isType === 'function') {        /*           取出自定义函数中的校验结果 是一个Boolean          checkNameValid(name) {            return {              valid: name === '三只萌新',              msg: '你不是萌新'            }          }        */        const validStatus = this.isType(this.currentValue)        this.valid = validStatus.valid        if (!this.valid) {        // 如果校验值无效将自定义校验的msg赋值给errors对象下的format          this.errors.format = validStatus.msg          this.forceShowError = true          this.getError()          return        } else {        // 如果校验值有效则将error对象下的format删除              delete this.errors.format        }        // 如果都符合将valid赋值为有效      this.valid = true    }}复制代码

validate函数校验当前是否有值,是否为必填,如果当前值的校验方式是函数,将校验结果赋值给valid。如果valid是false则将自定义的msg统一存储在errors对象下,errors是用来存储不同类型的错误信息。 然后执行getError函数

getError() {      let key = Object.keys(this.errors)[0]      this.firstError = this.errors[key]      console.log('firstError' + this.firstError)    }复制代码

Object.keys(this.errors)返回errors对象下的所有可枚举属性,并且取第一个作为键名,取出对于的值赋值给firstError ,firstError是提示框文字

{
{ firstError }}
复制代码

当点击错误图标判断是否有firstError,shouldToastError未传入值默认为true,点击时如果valide校验为错误时会触发getError函数将错误提示赋值给firstError,所以会将fistError对应的提示信息显示出来。而图标的显示与否与valid有关,其中一个条件是valid为false时才会显示。

shouldToastError: { type: Boolean, default: true } showWarn() { return ( !this.novalidate && !this.equalWith && !this.valid && this.firstError && (this.touched || this.forceShowError) ) } onClickErrorIcon() { if (this.shouldToastError && this.firstError) { this.showErrorToast = true } this.$emit('on-click-error-icon', this.firstError) }复制代码

分析了上面的代码,为什么执行了reset方法后,校验报错还是在,原因是valid依然还是false,导致showWarn返回值是ture,而reset中方法中明明将valid设置为true了,为什么最后结果为false。

watch:{      currentValue(newVal, oldVal) {           if (newVal && this.equalWith) {            if (newVal.length === this.equalWith.length) {              this.hasLengthEqual = true            }            this.validateEqual()          } else {            this.validate()          }      }}复制代码

因为监听了input绑定currentValue的值,当reset方法执行的时候this.currentValue = ' ' 触发了变动执行validate方法,导致再次给this.valid赋值false。

该如何解决这个问题,问题发生的原因是currentValue发生变化导致触发validate方法校验,所以我们只要当执行reset方法后不触发currentValue改变就可以不触发validate方法校验
方法一:

onSubmitClick() {    this.$refs.group.$children.forEach(child => {     // 这次reset是将currentValue全部置为""      child.reset()    })    this.$nextTick(() => {    // 当所以input的值都置为空后在此执行reset方法,这次前后currentValue没有发生变化不会触发validate校验所以valide为true不会导致图标出现      this.$refs.group.$children.forEach(child => {        child.reset()      })    })}复制代码

方法二: 其实想做的就是在reset方法执行之前将currentValue置为空

created(){    this.currentValue =      this.value === undefined || this.value === null        ? ''        : this.mask ? this.maskValue(this.value) : this.value},props:{    value: [String, Number]},watch:{    value(val) {      this.currentValue = val    }}复制代码

可以通过传入value来改变currentValue的值,将v-model="name"绑定值的方式改为:value="name"

onSubmitClick() {    this.name = ''    this.$nextTick(() => {      this.$refs.group.$children.forEach(child => {        child.reset()      })    })}复制代码

场景2

当我们点击提交时,如果有校验选项不符合规则能提示相匹配的警告

data(){    return {        message: '还未填写信息'    }}复制代码

将message提示信息初始值设置为还未填写信息,当我们未进行填写信息的时候点击提交显示。然后使用on-change函数绑定校验规则,实时更新message对应的提示语,业务逻辑如下:

onValueChange() {      // 多次使用赋值给变量      const children = this.$refs.group.$children      let statusList = []      // 筛选出有值的,作为是否全部未填的判断依据 如果length小于1则还没填写任何内容      statusList = children.filter(item => {        return item.currentValue      })      if (statusList.length < 1) {        this.message = '还未填写信息'        return      }      // 找到第一个没有值的那一项,如果都有则返回undefined      const firstInvalid = children.find(item => {        return !item.valid      })      if (firstInvalid !== undefined) {        this.message = `请填写正确的${firstInvalid.title}`      }      // 显示的将是否有效赋值给valid增加代码可读性      this.valid = Boolean(firstInvalid)    }复制代码

github

转载地址:http://cnaql.baihongyu.com/

你可能感兴趣的文章
[日推荐]『与你见字如面』信息时代的一股清流
查看>>
如何准备BAT技术面试答案(中)——Java研发方向
查看>>
Android - 文件读写操作 总结
查看>>
应对小规模DDOS:使用nginx_lua打造PHP应用防火墙
查看>>
SpringMVC+MyBatis项目总结(三)
查看>>
CentOS minimal 安装后网络配置
查看>>
自己实现一个Python调试器
查看>>
Hadoop分析
查看>>
印度帮是如何统治硅谷的?
查看>>
Android监听SD卡文件变化
查看>>
DES加密和解密
查看>>
Apache2.2.21的httpd命令详解
查看>>
创建节点参数-name和-sname的区别
查看>>
git分支管理策略
查看>>
CentOS 7 使用国内源加速 Docker pull 镜像
查看>>
Nodejs 的express框架
查看>>
mysql,oracle批量导入数据
查看>>
顶天立地
查看>>
python-------memcache
查看>>
SimpleDateFormat转换时间,12,24时间格式
查看>>