目的效果:
1、focus时是浮点数
2、blur时展示的是千分符格式
3、输入框取值时是浮点数
4、基于element-ui el-input
<template>
<el-input
:value="formatValue"
v-bind="$attrs"
v-on="inputListeners"
/>
</template>
<script>
export default {
name: 'CurrencyInput',
inheritAttrs: false,
props: {
value: {
type: [String, Number],
default: null,
desc: '数值'
}
},
data: () => {
return {
formatValue: ''
}
},
computed: {
inputListeners: function() {
var vm = this
// `Object.assign` 将所有的对象合并为一个新对象
return Object.assign({},
// 我们从父级添加所有的监听器
this.$listeners,
// // 然后我们添加自定义监听器,
// // 或覆写一些监听器的行为
{
// 这里确保组件配合 `v-model` 的工作
input: function(event) {
vm.formatValue = event
vm.$emit('input', parseFloat(vm.fmoney(event).replace(/,/g, '')))
},
blur: function(event) {
vm.formatValue = vm.fmoney(vm.value)
if (vm.$listeners.blur) {
vm.$listeners.blur(event)
}
},
focus: function(event) {
vm.formatValue = vm.value
}
}
)
}
},
created() {
this.formatValue = this.fmoney(this.value)
},
methods: {
fmoney(s) {
if (s === 0) {
return '0.00'
} else if (
s === '' ||
s == null
) {
return ''
}
var n = 2
var b = parseFloat(s)
n = n > 0 && n <= 20 ? n : 2
if (b < 0) {
s = (-1 * parseFloat((s + '').replace(/[^\d\.-]/g, ''))).toFixed(n) + ''
} else {
s = parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(n) + ''
}
var l = s.split('.')[0].split('').reverse()
var r = s.split('.')[1]
var t = ''
for (var i = 0; i < l.length; i++) {
t += l[i] + ((i + 1) % 3 === 0 && (i + 1) !== l.length ? ',' : '')
}
if (b < 0) {
return '-' + t.split('').reverse().join('') + '.' + r
} else {
return t.split('').reverse().join('') + '.' + r
}
}
}
}
</script>
bug 发现:
IE浏览器下
在input的focus中
vm.formatValue = vm.fmoney(vm.value)
会导致光标移向最左边
当聚焦后主动移动光标
focus: function(event) {
vm.formatValue = vm.value
if (!!window.ActiveXObject || 'ActiveXObject' in window) {
event.target.setSelectionRange(String(vm.value).length, String(vm.value).length)
}
}
setSelectionRange后会阻塞,导致focus时双击事件等一些事件无效,大概会阻塞0.1s左右
参考思路:
[1]vue.js文档 自定义组件的 v-model
[2]基于vue+element的金额格式化组件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。