事件的起因是我在几个项目中多次碰到了input组件限制输入纯数字的需求,之前只能在方法里面各种使用正则,一顿猛如虎的操作下干巴巴地实现了需求。这次我决定正视它,刚好把js正则的基础使用一并学习下。相信我遇到的以下需求,各位应该都能经常碰到。 因为这个功能比较常见,需要重复利用,遂封装成为了一个组件,下面贴出👶组件核心代码:
const vm = new Vue({
el: '#app',
data: {
msg: '输入框限制只能输入数字,并且对小数点后可以输入几位做限制',
pureNum: '', // 纯数字
// 自定义一个组件
components: {
'custom-input': {
props: {
// 默认值
defaultNum: {
type: String,
deafault: ''
// 是否正整数
isInt: {
type: Boolean,
default: true
// 小数点后保留几位
keepPoint: {
type: Number,
default: 2
data() {
return {
inputVal: this.defaultNum
methods: {
// 在 Input 值改变时触发
handleInput(val,event) {
if (this.isInt) {
// \D 查找非数字字符 n+ 匹配任何包含至少一个n的字符串
// 匹配任何包含至少一个非数字字符的字符串
let value = event.target.value.replace(/\D+/,'')
this[val] = value
} else {
/* 1.匹配必须要是数字(任何包含至少一个数字) \d 查找数字
* 2.匹配只包含小数点零个或者一个以内 n? 匹配任何包含零个或一个n的字符串
* 3.匹配零个或多个数字的字符串 n* 匹配任何包含零个或多个n的字符串 */
// 在字符串内检索指定的值 返回值是存放匹配结果的数组
let matchArr = event.target.value.match(/\d+\.?\d*/)
this[val] = matchArr ? matchArr[0] : ''
// 保留小数点还要判断 因为如果定义了isInt:false也可以输入正整数
let str = String(this[val])
if (this.keepPoint) {
if (str.includes('.')) {
// 例如数据为 123.4567 ==> 123.45
/* 1.通过 indexOf('.')找到包含小数点位置的索引值
* 2.读取几位从这个索引值的位置开始+(.xx)共三位数|+(.xxx)共四位数
* 3.string.indexOf('.') + length + 1 substr(start,length) */
this[val] = str.substr(0,str.indexOf('.')+(this.keepPoint+1))
} else {
// 此处控制的是如果没有小数点,首位不能为类似于 01、02的金额
if (str != '') {
this[val] = String(parseFloat(this[val]))
// this[val] 其实就是 inputVal
this.$emit('update',this[val])
// 下面只不过利用的是elementUI的输入框的样式 因为原生的input事件默认的参数就是事件对象
// 如果传入多个参数的话 事件对象放在最后
template: `
<input class="el-input__inner"
v-model="inputVal"
@input="handleInput('inputVal', $event)"
placeholder="请输入上面要求的数字"
</input>
<p>{{inputVal}}</p>
应用到👨组件时候的代码:
<div id="app">
<!-- 当使用的不是字符串模板时,驼峰式命名的prop(js中命名的)在html中使用时要转换成kebab-case -->
<el-card style="width: 50%;">
<custom-input
:default-num="pureNum"
@update="pureNum = $event"
:is-int="false"
:keep-point="2"
</custom-input>
</el-card>
真正实现功能的代码量其实并不多,我很喜欢写注释,只要感觉有点不懂的就记下来,努力做到注释比代码多~