e.target和v-model的冲突
问题发现
页面是实现input输入框检测用户输入的字符数(中文为2个字,英文为1个字)
// 页面部分(限制用户输入10个字符)
<template slot="remark" slot-scope="action, record">
<a-input size="small" type="text" v-model="record.remark" :disabled="pageType=='details'" @keyup="limitLength($event,10)" ></a-input>
</template>
//js部分
limitLength(e,maxLength) {
const target=e.target
const value = target.value
const split = value.split('');
const map = split.map((s, i) => {
return (value.charCodeAt(i) >= 0 && value.charCodeAt(i) <= 128) ? 1 : 2;
});
let n = 0;
const charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
const count = accumulator + currentValue;
if (count === maxLength-1 || count === maxLength) {
n = index;
}
if (count > maxLength) {
e.target.value = split.slice(0, n+1).join('')
// 控制台输出更改的字符长度
console.log(e.target.value.length)
}
return count
});
},
可以看到,当输入英文字母(1个英文字母为1字符),会强制截取成10位,随后提交数据。
提交数据后,我查看数据,发现变为了11位。
于是我查看是后台返回给我的数据有问题,还是我提交给后台的数据有问题。
发现我这边提交的数据就已经是11位的了,后台返回的数据自然而然也是11位。
问题解决
// html部分
// 将kepup触发的事件中传递的参数,改为v-model绑定的参数
<template slot="remark" slot-scope="action, record">
<a-input size="small" type="text" v-model="record.remark" :disabled="pageType=='details'" @keyup="limitLength(record,10)" ></a-input>
</template>
// js部分
limitLength(data,maxLength) {
const value = data.remark
const split = value.split('');
const map = split.map((s, i) => {
return (value.charCodeAt(i) >= 0 && value.charCodeAt(i) <= 128) ? 1 : 2;
});
let n = 0;
const charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
const count = accumulator + currentValue;
if (count === maxLength-1 || count === maxLength) {
n = index;
}
if (count > maxLength) {
data.remark = split.slice(0, n+1).join('')
}
return count
});
},
从解决方案倒退,可以理解我通过input输入框修改v-model双向绑定的值,在v-model接受了值之后,映射到本地仓库,此时接受的值应该是还未通过限制的值,即11位数据。而当用户输入完毕,页面上能显示10位数据,不过通过e.target.value修改的10位数据并没有被v-model劫持,v-model中的数据仍然是11位数据。这让我想到了,在vue中,通过数组下标来修改数组,即使能修改数据,vue无法检测到数据的改变,只能通过数组对象身上的方法类似push(),pop()才能及时渲染。在这个问题中,即使我通过e.target.value修改了input框中的值,vue也无法检测到数据的改变,只有直接更改vue中data的数值时,才能检测到更改并及时渲染。