【directives】自定义指令之input数值
2022-06-24 本文已影响0人
两年半练习程序员
需求
由于input输入框的number类型不调好用,故通过自定义指令给element el-input组件设置输入限制
功能
1.可设置允许输入的最大最小值
2.可设置精度
3.限制非数值输入
输入限制
1.小数点"."
不允许出现在第一位,且只允许输入一次
2.负号"-"
仅可以出现在第一位,且配置最小值允许出现负值时可用
3.限制输入法的输入事件
未实现功能TODO/(ㄒoㄒ)/~~
精度拦截目前在输入时未做拦截
原因
:在输入框输入达到精度限制时,此时按ctrl+a
想要执行覆盖选中重新输入
操作时,输入事件会判断达到输入精度做大值,无法执行上述操作
替换方案
:在输入框失去焦点时做精度格式化
有解决方案的小伙伴欢迎解答 😀T_T
demo如下👇
提供三个参数
{min: -100, max: 100, precision: 2},
1.min最小值:默认-100
2.max最小值:默认100
3.precision精度(保留小位数):默认2
'懒人'提醒
可根据需求修改默认值,或设置为null不做限制
只需将demo中对应的监听事件里 声明的 _min 和 _max 和 _precision 改为想要的默认值即可
//keypress下
let _precision = 2;
let _max = 100;
let _min = -100;
//keyup下
let _precision = 2;
let _max = 100;
let _min = -100;
//focusout
let _precision = 2;
<template>
<div class="hello">
<el-input
type="text"
v-model="test"
v-only-number="{ min: -100, max: 100, precision: 2 }"
></el-input>
</template>
<script>
export default {
name: "HelloWorld",
directives: {
onlyNumber: {
// 只调用一次,第一次绑到元素时调用。在这里可以进行一次性的初始化设置。
bind: function (el, vDir) {
let dom = el.tagName == "INPUT" ? el : el.querySelector("input");
dom.placeholder = "请输入数值" + JSON.stringify(vDir.value);
},
// 当被绑定的元素插入到 DOM 中时
inserted: function (el, vDir) {
let dom = el.tagName == "INPUT" ? el : el.querySelector("input");
//记录当前值
let content = dom.value;
//插槽参数
let config = vDir.value;
/**
* @function 输入有效值监听事件
* @description 只允许输入 数字/小数点/负号
*/
el.addEventListener("keypress", (e) => {
//阻止输入
function preventInput() {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}
let re = /\d|\.|-/; //只允许输入 数字/小数点/负号
let key = e.key; //输入值
content = e.target.value; //输入值生效前的值
//配置
let _precision = 2;
let _max = 100;
let _min = -100;
if (config) {
_precision = parseInt(config.precision);
_max = parseFloat(config.max);
_min = parseFloat(config.min);
}
if (!re.test(key)) {
preventInput();
} else if ((content.indexOf(".") > 0 || !content) && key == ".") {
// .不允许出现在第一位,且只允许输入一次
preventInput();
} else if ((_min >= 0 || content) && key == "-") {
// "-"号仅可以出现在第一位,且配置最小值允许出现负值
preventInput();
} else if (
// 精度拦截
content.split("").reverse().join("").indexOf(".") == _precision
) {
// preventInput();
}
});
el.addEventListener("keyup", (e) => {
let value = e.target.value; //输入值生效后的值
//输入非数值,keypress已过滤,此处过滤输入法输入中文情况
if (isNaN(value) && value !== "-") {
e.target.value = content;
return false;
}
content = value;
//精度
let _precision = 2;
let _max = 100;
let _min = -100;
if (config) {
_precision = parseInt(config.precision);
_max = parseFloat(config.max);
_min = parseFloat(config.min);
}
if (value > _max) {
e.target.value = _max;
content = _max;
}
if (value < _min) {
e.target.value = _min;
content = _min;
}
});
el.addEventListener("focusout", (e) => {
let value = e.target.value;
//精度
let _precision = 2;
if (config) {
_precision = parseInt(config.precision);
}
e.target.value =
value != "" ? parseFloat(value).toFixed(_precision) : "";
dom.dispatchEvent(new Event("input"));
});
},
},
},
data() {
return {
test: "",
};
},
watch:{
test(){
console.log('watch test',this.test)
}
}
};
</script>