自定义指令文件
moneyFormat.js
/**
* v-money 金额千分位转换
*/
export default {
inserted: inputFormatter({
// 格式化函数
formatter(num, util) {
if(num == null || num == '' || num == 'undefined' || typeof(num) == 'undefined'){
return ''
}
if(util == '万元' || util == '万'){
return formatMoney(num,'wan');
}else if(util == '元'){
return formatMoney(num);
}
// num = num.toString()
// let num1 = num.split(".")[0], num2 = num.split(".")[1];
// let c = num1.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
// return num.toString().indexOf(".") !== -1 ? c + "." + num2 : c;
},
// 解析函数
parser(val) {
val = val.toString().replace(/,/g, "")
console.log(val,'val')
return parseFloat(val) //.replace(/0+$/,"");
},
isNumber: true
})
}
/**
* 监听输入框 数值千位符
* @param {*} param0
* @returns
*/
function inputFormatter({ formatter = (e) => e, parser = (e) => e, limit = (e) => e, watchInput = true, isNumber = false }){
return (el, binding, vnode) => {
console.log(vnode.elm.innerText,'vnode.elm.innerText')
if(vnode.elm.innerText != '元' && vnode.elm.innerText != '万元' && vnode.elm.innerText != '万'){
return
}
let watchVal = true
const input = el.getElementsByClassName("el-input__inner")[0] //$(el).find(".el-input__inner")[0]
// 获取记录光标位置
let selectionSite
let getSelectionSite = (event) => {
let oldVal = event.target.value || ''
let selectionStart = event.target.selectionStart
selectionSite = oldVal.length - selectionStart
}
// 点击、键盘事件更新光标位置
el.addEventListener("click", getSelectionSite)
el.addEventListener("keyup", getSelectionSite)
//为input绑定值赋值
const assignment = (val) => {
vnode.componentInstance.$emit('input', parser(val))
}
// 更改显示的值
const upShow = (val) => {
console.log(val,'valvalval')
vnode.context.$nextTick(() => {
input.value = val
})
}
// 监听绑定值变化
vnode.componentInstance.$watch('value', val => {
if (watchVal) { upShow(formatter(val, vnode.elm.innerText)) }
}, { deep: true, immediate: true })
// 数字格式化
let toNumber = (val) => {
val = val.toString().replace(/[^\d^\.^\-]+/g, "") // 第二步:把不是数字,不是小数点、-的过滤掉
.replace(/^0+(\d)/, "$1") // 第三步:第一位0开头,0后面为数字,则过滤掉,取后面的数字
.replace(/^\./, "0.") // 第四步:如果输入的第一位为小数点,则替换成 0. 实现自动补全
.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".") // 只保留第一个".", 清除多余的"."
// .match(/^\d*(\.?\d{0,9})/g)[0] || ""; // 第五步:最终匹配得到结果 以数字开头,只有一个小数点,而且小数点后面只能有1到9位小数
return val
}
// 处理最后一位非法字符
const handlerIllegalStr = (str) => {
while (!(/^[0-9]+.?[0-9]*/.test(str.charAt(str.length - 1))) && str) {
str = str.substr(0, str.length - 1)
}
return str || ''
}
// 监听input事件,可添加操作
el.addEventListener("input", (event) => {
let selectionStart = input.selectionStart
let val = event.target.value
if (binding.modifiers.number || isNumber) {
val = toNumber(val)
}
let inp = limit(val)
console.log(inp,'inp')
event.target.value = inp
// if (binding.modifiers.watchInput || watchInput) {
// assignment(inp)
// upShow(formatter(parser(val)))
// }
// setTimeout(() => {
// if (selectionSite && input.value.length != selectionStart) {
// input.selectionStart = input.selectionEnd = input.value.length - selectionSite
// }
// }, 0)
})
if (input) {
// 失去焦点
input.addEventListener("blur", (event) => {
watchVal = true
let val = event.target.value;
console.log(val,'失去焦点111')
if(val == null || val == '' || val == 'undefined' || typeof(val) == 'undefined'){
return ''
}
if (binding.modifiers.number || isNumber) {
val = handlerIllegalStr(val)
}
// assignment(val)
upShow(formatter(val, vnode.elm.innerText))
console.log(val,'失去焦点22')
})
// 获取焦点
input.addEventListener("focus", (event) => {
watchVal = false
let val = event.target.value;
if(val == null || val == '' || val == 'undefined' || typeof(val) == 'undefined'){
return ''
}
// val = delcommafy(val);
// assignment(val)
upShow(parser(val))
console.log(parser(val),'获取焦点')
})
}
}
}
//去除千分位中的‘,’
function delcommafy(num){
if (num) {
num = num.toString()
num = num.replace(/,/gi, '')
num = num.replace(/[ ]/g, '') //去除空格
return num
}
return num
}
/**
* 金额千位符转换
* @param {*}} val //金额
* @param {*}} util //单位
* @returns
*/
function formatMoney(val, util) {
if(!val) return val;
// 保留小时位数
var count = util=='wan' ? 6 : 2;
let str = val.toString().split('.');
let re = /\d{1,3}(?=(\d{3})+$)/g;
let n1 = str[0].replace(re, "$&,");
var zeroCount = str.length > 1 && str[1] ? str[1] : ''
// 小数点后面金额位置
var strLength = str.length > 1 && str[1] ? str[1].length : 0
for (let i = 0; i < (count-strLength); i++) {
zeroCount += '0'
}
return str.length > 1 && str[1] ? `${n1}.${zeroCount}` : `${n1}.${zeroCount}`;
}
暴露指令index文件
directiveIndex.vue
import money from './moneyFormat'
const install = function(Vue) {
Vue.directive('money', money)
}
export default install
引入自定义指令
main.js
import directive from './directiveIndex'
Vue.use(directive)
使用方式
<el-input v-model="money" placeholder="请输入金额" v-money>
<template slot="append" >元</template>
</el-input>