美文网首页
vue响应式对象

vue响应式对象

作者: 大猪蹄子_0f6b | 来源:发表于2020-03-12 15:59 被阅读0次

在Vue初始化阶段的_init方法执行的时候,会执行initState(vm),法主要是对 props 、 methods 、 data 、 computed 和 wathcer 等属性做了初始化操作。

  • initProps主要过程,就是遍历定义的 props 配置。遍历的过程主要做两件事情:⼀个是调⽤ defineReactive ⽅法把每个 prop 对应的值变成响应式,可以通过 vm._props.xxx 访问到定义 props 中对应的属性;另⼀个是通过 proxy把 vm._props.xxx 的访问代理到 vm.xxx 上

  • initData是对定义 data 函数返回对象的遍历,通过 proxy把每⼀个值 vm._data.xxx 都代理到 vm.xxx 上;另⼀个是调⽤ observe ⽅法观测整个 data的变化,把 data 也变成响应式,可以通过 vm._data.xxx 访问到定义 data 返回函数中对应的属性

    • proxy是通过Object.defineProperty 把 target[sourceKey][key] 的读写
      变成了对 target[key] 的读写

    • observe 的功能就是⽤来监测数据的变化,是给⾮ VNode 的对象类型数据添加⼀个 Observer

  • Observer是⼀个类,它的作⽤是给对象的属性添加 getter 和 setter,⽤于依赖收集和派发更新:

    • 构造函数⾸先实例化 Dep 对象,接着通过执⾏ def 函数把⾃⾝实例添加到数据对象 value 的 __ob__ 属性上,然后在data上对象类型的数据都有多出一个__ob__的属性。(def是Object.defineProperty的封装)
    • 接下来会对 value 做判断,对于数组会调⽤ observeArray ⽅法,否则对纯对象调⽤ walk ⽅法。而 observeArray 是遍历数组再次调⽤ observe ⽅法,walk ⽅法是遍历对象的 key 调⽤ defineReactive ⽅法

defineReactive

功能就是定义⼀个响应式对象,给对象动态添加 getter 和 setter。
最开始初始化 Dep 对象的实例,接着拿到 obj 的属性描述符,然后对⼦对象递归调⽤ observe ⽅法,这样就保证了⽆论 obj 的结构多复杂,它的所有⼦属性也能变成响应式的对象,这样我们访问或修改 obj 中⼀个嵌套较深的属性,也能触发 getter 和 setter。

getter 做的事情是依赖收集,setter 做的事情是派发更新

export function defineReactive (
  obj: Object,
  key: string,
  val: any,
  customSetter?: ?Function,
  shallow?: boolean
) {
  const dep = new Dep()

  const property = Object.getOwnPropertyDescriptor(obj, key)
  if (property && property.configurable === false) {
    return
  }

  // cater for pre-defined getter/setters
  const getter = property && property.get
  const setter = property && property.set
  if ((!getter || setter) && arguments.length === 2) {
    val = obj[key]
  }

  let childOb = !shallow && observe(val)
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      const value = getter ? getter.call(obj) : val
      if (Dep.target) {
        dep.depend()
        if (childOb) {
          childOb.dep.depend()
          if (Array.isArray(value)) {
            dependArray(value)
          }
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      const value = getter ? getter.call(obj) : val
      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      /* eslint-enable no-self-compare */
      if (process.env.NODE_ENV !== 'production' && customSetter) {
        customSetter()
      }
      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
      childOb = !shallow && observe(newVal)
      dep.notify()
    }
  })
}

相关文章

  • 2021-07-23 vue2与vue3的响应式原理

    vue2的响应式原理 无法响应对象的新增与删除 vue3的响应式原理

  • vue 3.0 笔记

    vue 3.0 笔记 1、Vue 3.0 如何做到性能提升 响应式系统升级使用 Proxy 对象重写响应式系统:v...

  • 响应式原理(二)

    依赖收集 通过上一节的分析我们了解 Vue 会把普通对象变成响应式对象,响应式对象 getter 相关的逻辑就是做...

  • vue2.0源码解析 - 依赖收集

    依赖收集通过上一节的分析我们了解 Vue 会把普通对象变成响应式对象,响应式对象 getter 相关的逻辑就是做依...

  • Vue源码分析—响应式原理(二)

    依赖收集 Vue会把普通对象变成响应式对象,响应式对象getter相关的逻辑就是做依赖收集,我们来详细分析这个过程...

  • vue响应式对象

    在Vue初始化阶段的_init方法执行的时候,会执行initState(vm),法主要是对 props 、 met...

  • Vue源码阅读、七

    响应式原理 Vue实现响应式的核心是利用了Object.defindProperty为对象的属性添加getter和...

  • 双向绑定

    数据响应式原理 vue实现数据响应式的原理就是利用了Object.defineProperty(),重新定义了对象...

  • 一步一步实现Vue的响应式-数组观测

    本篇是以一步一步实现Vue的响应式-对象观测为基础,实现Vue中对数组的观测。 数组响应式区别于对象的点 如果是直...

  • Vue实例构造-1

    data Vue 实例的数据对象,Vue会将这些数据对象的属性转换为getter/setter,从而实现数据响应式...

网友评论

      本文标题:vue响应式对象

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