调试$set方法

Vue

# 模板html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Vue.js 01 component example</title>
  </head>
  <body>
    <div id="app">
      {{ obj.title }}
      <hr>
      {{ obj.name }}
      <hr>
      {{ arr }}
    </div>

    <script src="../../dist/vue.js"></script>
    <script>
      const vm = new Vue({
        el: '#app',
        data: {
          obj: {
            title: 'Hello Vue!'
          },
          arr: [1, 2, 3]
        }
      })
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 设置断点

在core/observer/index.js的set方法里面设置断点

image

# 调试数组

控制台输入vm.$set(vm.arr,1,100)进入调试,判断是否是数组,且index在合法范围内,之后进行处理

image

进入splice方法,按F11

这里面显示定义了原生的splice方法,利用apply方法改变this,让其指向数组对象,然后传递参数

image

之后会获取ob,判断method的类型,是splice就将其第三个参数存储到inserted里面

image

之后会调用observeArray,这个方法中会遍历传入的数组,并且把他里面每一个元素取出来调用observe函数,如果这个元素是对象的话会转化成响应式数据.这里不做详细处理

接下来就是发送通知

image

按F11进入是调用每个元素的update方法

image

之后不再进行演示,执行完成之后视图进行了更新

image

数组的更新就调试完毕了

# 调试对象

在控制台中输入vm.$set(vm.obj, 'name', 'xm')之后进入调试

  • 因为这个时候不是数组,所以跳过数组的处理

  • 下一个判断name是否在obj中,此时也是没有的,所以下一步

  • 获取target的__ob__,判断其是不是Vue实例或者是$data,不是继续下一步

  • 下一步判断ob是否存在,当前target对象是响应式的,ob存在所以继续下一步

到达defineReactive这一行

image

这里通过defineReactive给target添加属性name

image

下一步就是发送通知,到这里set函数执行就调试完毕.

更新时间: 2022-01-11 10:46