最近写搜索功能时,为了代码简洁(偷懒),把搜索结果字段写在一个对象中,然后使用watch 深度监听,烦是对象发生改变了就调用后端接口后端最新的搜索结果。本身是没有问题的,但是之后发现凡是 input 框发生改变时,就会调用后端接口。如果用户打字速度过快的话,有可能出现用户之前搜索到的结果覆盖最新的结果(假设用户打了五个字,并且该用户打字速度挺快的,当用户打完5个字之后,并且拿到了返回的结果,但是请求后端是异步的,可能用户输入4个字,3个字返回的数据要在全部输入完之后,这样就会导致旧的结果覆盖新的结果)

watch深度监听使用方法

watch:{} 对象,可监听数据,数据发生变化, 处理函数。

watch监听对象,同时用**deep: true**深度监听,此时只有对象中的某个值发生改变就会触发。

watch: { obj: { // 数据变化时执行的逻辑代码 handler(newName, oldName) { console.log('obj.a changed'); }, // 开启深度监听 deep: true }}





问题:监听到的新旧值相同。

我本想的想法是,如果监听到的新值和旧值的input框绑定值不同,说明此次数据发生改变是用户正在操作的输入框,则给其单独做处理,但是我发现,watch 深度监听的新旧值是完全一样的。



最后在官方文档中找到了原因:注意:在变异(不是替换)对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变异之前值的副本。

解决方法

新增一个计算属性,返回JSON格式,然后使用watch 监听 计算属性重新计算的结果。因为转为json格式之后,那么它的数据类型就会转为原始数据类型。



结果:



这样的话,就可以完美解决watch监听到的新旧值一样的问题,只需要使用JSON.parse()再转换回去即可。