入口

  1. // 类似于工厂函数,在满足一定情况后会 new Observer(value),使得 value 具备响应式,同时返回 observer 实例
  2. // 基本类型的值是没有 Observer 的
  3. // asRootData 主要用于 vmCount 计算
  4. export function observe (value: any, asRootData: ?boolean): Observer | void {
  5. // 如果传入的值不是对象或者是 VNode 则直接返回
  6. if (!isObject(value) || value instanceof VNode) {
  7. return
  8. }
  9. let ob: Observer | void
  10. // 如果已经观测过了则不再 new 一个新的
  11. if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
  12. ob = value.__ob__
  13. } else if (
  14. // 全局开关,在特定情况下不会对数据进行观测
  15. shouldObserve &&
  16. // 服务端渲染时,不会观测
  17. !isServerRendering() &&
  18. // 必须得是数据或者对象才对其观测
  19. (Array.isArray(value) || isPlainObject(value)) &&
  20. // 值必须得是可扩展的,Object.freeze/Object.preventExtensions/Object.seal 的值就不会对其的观测
  21. Object.isExtensible(value) &&
  22. // 防止 Vue 实例被观测
  23. !value._isVue
  24. ) {
  25. ob = new Observer(value)
  26. }
  27. //
  28. if (asRootData && ob) {
  29. ob.vmCount++
  30. }
  31. return ob
  32. }

Observer

  1. // 用于监听值
  2. // value,值自身
  3. // dep,观察值的依赖项集合
  4. // vmCount,以当前值为 data option 的实例数量
  5. // value.__ob__,definePrototype 实现的访问代理,指向当前 Observer 实例
  6. // 然后根据不同数据类型进行监听
  7. export class Observer {
  8. value: any;
  9. dep: Dep;
  10. vmCount: number; // number of vms that have this object as root $data
  11. // 构造函数
  12. constructor (value: any) {
  13. this.value = value
  14. // 初始化依赖项
  15. this.dep = new Dep()
  16. this.vmCount = 0
  17. // 为数据自身添加一个访问代理,value.__ob__,将访问到当前 Observer 实例
  18. def(value, '__ob__', this)
  19. // 数组/对象的响应式处理
  20. if (Array.isArray(value)) {
  21. // 数组的响应式处理
  22. if (hasProto) {
  23. protoAugment(value, arrayMethods)
  24. } else {
  25. copyAugment(value, arrayMethods, arrayKeys)
  26. }
  27. this.observeArray(value)
  28. } else {
  29. // 对象的响应式处理,遍历并使其具备响应式
  30. this.walk(value)
  31. }
  32. }
  33. // 遍历并响应式处理
  34. walk (obj: Object) {
  35. const keys = Object.keys(obj)
  36. for (let i = 0; i < keys.length; i++) {
  37. defineReactive(obj, keys[i])
  38. }
  39. }
  40. // 对数组的子集进行深度监听
  41. observeArray (items: Array<any>) {
  42. for (let i = 0, l = items.length; i < l; i++) {
  43. observe(items[i])
  44. }
  45. }
  46. }