Vue输入框快速打字文字丢失 组件更新导致的响应式问题如何解决
问题根因
你遇到的字符丢失问题核心有两个诱因:
- 输入事件绑定了
keyup而非input:快速输入时,部分字符输入后还没触发keyup事件把值同步给父组件,此时父组件suggestions更新触发子组件重渲染,输入框的value会被重置为父组件还没更新的旧search值,刚输入的字符就被冲掉了。 v-for没有绑定唯一key:Vue更新列表时默认用就地复用策略,父组件数据变更触发列表重绘时,可能连带引发输入框的异常重置。
修复方案
最简修复
直接修改两个点即可解决99%的丢字问题:
- 把输入框的
@keyup替换为@input事件,输入内容变更时立刻同步给父组件,消除值同步延迟 - 给
v-for循环加唯一key,避免不必要的DOM复用导致的异常渲染
修改后的子组件代码如下:
const search = Vue.component('search', { props: [ "suggestions", "settings", "search" ], template: ` <div> <input type="text" placeholder="Search..." :value="search" @input="$emit('update:search', $event.target.value)"> <p v-for="(suggestion, index) in suggestions" :key="`suggest-${index}`">{{ suggestion }}</p> </div> ` })
更稳妥的增强方案
如果还有偶发丢值情况,可以给子组件加内部状态缓存输入值,完全隔离父组件其他属性更新的影响:
const search = Vue.component('search', { props: [ "suggestions", "settings", "search" ], data() { return { localSearch: this.search } }, watch: { // 父组件search主动更新时再同步本地值 search(newVal) { this.localSearch = newVal } }, template: ` <div> <input type="text" placeholder="Search..." v-model="localSearch" @input="$emit('update:search', localSearch)"> <p v-for="(suggestion, index) in suggestions" :key="`suggest-${index}`">{{ suggestion }}</p> </div> ` })
内容的提问来源于stack exchange,提问作者Martyn Ball
相关产品推荐
相关产品推荐

