日前接到需求需要实现获取焦点数值型输入框以普通字符显示,失去焦点要用千分位符显示。
首先在 main.js 中加入
var desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')
Object.getOwnPropertyDescriptor
() 静态方法返回一个对象,该对象描述给定对象上特定属性(即直接存在于对象上而不在对象的原型链中的属性)的配置。返回的对象是可变的,但对其进行更改不会影响原始属性的配置。
Object.defineProperty() 该方法允许查看属性的精确描述。在 JavaScript 中,一个属性由一个字符串值的名称或一个 Symbol 和一个属性描述符组成。关于属性描述符类型及其特性的更多信息可以在 Object.defineProperty() 中找到。
获取所有加入特殊标识的(numInput)的 input 输入框并实时监听值的变化
<el-input size="default" v-model="param.registeredCapital" placeholder="请填写数字,支持小数点后 6 位" v-numInput numInput="true" @input="proxy.numberFilter(9, 6, param, 'registeredCapital')" />
Object.defineProperty(HTMLInputElement.prototype, 'value', {
...desc,
set(v) {
// let upCls = document.getElementsByClassName('el-upload-list__item-file-name')
// 判断是否要修改值
if (this.getAttribute('numInput') === 'true' && v) {
v = $number.formatCurrencyInput(v)
}
desc.set.call(this, v)
}
})
Object.defineProperty()
静态方法会直接在一个对象上定义一个新属性,或修改其现有属性,并返回此对象。
添加指令,监听失去焦点与获取焦点的事件,修改 numInput 属性触发 Object.defineProperty()
// 自定义指令 数字输入框用千分位符分割
app.directive('numInput', {
beforeMount(el, binding, vnode) {
let input = el.children[0].children[0]
// 获取焦点
input.addEventListener('focus', function(ev) {
// 修改是否转换属性为false
input.setAttribute('numInput', 'false')
let e = input.value.split(',')
input.value = e.join('')
})
// 失去焦点
input.addEventListener('blur', function(ev) {
input.value = $number.formatCurrencyInput(input.value)
// 修改是否转换属性为true
input.setAttribute('numInput', 'true')
})
}
})
转换千分位符 $number.formatCurrencyInput()
const formatCurrencyInput = (s) => {
if (s === undefined || s === null || !Number(s) || s === '') {
return s;
}
s = s.toString()
// n为小数点后保留小数位
// s = parseFloat((s + "").replace(/[^\d\.-]/g, "")).toFixed(n) + "";
let l = s.split(".")[0].split("").reverse()
let r = s.split(".")[1] || '';
let t = "";
for (let i = 0; i < l.length; i++) {
t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length && l[i + 1] != '-' ? "," : "");
}
return t.split("").reverse().join("") + (r ? ("." + r) : '');
// return Number(s)
};
至此功能完成,传给后端也是数字不带有千分位符,页面失去焦点显示千分位符。