在使用表单元素 input 的 v-model 指令时,碰到一个问题:
如上图,修改 input 的内容,以便随时显示;但显示时明显慢一步。
<template>
<div>
<input type="text" v-model="obj.val" @keyup="onUpdate">
<span class="show">{{ obj.x }}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
obj: {
val: ''
}
}
},
methods: {
onUpdate () {
this.obj.x = this.obj.val
}
}
}
</script>
稍微熟悉 vue 就明白,这是因为给 obj 新增了属性 x,而 x 并不是响应式的。
输出 obj 也可以观察到:
val 有 getter/setter,是一个 存储器属性;而新增的 x 只是一个单纯的 数据属性。
根据官方文档,用 set 方法即可解决:
this.$set(this.obj, 'x', this.obj.age)
但如果一定要用等号 = 赋值的话,是不是没办法解决视图渲染延迟的问题?
其实可以将监听事件改为 input 就行: @input="onUpdate"
为什么是 input 而不是其它事件?
再看看文档
因为 v-model 本质上就是在 input 事件触发后同步输入框的值与数据。
再试试 change 事件:
<input v-model.lazy="obj.val" @change="onUpdate">
当然这种方式导致 x 不是响应式属性,但能解决问题,只是不知道会不会产生其它问题。