vue金额限制指令

实现了整数位数、小数位数、是否可录入负数、小数位是否自动补0的控制。太好用了!!!

// numlength.js
/**
 * 触发事件
 * @param {string} name 事件名
 */
function event(name) {
  var evt = document.createEvent('Event')
  evt.initEvent(name, true, true)
  return evt
}
/**
 * 修改光标位置
 * @param {*} el
 * @param {*} position
 */
function setCursor(el, position) {
  var setSelectionRange = function() { el.setSelectionRange(position, position) }
  if (el === document.activeElement) {
    setSelectionRange()
    setTimeout(setSelectionRange, 1) // Android Fix
  }
}
/**
 * 格式化value
 * @param {*} fv 最初的value
 * @param {string} intlen 整数长度
 * @param {string} deciLen 小数长度
 * @param {boolean}  negative  修饰符标识
 * @param {boolean}  short  修饰符标识
 * @param {boolean}  b  blur失去焦点时的格式化标识
 */
function formatVal(fv, intlen, deciLen, negative, short, b) {
  // console.log(negative)
  let value = fv
  let lose = ''
  if (fv.indexOf('-') > -1) { lose = '-' }
  if (fv.indexOf('+') > -1) { lose = '' }
  const v = fv.replace(/[^\d\.]/g, '')
  const vArr = v.split('.')
  vArr.length = vArr.length > 2 ? 2 : vArr.length
  if (intlen || intlen === '0') {
    vArr[0] = vArr[0].slice(0, intlen)// 裁剪 整数部分
  }
  if (b && !vArr[0]) { // 失去焦点后 整数部分为空, 默认给整数0
    vArr[0] = '0'
  }
  if (deciLen && vArr[1]) {
    vArr[1] = vArr[1].slice(0, deciLen)// 裁剪 小数部分
  } else if ((b || deciLen === '0') && !vArr[1]) {
    vArr.length = 1
  }
  if (!negative) { lose = '' }// 默认正数
  const strNum = vArr.join('.')
  if (b && !strNum) {
    value = ''
  } else {
    value = lose + strNum
  }
  if (b && value) {
    value = parseFloat(value).toFixed(deciLen)
    if (short && /\.\d/.test(value)) {
      value = parseFloat(value).toString()
    }
  }
  return value
}
/**
 * input 限制数字长度
 * @author shv
 *
 * 使用方式: el-input 或 input 添加指令
 *   v-money:9_2.negative
 *   说明:
 *     :9_2 : 指令参数 9:整数的位数,取值范围[1-9];2:小数的位数,取值范围[0-9]
 *     .negative : 指令修饰符 允许输入负数,否则默认整数(含小数)
 *     .canempty : 指令修饰符 可以为空 加上后为空字符串时不格式化为0
 *     .short : 指令修饰符 小数位不补零
 *   特殊使用形式:
 *      1   v-money  整数长度默认9  小数长度默认2  只能是正数
 *      2   v-money.negative  整数长度默认9  小数长度默认2  允许输入负数
 *      3   v-money:5_2   整数长度5  小数长度2  只能是正数
 *
 */
export default {
  bind: (el, binding, vnode) => {
    let inputEl = null
    let intlen = '9' // 整数长度默认值(亿级别)
    let deciLen = '2' // 小数长度默认值
    if (el.tagName === 'INPUT') {
      inputEl = el // 支持el-input
    } else {
      inputEl = el.getElementsByTagName('input')[0] // 支持原生input
    }
    if (inputEl) {
      const arg = (binding.arg || '').split('_')
      const modifiers = binding.modifiers
      intlen = arg[0] || intlen
      deciLen = arg[1] || deciLen
      let flag = true
      inputEl.addEventListener('compositionstart', () => {
        flag = false
      })
      inputEl.addEventListener('compositionend', () => {
        flag = true
        inputEl.dispatchEvent(event('input'))
      })
      inputEl.oninput = (e, b) => {
        if (flag) {
          var positionFromEnd = inputEl.value.length - inputEl.selectionEnd
          const fv = e.target.value || '' // 原始value
          if (fv === '' && modifiers.canempty) {
            return
          }
          const lv = formatVal(fv, intlen, deciLen, modifiers.negative, modifiers.short, b) // 最终 value
          if (lv !== fv) { // 防死循环
            e.target.value = lv
            positionFromEnd = lv.length - positionFromEnd
            setCursor(inputEl, positionFromEnd)
            inputEl.dispatchEvent(event('input'))
            // inputEl.dispatchEvent(event('change'))
          }
        }
      }
      inputEl.onblur = (e) => {
        inputEl.oninput(e, true)
        // inputEl.dispatchEvent(event('input'))
      }
    }
  }
}

// main.js
Vue.directive('money', numlength)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值