Vue2 watch deep 原理

  1. const options = {
  2. template: '<h1></h1>',
  3. data() {
  4. return {
  5. obj: {
  6. name: 'name'
  7. }
  8. };
  9. },
  10. created() {
  11. this.watchValue();
  12. setTimeout(() => {
  13. this.obj.name = 'name1111'
  14. }, 1000)
  15. },
  16. methods: {
  17. watchValue() {
  18. this.$watch('obj', (newVal, oldVal) => {
  19. console.log('newVal:', newVal, 'oldVal:', oldVal);
  20. },{
  21. deep: false
  22. })
  23. // this.$watch(表达式 | 函数 ,回调, 配置项)
  24. //
  25. // 1. 假如obj 是一个对象 watch 这个对象 那么obj.a = 122 会不会触发回调
  26. // A: 只有加deep = true 才会触发回调
  27. }
  28. }
  29. };
  1. const options = {
  2. template: '<h1></h1>',
  3. data() {
  4. return {
  5. arr: []
  6. };
  7. },
  8. created() {
  9. this.watchValue();
  10. setTimeout(() => {
  11. this.arr.push(122)
  12. }, 5000)
  13. },
  14. methods: {
  15. watchValue() {
  16. this.$watch('arr', (newVal, oldVal) => {
  17. console.log('newVal:', newVal, 'oldVal:', oldVal);
  18. },{
  19. deep: false
  20. })
  21. // this.$watch(表达式 | 函数 ,回调, 配置项)
  22. //
  23. // 1. 假如arr 是一个数组 对其执行push 操作会不会有回调
  24. // A: 会触发回调
  25. }
  26. }
  27. };

deep 做的事情:
image.png
最终会触发travers函数 对监听的对象进行遍历 并读取每一个key值 触发 getter进行依赖收集

Vue3 watch deep 原理

  1. const { createApp } = Vue;
  2. const Counter = {
  3. data() {
  4. return {
  5. counter: 0,
  6. arr: []
  7. }
  8. },
  9. created() {
  10. this.$watch('arr', (newVal, oldVal) => {
  11. console.log('newVal:', newVal, 'oldVal:', oldVal);
  12. },{
  13. deep: false
  14. });
  15. setTimeout(() => {
  16. this.arr.push(122)
  17. }, 1000);
  18. }
  19. }
  20. createApp(Counter).mount('#counter')
  21. // 这里watch 不会生效 只有deep 为true 才会 生效
  22. // why?
  23. // Vue3 官方文档解释: 当侦听的值是一个对象或者数组时,对其属性或元素的任何更改都不会触发侦听器,因为它们引用相同的对象/数组:
  24. // 为了发现对象内部值的变化,可以在选项参数中指定 deep: true。这个选项同样适用于监听数组变更。