vue取通过key取value_彻底理解Vue中的Watcher、Observer、Dep
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                vue取通过key取value_彻底理解Vue中的Watcher、Observer、Dep
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                思考以下代碼
new Vue({el: '#example',data(){return{obj:{a:1}}}, })當我們寫下這行代碼時,vue將我們在data內定義的obj對象進行依賴追蹤.
具體做法為執行new Observer(obj)
//經過上面的代碼,我們的obj對象會變為以下的樣子 {obj:{a:1,__ob__:{ //Observer 實例dep:{Dep 實例subs:[ //存放 Watcher 實例new Watcher(),]}}} }我們來一步步實現看下。 1. 在obj對象上新增__ob__屬性,值為Observe 類的實例,我們編寫一個 def 函數,用來增加屬性
function def(obj, key, val, enumerable) {Object.defineProperty(obj, key, {value: val,enumerable: !!enumerable,writable: true,configurable: true}); }增加啥屬性呢?之前提到了,我們需要增加一個 Observer 實例,實現如下
Observe 實現
class Observer {constructor(targetObject) {def(targetObject, '__ob__', this);//在 targetObject 上 添加 Observer 實例, setter時 通知該實例this.walk(targetObject)this.dep = new Dep()}walk(obj) {Object.keys(obj).forEach(key => {defineReactive(obj, key, obj[key])});}}function observe(data) {if (Object.prototype.toString.call(data) !== '[object Object]') {return}new Observer(data) }function defineReactive(obj, key, val) {observe(val)Object.defineProperty(obj, key, {enumerable: true,configurable: true,get: function reactiveGetter() {console.log('get');const ob = this.__ob__ob.dep.depend();return val},set: function reactiveSetter(newVal) {console.log('set');if (newVal === val) returnval = newValobserve(newVal)const ob = this.__ob__ob.dep.notify();},}) }function def(obj, key, val, enumerable) {Object.defineProperty(obj, key, {value: val,enumerable: !!enumerable,writable: true,configurable: true}); }這里面牽扯到了 Dep,我們也把Dep實現下,
Dep
class Dep {constructor() {this.subs = []}addSub(sub) {this.subs.push(sub)}depend() {this.subs.push(Dep.target)}notify() {for (let i = 0; i < this.subs.length; i++) {this.subs[i].fn()}} }Dep.target = nullObserver 類 主要做了以下事情
看下 dep.depend()做了些啥
this.subs.push(Dep.target)將Dep.target添加到 訂閱數組內(this.subs)
也就是說,只要我們 Dep.target 賦值了,再執行 dep.depend(),那么該值就會被添加到 dep 的 subs 數組內,比如Dep.target =function test(){} dep.depend() // test 函數就算 Dep 的訂閱者了實現自動添加依賴
這個時候該 Watcher出場了
Watcher 實現
const Dep = require('./Dep')class Watcher {constructor(vm, exp, fn) {this.vm = vmthis.exp = expthis.fn = fnDep.target = this//將自己掛載到 Dep.target,調用 Dep.depend時會讀取該變量this.vm[exp]} }module.exports = Watcher根據一個小例子來理解 Watcher
const obj = {a: 1,b: {c: 2} }new Observer(obj) new Watcher(obj, 'a', () => {console.log('Watcher 回調執行') }) obj.a='222'流程如下: 1. 先觀測 obj 對象(new Observer(obj)) 2. 實例化Watcher時,會執行Dep.target = this,然后執行this.vm[exp],也就是取一次值,那么會觸發 getter,將自身(Watcher實例)添加到dep的訂閱者數組內
get: function reactiveGetter() {const ob = this.__ob__ob.dep.depend();return val},最后,改變數據時候,觸發setter
set: function reactiveSetter(newVal) {if (newVal === val) returnval = newValobserve(newVal)const ob = this.__ob__ob.dep.notify();},執行ob.dep.notify()
notify() {for (let i = 0; i < this.subs.length; i++) {this.subs[i].fn()}遍歷 訂閱者(subs)執行回調函數,整個流程結束
Leeesin/learn-vue-source-code?github.com總結
以上是生活随笔為你收集整理的vue取通过key取value_彻底理解Vue中的Watcher、Observer、Dep的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: html富文本编辑器插件_vue中使用v
- 下一篇: 各种水龙头拆卸图解_水龙头上包卫生纸,竟
