美文网首页vue
谨慎使用vue.watch

谨慎使用vue.watch

作者: 浩神 | 来源:发表于2018-06-18 16:09 被阅读3584次

如果不是对Vue的响应式原理了如指掌,请谨慎使用watch
本文不讨论watch一个基本类型的数据,因为这种情形几乎不会出现意料之外的表现。
试着看一下下面的代码:

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
  new Vue({
    data() {
      return {
        city: {id: 1, name: '北京'}
      }
    },
    watch: {
      city() {
        console.log('city changed')
      }
    },
    created() {
      this.city = {id: 1, name: '北京'}
    }
  })
</script>
</body>
</html>

会触发watch吗?
会的,因为在created方法里面重新给city赋值了一个对象,city前后的指向不同了
以上这点代码出自一个有三年工作经验的前端程序员。他期望city发生变化之后,重新请求跟city相关的数据,他并没有意识到重新赋值给this.city一个相同的对象也会触发更新。所以在页面加载的时候就连发了两个city相关数据的请求。

这就是我写这篇文章的原因,我们考虑更多的情景。

下面这种情况会触发watch吗?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
  const city = {id: 1, name: '北京'}
  new Vue({
    data() {
      return {
        city
      }
    },
    watch: {
      city() {
        console.log('city changed')
      }
    },
    created() {
      this.city.name = 'Beijing'
    }
  })
</script>

</body>
</html>

不会触发, 因为created方法执行之后, city的指向没有变
如果我们期望捕获这种更新,应该这样写代码:

 watch: {
      city: {
        handler: () => console.log('city changed'),
        deep: true
      }
    }

将选项deep设为true能让vue捕获对象内部的变化。

下面讨论一下watch一个数组:

  new Vue({
    el: '#body',
    data() {
      return {
        cities: ['beijing', 'tianjin']
      }
    },
    watch: {
      cities() {
        console.log('cities changed')
      }
    }
  })

那下面哪些操作会触发cities的watch回调呢?

this.cities = ['beijing', 'tianjin']
this.cities.push('xiamen')
this.cities = this.cities.slice(0, 1)
this.cities[0] = 'dali'
this.cities.splice(0, 1)
this.cities.length = 0

答案是只有最后两行不会触发。

总结

  1. 如果watch的是一个对象,reference equal的变化不会触发watch回调,这里包括:
  • 属性增减(delete 或直接新增属性)
  • 修改某一个属性的值(需要添加deep: true的选项)
  1. 如果watch的对象赋值给一个内部所有属性和属性的值相等的新对象,也会触发更新。
  2. Vue内部已经重写了数组的一些方法,如: splice, shift, push pop等,但下面的情况不能捕获更新:
  • 直接用index去更新数组,如 cities[1] = 'sss'
  • 直接修改cities的长度 如cities.length = 0

相关文章

  • 谨慎使用vue.watch

    如果不是对Vue的响应式原理了如指掌,请谨慎使用watch本文不讨论watch一个基本类型的数据,因为这种情形几乎...

  • 谨慎使用STL

    谨慎使用STL 最近解决了一个因为大量使用STL造成的严重内存泄漏问题,再次记录下。 上周上线了基于用户tag的推...

  • Android内存泄漏:谨慎使用getSystemService

    Android内存泄漏:谨慎使用getSystemService

  • 对于drawRect使用,谨慎使用!

    1.drawRect简介 drawRect方法在UIView的使用上起着十分关键的作用。不知道大家注意过没有,每一...

  • 谨慎拥有,珍惜使用

    一个月前,我给自己制定了一个“三十天挑战计划”——每天给自己的穿搭拍一张照片。 三十天过去了,收获的不仅是三十张照...

  • 使用map要谨慎

    scala非RDD的数据结构使用map形成的键值对,如果存在相同键的键值对,将会覆盖,最终只保留一个。所以这种情况...

  • 谨慎使用getter/setter

    在工作中,已经形成了一个习惯,常常在新加一个类时,在写好一些private变量之后,会顺手自动生成相应的gette...

  • 谨慎使用Aⅰ换脸

    前段时间,我听说有一种软件,里面有各种的视频和照片,还可以换脸,所谓的画面就是换成你的脸。 我一看这么神奇...

  • Android性能优化

    1.内存优化 static谨慎使用 善用softreference、weakreference、lrucache ...

  • Android 保存图片到相册

    @deprecated insertImage 谨慎使用 更新方法 远程图片转bitmap

网友评论

    本文标题:谨慎使用vue.watch

    本文链接:https://www.haomeiwen.com/subject/dajbeftx.html