Vue.js 最核心的功能有兩個,一是響應式的資料繫結系統,二是元件系統。本文僅探究雙向繫結是怎樣實現的。先講涉及的知識點,再用簡化得不能再簡化的程式碼實現一個簡單的 hello world 示例。
參考文章:https://segmentfault.com/a/1190000006599500
一、訪問器屬性
訪問器屬性是物件中的一種特殊屬性,它不能直接在物件中設定,而必須透過 defineProperty() 方法單獨定義。
var obj = { };
// 為obj定義一個名為 hello 的訪問器屬性
Object.defineProperty(obj, "hello", {
get: function () {return sth},
set: function (val) {/* do sth */}
})
obj.hello // 可以像普通屬性一樣讀取訪問器屬性
訪問器屬性的"值"比較特殊,讀取或設定訪問器屬性的值,實際上是呼叫其內部特性:get和set函式。
obj.hello // 讀取屬性,就是呼叫get函式並返回get函式的返回值
obj.hello = "abc" // 為屬性賦值,就是呼叫set函式,賦值其實是傳參
get 和 set 方法內部的 this 都指向 obj,這意味著 get 和 set 函式可以操作物件內部的值。另外,訪問器屬性的會"覆蓋"同名的普通屬性,因為訪問器屬性會被優先訪問,與其同名的普通屬性則會被忽略。
二、極簡雙向繫結的實現
此例實現的效果是:隨文字框輸入文字的變化,span 中會同步顯示相同的文字內容;在js或控制檯顯式的修改 obj.hello 的值,檢視會相應更新。這樣就實現了 model => view 以及 view => model 的雙向繫結。
以上就是 Vue 實現雙向繫結的基本原理。
三、分解任務
上述示例僅僅是為了說明原理。我們最終要實現的是:
首先將該任務分成幾個子任務:
1、輸入框以及文字節點與 data 中的資料繫結
2、輸入框內容變化時,data 中的資料同步變化。即 view => model 的變化。
3、data 中的資料變化時,文字節點的內容同步變化。即 model => view 的變化。
要實現任務一,需要對 DOM 進行編譯,這裡有一個知識點:DocumentFragment。
四、DocumentFragment
DocumentFragment(文件片段)可以看作節點容器,它可以包含多個子節點,當我們將它插入到 DOM 中時,只有它的子節點會插入目標節點,所以把它看作一組節點的容器。使用 DocumentFragment 處理節點,速度和效能遠遠優於直接操作 DOM。Vue 進行編譯時,就是將掛載目標的所有子節點劫持(真的是劫持,透過 append 方法,DOM 中的節點會被自動刪除)到 DocumentFragment 中,經過一番處理後,再將 DocumentFragment 整體返回插入掛載目標。
Vue.js 最核心的功能有兩個,一是響應式的資料繫結系統,二是元件系統。本文僅探究雙向繫結是怎樣實現的。先講涉及的知識點,再用簡化得不能再簡化的程式碼實現一個簡單的 hello world 示例。
參考文章:https://segmentfault.com/a/1190000006599500
一、訪問器屬性
訪問器屬性是物件中的一種特殊屬性,它不能直接在物件中設定,而必須透過 defineProperty() 方法單獨定義。
var obj = { };
// 為obj定義一個名為 hello 的訪問器屬性
Object.defineProperty(obj, "hello", {
get: function () {return sth},
set: function (val) {/* do sth */}
})
obj.hello // 可以像普通屬性一樣讀取訪問器屬性
訪問器屬性的"值"比較特殊,讀取或設定訪問器屬性的值,實際上是呼叫其內部特性:get和set函式。
obj.hello // 讀取屬性,就是呼叫get函式並返回get函式的返回值
obj.hello = "abc" // 為屬性賦值,就是呼叫set函式,賦值其實是傳參
get 和 set 方法內部的 this 都指向 obj,這意味著 get 和 set 函式可以操作物件內部的值。另外,訪問器屬性的會"覆蓋"同名的普通屬性,因為訪問器屬性會被優先訪問,與其同名的普通屬性則會被忽略。
二、極簡雙向繫結的實現
此例實現的效果是:隨文字框輸入文字的變化,span 中會同步顯示相同的文字內容;在js或控制檯顯式的修改 obj.hello 的值,檢視會相應更新。這樣就實現了 model => view 以及 view => model 的雙向繫結。
以上就是 Vue 實現雙向繫結的基本原理。
三、分解任務
上述示例僅僅是為了說明原理。我們最終要實現的是:
首先將該任務分成幾個子任務:
1、輸入框以及文字節點與 data 中的資料繫結
2、輸入框內容變化時,data 中的資料同步變化。即 view => model 的變化。
3、data 中的資料變化時,文字節點的內容同步變化。即 model => view 的變化。
要實現任務一,需要對 DOM 進行編譯,這裡有一個知識點:DocumentFragment。
四、DocumentFragment
DocumentFragment(文件片段)可以看作節點容器,它可以包含多個子節點,當我們將它插入到 DOM 中時,只有它的子節點會插入目標節點,所以把它看作一組節點的容器。使用 DocumentFragment 處理節點,速度和效能遠遠優於直接操作 DOM。Vue 進行編譯時,就是將掛載目標的所有子節點劫持(真的是劫持,透過 append 方法,DOM 中的節點會被自動刪除)到 DocumentFragment 中,經過一番處理後,再將 DocumentFragment 整體返回插入掛載目標。