浅谈vux之x-input使用以及源码解读


Posted in Javascript onNovember 04, 2018

前言

近期项目中使用的vux中的input,以及使用自定义校验规则和动态匹配错误提示,有时间记录下自己的使用经历和源码分析。希望大家多多指正,留言区发表自己宝贵的建议。 详解 列举官方文档中常用的几个属性的使用方法,代码如下

<group ref="group">
  <x-input v-model="name"
  class="vux-input__name"
  title="名字"
  placeholder="tell me your name"
  required
  :is-type="checkNameValid"
  @on-change="onValueChange">
  <div slot="label"
   class="name__icon">
   <icon type="success"></icon>
  </div>
  </x-input>
 </group>

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

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

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

vux本身写好几种校验方式,如果使用 email,china-name,china-mobile 这几种方式直接绑定字符串即可。

solt插槽如slot="label"用于自定义title,源码如下

<slot name="label">
 <label class="weui-label"
  :class="labelClass"
  :style="{width: labelWidth || $parent.labelWidth || labelWidthComputed, textAlign: $parent.labelAlign, marginRight: $parent.labelMarginRight}"
  v-if="title"
  v-html="title"
  :for="`vux-x-input-${uuid}`"></label>
 <inline-desc v-if="inlineDesc">{{ inlineDesc }}</inline-desc>
 </slot>

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

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

浅谈vux之x-input使用以及源码解读 

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

使用场景

场景1

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

需求:

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

问题:

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

解决方法:

文档中写了reset可以重置输入框值,清除错误信息

使用方式:

在x-input外层的group标签上绑定ref来访问子组件。因此我们可以通过 this.$refs.group.$children获取到input组件集合并且可以使用组件中定义的reset方法

如果你的项目中已经安装了vux可以通过安装Search node_modules查找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
  }

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

浅谈vux之x-input使用以及源码解读 

通过 vue-devtools可以看到

浅谈vux之x-input使用以及源码解读

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是提示框文字

<toast v-model="showErrorToast"
  type="text"
  width="auto"
  :time="600">{{ firstError }}</toast>

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

<icon @click.native="onClickErrorIcon"
  class="vux-input-icon"
  type="warn"
  :title="!valid ? firstError : ''"
  v-show="showWarn"></icon>
  
 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:代码地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
EXT窗口Window及对话框MessageBox
Jan 27 Javascript
JavaScript计算两个日期时间段内日期的方法
Mar 16 Javascript
JavaScript实现将UPC转换成ISBN的方法
May 26 Javascript
js实现的简洁网页滑动tab菜单效果代码
Aug 24 Javascript
javascript中异常处理案例(推荐)
Oct 03 Javascript
值得分享的JavaScript实现图片轮播组件
Nov 21 Javascript
详解微信小程序开发之下拉刷新 上拉加载
Nov 24 Javascript
通过修改360抢票的刷新频率和突破8车次限制实现方法
Jan 04 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
Jul 31 Javascript
JavaScript选取(picking)和反选(rejecting)对象的属性方法
Aug 16 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
Aug 06 Javascript
js之ajax文件上传
May 13 Javascript
小程序实现选择题选择效果
Nov 04 #Javascript
小程序实现单选多选功能
Nov 04 #Javascript
Vuex的基本概念、项目搭建以及入坑点
Nov 04 #Javascript
微信小程序实现登录注册tab切换效果
Dec 29 #Javascript
原生js实现淘宝放大镜效果
Oct 28 #Javascript
微信小程序如何获取手机验证码
Nov 04 #Javascript
微信小程序实现弹出层效果
May 26 #Javascript
You might like
PHP之短标签开启设置
2013/06/17 PHP
深入理解PHP中的empty和isset函数
2016/05/26 PHP
微信公众号开发之通过接口删除菜单
2017/02/20 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
使用onbeforeunload属性后的副作用
2007/03/08 Javascript
jquery实现点击TreeView文本父节点展开/折叠子节点
2013/01/10 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
javascript判断移动端访问设备并解析对应CSS的方法
2015/02/05 Javascript
解决js图片加载时出现404的问题
2020/11/30 Javascript
js实现根据身份证号自动生成出生日期
2015/12/15 Javascript
Bootstrap创建可折叠的组件
2016/02/23 Javascript
JavaScript中的boolean布尔值使用学习及相关技巧讲解
2016/05/26 Javascript
JavaScript 冒泡排序和选择排序的实现代码
2016/09/03 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
2016/09/19 Javascript
详解如何在vue项目中引入elementUI组件
2018/02/11 Javascript
vue 过滤器filter实例详解
2018/03/14 Javascript
微信小程序搜索功能(附:小程序前端+PHP后端)
2019/02/28 Javascript
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
[39:19]完美世界DOTA2联赛PWL S2 SZ vs LBZS 第二场 11.26
2020/11/30 DOTA
Python使用py2exe打包程序介绍
2014/11/20 Python
python3监控CentOS磁盘空间脚本
2018/06/21 Python
Python之list对应元素求和的方法
2018/06/28 Python
python实现多人聊天室
2020/03/31 Python
详解Django模版中加载静态文件配置方法
2019/07/21 Python
浅谈tensorflow模型保存为pb的各种姿势
2020/05/25 Python
css3和jquery实现的可折叠导航菜单适合放在手机网页的导航菜单
2014/09/02 HTML / CSS
英国最大最好的无人机商店:Drones Direct
2019/07/12 全球购物
心理健康课教学反思
2014/02/13 职场文书
菜篮子工程实施方案
2014/03/08 职场文书
《吃水不忘挖井人》教学反思
2014/04/15 职场文书
道德大讲堂实施方案
2014/05/14 职场文书
导师工作推荐信范文
2014/05/17 职场文书
安全生产承诺书范文
2014/05/22 职场文书
2015年“世界无车日”活动方案
2015/05/06 职场文书
浅谈MySQL 亿级数据分页的优化
2021/06/15 MySQL
深入浅析python3 依赖倒置原则(示例代码)
2021/07/09 Python