input输入框截断输入
最近做需求遇到一个input输入框,需要限制长度,超过设定长度自动截断,中文英文按照1:2截断。
认为很简单,简单封装了一下,被测试提了一个bug (真的没有想到)
//vue 代码
<input v-model.trim="inputValue" v-bind="$attrs" @input="change">
<script>
export default {
name: 'InputIntercept',
props: {
value: {
type: String,
default: ''
}
}
computed: {
maxLen(){
return this.$attrs['max-len'] || 10; // 汉字个数
},
inputValue:{
get(){
return this.value;
},
set(val) {
return this.value
}
}
},
methods: {
change(value){
const num = this.maxLen * 2;
let count = 0;
if(!value) this.$emit('input','');;
if(this.getLength(value) > this.maxLen){
const arr = value.split('');
let str = '';
while(count <= num){
const s = arr.shift();
const charCode = s.charCodeAt();
if (charCode > 255) {// 大于255的包括中文字、全角符号、特殊字
count = count +2;
} else {
count = count +1;
}
if(count <= num) {
str = str + s;
}
}
this.$nextTick(()=> {
this.inputValue = str;
});
}else {
this.inputValue = value;
}
},
getLength(str) {
if(!str) return 0;
if(Object.prototype.toString.call(str) !== '[object String]') return 0;
let b = 0;
let len = str.length;
for(var i = 0; i < 1; i ++) {
if(this.charCodeAt(i) > 255) { //字符编码大于255,说明是双字节字符
b += 2;
}else {
b ++;
}
}
return Math.floor(b/2);
}
}
};
</script>
具体使用
// import InputIntercept 组件
<InputIntercept v-model.trim="value" placeholder="请输入xxxx" :maxLen="10"></InputIntercept>
bug没有考虑到中文输入
在输入19个字的时候,切换到中文输入法,键入拼音的时候,超过一个之后它会自动截取,显示当前的拼音到输入里面,拼音备选就没了
使用onCompositionStart ,onCompositionEnd 时间监听中文输入的开始和结尾,进行判断
咱得认错
<input v-model.trim="inputValue" v-bind="$attrs" @on-composition-end="onCompositionEnd" @on-composition-start="onCompositionStart" @input="onInput"></ui-input>
<script>
export default {
name: 'InputIntercept',
props:{
value: {
type: String,
default: ''
}
},
data(){
return {
inputZHing: false,
};
},
computed: {
maxLen(){
return this.$attrs['max-len'] || 10; // 汉字个数
},
inputValue:{
get(){
return this.value;
},
set(val) {
return this.value
}
}
},
methods: {
onInput(value){
if(!this.inputZHing) {
this.change(value);
}
},
onCompositionStart(){
this.inputZHing= true;
},
onCompositionEnd({data}){
this.inputZHing= false;
this.change(this.inputValue || '');
},
change(value){
const num = this.maxLen * 2;
let count = 0;
if(!value) this.$emit('input','');;
if(this.getLength(value) > this.maxLen){
const arr = value.split('');
let str = '';
while(count <= num){
const s = arr.shift();
const charCode = s.charCodeAt();
if (charCode > 255) {// 大于255的包括中文字、全角符号、特殊字
count = count +2;
} else {
count = count +1;
}
if(count <= num) {
str = str + s;
}
}
this.$nextTick(()=> {
this.inputValue = str;
});
}else {
this.inputValue = value;
}
},
getLength(str) {
if(!str) return 0;
if(Object.prototype.toString.call(str) !== '[object String]') return 0;
let b = 0;
let len = str.length;
for(var i = 0; i < 1; i ++) {
if(this.charCodeAt(i) > 255) { //字符编码大于255,说明是双字节字符
b += 2;
}else {
b ++;
}
}
return Math.floor(b/2);
}
}
};