1. 各自处理的数据关系场景不同
watch擅长处理的场景:一个数据影响多个数据 ,当需要在数据变化响应时,执行异步操作,或高性能消耗的操作,自定义 watcher 的方式就会很有帮助。
- computed擅长处理的场景:一个数据受多个数据影响 ,可以关联多个实时计算的对象,当这些对象中的其中一个改变时都会出发这个属性。具有缓存能力,所以只有当数据再次改变时才会重新渲染,否则就会直接拿取缓存中的数据。
2. 工作流程
- watch
1.初始化组件上配置的watcher属性
2.对watcher属性可能的写法进行规整,得出key和handle
3.通过new Watcher 来创建一个基于key和handle的观察者
4.Watcher 的key为响应式的vm 上的变量,在watcher.get的时候,watcher 订阅了对应key的变化。完成响应依赖。
5.当key的值发生了变化,触发watcher的更新方法,并执行回调函数handle - computed
1.初始化的时候会获取computed里的定义。
2.通过遍历第一步的结果,按照computed新的变量名生成Watcher实例。
3.computed的watcher默认是lazy模式的,所以new Watcher 的时候不会调 用watcher实例的get方法
4.vue 为computed 里的每个key 代理了一个新的get方法createComputedGetter(),当render页面的时候,新的get调用computed watcher实例的默认get方法。
5.computed执行自定义get方法的时候,会判断是否依赖又变动,没有的话,直接取值,否则去执行获取依赖的变量。
6.获取依赖变量的时候,将computed的watcher实例订阅到依赖的变量的Dep里。
7.走完这一步后,再调用计算列的watcher.depend将组件的watcher实例也订阅到计算列依赖的所有变量的dep中。
8.这样,当变量变化后,会通知computed的watcher将dirty设置为true, 以及组件的watcher更新dom。
3. 注意事项
1.watcher 初始化是不执行的,如果想初始化就执行的话可以配置immediate属性
2.一般情况不要直接修改computed的值,会报错,一般通过为computed属性自定义set方法,通过改变依赖变量来改变computed的值
3.computed的属性如果不加入在dom中渲染是不会被加入到响应系统的。所以如果只是数据的变动的监控,不映射到dom上,请使用watcher或者其他方法。
4.watcher和computed 属性定义的函数不能使用箭头函数,否则内部this会指向组件的父环境,比如window,导致调用失败。
https://blog.csdn.net/weixin_41275295/article/details/100999927
4. watch
immediate: true,
//刷新加载 立马触发一次handler
deep: true
// 可以深度检测到对象的属性值的变化
5. computed
- computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
- 如果我们有一个计算属性,那么Vue会记住计算的属性所依赖的值。通过这样做,Vue只有在依赖变化时才可以计算值。否则,将返回以前缓存的值。这也意味着只要依赖还没有发生改变,多次访问计算属性会立即返回之前的计算结果,而不必再次执行函数。