Vue 源碼閱讀(五)響應式實現

說明

  • Vue 版本:2.5.13

正文

先來看看 Vue 的配置,以組件爲例this

{
    render(h) {
        
    },
    props: {
        props1: Number
    },
    data() {
        return {
            data1: 1,
            data2: 0
        }
    },
    computed: {
        computed1() {
            return this.data1 +  this.props1
        }
    },
    watch: {
        computed1(newValue) {
            setTimeout(()=>{
                console.log(newValue)
            },0)
        }
    }
}

響應式實現過程大概能夠分爲三塊:lua

數據 Data

初始化 data、props、computed 時(初始化 render 時還有一些其餘內置屬性),經過 Object.defineProperty 將屬性定義成 getset,併爲每一個屬性綁定一個 Dep 實例。code

詳見 src/core/instance/state.jsinitDatainitPropsget

組件 Component

能夠把整個 Vue 應用認爲是大大小小的組件堆砌而成。Vue 爲每一個組件都定義了兩塊重要的內容:Watcher 和 Render。it

執行 $mount 時調用 mountComponent、初始化 watch、computed時、調用實例方法 $watch時,都會給實例化一個 Watcher。而 Watcher 初始化時會進行一次求值(執行實例中的 getter 方法),首先會將當前實例設置爲 Dep 當前目標,而後觸發數據的相關屬性的 get 方法。console

詳見 src/core/instance/state.jsinitComputedinitWatchclass

依賴 Dep

Dep 類就是用來關聯數據與組件的 Watcher 的。響應式

// the current target watcher being evaluated.
// this is globally unique because there could be only one
// watcher being evaluated at any time.
Dep.target = null

其實初始化 Watcher 時,經過執行了對應屬性的 get 方法,將Watcher 實例放入數據對應的 Dep 實例的訂閱列表中。而當數據發生變化時,對應屬性執行 set 方法,會通知到對應的 Dep 實例,再通知訂閱列表中的 Watcher。配置

此時,Watcher 將通知組件執行 Render,從新計算出新的 VNode,經過新舊 VNode 的對比,進行視圖更新。方法

相關文章
相關標籤/搜索