Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

简述 Vue 响应式原理 #35

Open
janeLLLL opened this issue Nov 23, 2020 · 0 comments
Open

简述 Vue 响应式原理 #35

janeLLLL opened this issue Nov 23, 2020 · 0 comments

Comments

@janeLLLL
Copy link
Owner

  1. 从Vue的实例init()方式开始

    • 首先调用**initState()初始化Vue实例的状态**;
    • 然后在initState()方法中调用了initData(),initData()把data注入到Vue实例上,并且调用observe(data)将data对象转化成响应式对象
  2. 响应式的入口是observe(value)

    • 首先判断传入参数value是否是对象,如果不是对象直接返回;
    • 再判断value对象是否有__ob__这个属性,如果有,直接返回,如果没有,创建observe对象,并返回observe对象
  3. 创建observer对象时:

    • 给当前的value对象定义不可枚举的__ob__属性,记录当前的observer对象;
    • 然后再进行数组的响应式处理和对象的响应式处理。(数组的响应式处理就是拦截数组的几个特殊的方法:pushpopshift等)
    • 然后找到数组对象中的__ob__对象中的dep,调用dep的notify()方法,再遍历数组中每一个成员,对每个成员调用observe(),如果这个成员是对象的话,也会转换成响应式对象。
    • 调用walk()方法,进行对象的响应式处理。walk遍历对象的每一个属性,对每个属性调用defineReactive方法
  4. defineReactive方法为每一个属性创建对应的dep对象,让dep去收集依赖,如果当前属性的值是对象,会调用observe

    • getter:收集依赖。为每一个属性收集依赖,如果这个属性的值是对象,要为子对象收集依赖,最后返回属性的值
    • setter:先保存新值,如果新值是对象,也要调用observe,把新设置的对象也转换成响应式的对象,然后派发更新(发送通知),调用dep.notify()
  5. 收集依赖:

    • 在watcher对象的get方法中调用pushTarget,记录Dep,target属性
    • 访问data中成员的时候收集依赖,defineReactive的getter中收集依赖
    • 把属性对应的watcher对象添加到dep的subs数组中
    • childOb收集依赖,目的是子对象添加和删除成员时发送通知
  6. Watcher:

    • 在数据发生变化时,会调用dep.notify()发送通知。

    • dep.notify()会调用watcher对象的update()方法

    • update()中调用的queueWatcher()会去判断Watcher是否被处理,如果这个Watcher对象没有的话添加到queue队列中,并调用flushScheduleQueue()

    • flushScheduleQueue()触发beforeUpdate钩子函数调用Watcher.run()

    • run() → get() → getter() → updateComponent

    • 清空上一次的依赖

    • 触发active钩子函数

    • 触发updated钩子函数

响应式处理过程

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant