input 字符串长度限制,中文字符算两个
2021-08-25 本文已影响0人
royluck
<a-input v-model="inputValue" @change="onChange" style="width:300px"/>
onChange(e) {
let str = e.target.value
// 字符串长度限制,中文字符算两个
str = str.slice(0,this.maxLength)
let endIndex = 0
if(getBLen(str) > this.maxLength){
let dist = getBLen(str) - str.length
endIndex = this.maxLength - (~~(dist/2)) - (dist%2)
str = str.slice(0,endIndex)
}
// 还是大于最大值,存在临界状态
if(getBLen(str) > this.maxLength){
str = str.slice(0,(endIndex - 1))
}
this.inputValue = str
},
// 判断字符串长度(英文占1个字符,中文汉字占2个字符)
export function getBLen(str) {
let len = 0;
for (let i=0; i<str.length; i++) {
if (str.charCodeAt(i)>127 || str.charCodeAt(i)==94) {
len += 2;
} else {
len ++;
}
}
return len;
}
// 防抖
export function _debounce(fn, delay) {
var delay = delay || 200
var timer
return function() {
var _this = this
var args = arguments
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(function() {
timer = null
fn.apply(_this, args)
}, delay)
}
}
封装指令
import { getBLen } from '@/utils/util'
import { _debounce } from '@/utils/util.js'
// input 字符串长度限制,中文字符算两个
const maxLength = {
bind:function (el, binding) {
let flag = false
let oldStr = ''
el.addEventListener('compositionstart',function () {
flag = true
})
el.addEventListener('compositionend',function () {
flag = false
})
el.addEventListener('input', _debounce(() => {
if(flag) return
let str = el.value
const maxLength = binding.value
str = str.slice(0, maxLength)
let endIndex = 0
if(getBLen(str) > maxLength){
let dist = getBLen(str) - str.length
endIndex = maxLength - (~~(dist/2)) - (dist%2)
str = str.slice(0,endIndex)
}
// 还是大于最大值,存在临界状态
if(getBLen(str) > maxLength){
str = str.slice(0,(endIndex - 1))
}
el.value = str
// 避免反复触发
if(oldStr != el.value){
el.dispatchEvent(new Event('input'))
oldStr = el.value
}
}, 50))
}
}
Vue.directive('maxLength', maxLength)