源码放在我的 git 仓库:完整源码
缘由
使用 el-input-number
的过程中,一直有两点困扰我:
-
一个就是没啥用的增减控件,这个还好,设置
:controls="false"
就行了, -
第二个最麻烦,初始值空字符串
''
为0
的问题。这个官方说法是设置初始值为undefined
,那么输入框内就是空的,初始值为其它假值则为0
。于是麻烦的事来了:- 首先,后台传回来的初始值是一般是
null
,那就得自己判断并修改初始值为undefined
; - 其次,表单校验时
0
值算非空,所以必填校验能通过,这个时候需要自己写校验器处理; - 最后,用户填写
0
时,又需要通过必填校验。
- 首先,后台传回来的初始值是一般是
最尴尬的是,有业务需求需要数字在输入框中自动做千分符处理,思前想后还是重构 el-input-number
组件算了。
代码实现
查看 el-input-number
组件的源码会看到它实际上是基于 el-input
组件开发的,其遵循的大体逻辑如下:
- 监听组件
props
中的value
值,将其赋给组件内部的currentValue
- 监听
el-input
组件的input
事件,将输入值赋值给userInput
- 监听
el-input
组件的blur
和change
事件,令userInput = null
- 根据
currentValue
跟userInput
计算el-input
的value
属性值displayValue
不难想到,只要在计算 displayValue
值时增加处理逻辑即可。核心代码如下
export default {
computed: {
//...
displayValue() {
// 用户持续输入时,不计算页面展示值,直接返回
if (this.userInput !== null) {
return this.userInput
}
return this.formatValue(this.currentValue, this.precision)
}
}
methods: {
formatValue(value, precision) {
let reg = /(\d)(?=(?:\d{3})+$)/g
if (typeof value === 'number' && precision !== undefined) {
let val = value.toFixed(precision)
return val.split('.').length > 1
? val.split('.')[0].replace(reg, '$1,') + '.' + val.split('.')[1]
: val.split('.')[0].replace(reg, '$1,')
} else if (typeof value === 'string' && precision !== undefined) {
let val = value.replace(/,/g, '')
val = this.toPrecision(val, precision)
return val.split('.').length > 1
? val.split('.')[0].replace(reg, '$1,') + '.' + val.split('.')[1]
: val.split('.')[0].replace(reg, '$1,')
}
},
//...
}
};