VUE - MVVM - part1 - defineProperty

VUE 中關於如何實如今網上能夠搜出很多,在看了部分源碼後,梳理一下內容。vue

首先,咱們須要瞭解一下 js 中的一個 API :
Object.defineProperty(obj, prop, descriptor)git

通常狀況下咱們爲一個對象添加一個屬性通常都會這麼寫github

let object = {}
object.test = 'test'

Object.defineProperty 也能作到一樣的效果數組

let object = {}, test = 'test'
Object.defineProperty(object, 'test', {
    configurable: true,             // 描述該屬性的描述符可否被改變,默認值爲 false
    enumerable: true,               // 可否被遍歷,好比 for in,默認值爲 false
    get: function(){                // 取值的時候調用,object.test,默認值爲 false
        console.log('enter get')
        return test
    },
    set: function(newValue){        // 設置值的時候使用
        console.log('enter set')
        test = newValue
    }
})

這樣寫雖然代碼量多了很多,可是卻擁有了控制屬性取值和設置值的權利,讓咱們來測試一下。函數

object.test
// enter get
// test
object.test = 'test2'
// enter set
// test2

接着咱們把 defindProperty 這個函數封裝同時改造一下,方便咱們調用測試

let callback = {
    target: null
}
let defineReactive = function(object, key, value){
    let array = []
    Object.defineProperty(object, key, {
        configurable: true,
        enumerable: true,
        get: function(){
            if(callback.target){
                array.push(callback.target)
            }
            return value
        },
        set: function(newValue){
            if(newValue != value){
                array.forEach((fun)=>fun(newValue, value))
            }
            value = newValue
        }
    })
}

能夠從代碼中看出來,我在函數內部聲明瞭一個數組用於存放 callback 中的 target,當對 object 進行 get 操做(取值操做)的時候,就會往 array 中存放函數,進行 set 操做(設置值)的時候執行 array 中的函數。看看效果如何優化

let object = {}
defineReactive(object, 'test', 'test')
callback.target = function(newValue, oldValue){
    console.log('我被添加進去了,新的值是:' + newValue)
}
object.test
// test

callback.target = null
object.test = 'test2'
// 我被添加進去了,新的值是:test2

callback.target = function(newValue, oldValue){
    console.log('添加第二個函數,新的值是:' + newValue)
}
object.test
// test

callback.target = null
object.test = 'test3'
// 我被添加進去了,新的值是:test3
// 添加第二個函數,新的值是:test3

這樣咱們就達成了在 object.test 的值發生改變時,運行一個函數隊列(雖然這個隊列挺簡陋的)的目的。code

換個說法,當咱們取值的時候,函數自動幫咱們添加了針對當前值的依賴,當這個值發生變化的時候,處理了這些依賴,好比說 DOM 節點的變化。對象

這個也是 VUE 中實現 MVVM 的最核心的代碼,固然在 VUE 中,這個依賴收集的過程遠比如今的代碼要複雜,這裏僅僅實現了依賴的收集和觸發,對於依賴的管理這裏的代碼還作不到。
只是簡單的瞭解一下 VUE 中依賴收集的過程,關於如何去完美的收集依賴,還須要瞭解幾個感念,以後再說。blog

點擊查看相關代碼

系列文章地址

  1. VUE - MVVM - part1 - defineProperty
  2. VUE - MVVM - part2 - Dep
  3. VUE - MVVM - part3 - Watcher
  4. VUE - MVVM - part4 - 優化Watcher
  5. VUE - MVVM - part5 - Observe
  6. VUE - MVVM - part6 - Array
  7. VUE - MVVM - part7 - Event
  8. VUE - MVVM - part8 - 優化Event
  9. VUE - MVVM - part9 - Vue
  10. VUE - MVVM - part10 - Computed
  11. VUE - MVVM - part11 - Extend
  12. VUE - MVVM - part12 - props
  13. VUE - MVVM - part13 - inject & 總結
相關文章
相關標籤/搜索