❗️ Note: it has been
days since this article was written, please be aware of its timeliness
Origin of This Article
After studying Vue’s reactivity principle, I wanted to document it and implement Vue’s reactivity system from scratch, hence this article.
Overview
Vue The initialization of reactive data occurs in initState’s initData, where the observe function observes the data properties of the vm object and then sets the getter and setter properties.
Thus, at least three functions are required: an observer for setting properties getter and setter, a trigger for getter and setter’s 监听者, and a 收集框 to store property dependencies. I named them observe, watcher, and dep, respectively.
Process
First, in observe, the properties in data are recursively augmented with getter and setter. Later, when accessing one of the properties in watcher, the watcher instance triggers the getter interceptor. The interceptor for that property then adds the watcher instance to the property’s closure-based dependency collector dep, while also placing this closure-based dependency collector into the watcher.
Subsequently, when modifying the aforementioned property, the setter interceptor defined in observe is triggered. At this point, the watcher in dep starts working, executing the callback of that watcher.
Notes
How to prevent duplicate dependency collection when triggering getter?
When watcher triggers getter, it adds the current property’s dependency collector to watcher’s Set array for comparison. If it’s a duplicate, it won’t be added again:
1 2 3 4 5 6 7
addDep (dep) { var id = dep.id; if (!this.depIds.has(id)) { // 一次求值时候的去重 this.deps.push(dep); dep.addSubs(this); // 再将 watcher 放到字段的 Dep 的实例 subs 中, 以供值变化的时候 执行 notity, 把 subs 中的 watcher 拉出来挨个执行一遍 } }
How to execute callbacks when triggering setter?
When setter is triggered, it retrieves the array containing watcher for that property and executes each one sequentially:
I often wish that when facing some key decisions in life, someone could tell me the best course of action so that I would not waste my precious time. Putting myself in others' shoes, I therefore write blogs often, hoping to record in this tiny corner of the vast Internet the once-in-a-lifetime experiences that matter to me, and to help those who seek help.