對資料雙向繫結一直都是半知半解,今天就打算自己寫個簡單的實現。
可能有理解不到位甚至是錯誤的地方,如果有人發現的話可以指正~謝謝
資料的雙向繫結,即檢視和資料之間
// html
// js
var oinput = document.getelementbyid('input')
var ooutput = document.getelementbyid('output')
var data =
以上準備了乙個用於修改資料的input輸入框,用於展示資料的p標籤以及用於儲存相關資料的data物件;當input輸入框的值改變時,值將同步更新於p標籤。
這個比較簡單,,當輸入的內容變化時,就將輸入框內容複製給data物件
// js
oinput.addeventlistener('keyup', function(e) ,false)
vue裡用了object.defineproperty(),結合訂閱/發布模式實現個人的理解如下圖:
1. 將需要取值的元素定義為資料的訂閱者,在上面的例子中就是p標籤。
訂閱者的任務就是更新檢視,即更新p標籤展示的內容。
function watcher(obj, key, cb)
watcher.prototype.update = function()
2. 那麼多訂閱者由誰來統一管理?它們訂閱的資訊由誰來統一發布資訊呢?對於a資料,可能有a1,a2,a3…訂閱者,a1,a2,a3…都需要展示a資料,那麼這些a1,a2,a3…就由發布者a來統一管理;同理對於b資料,就由發布者b來管理b的訂閱者b1,b2,b3。
發布者的任務就是收集訂閱者和通知訂閱者更新檢視
function dep()
dep.prototype.notify = function(newval)
}function definereactive(obj, key, val)
return val
},set(newval) ,})}
現在各路神仙已經到位啦!
1. 現在我們知道p標籤要運用到的是data物件,先給data裡的資料加上set/get來攔截訪問操作;並新增觀察者來更新p檢視。
observe(data)
new watcher(data, 'content', val => )
在watcher裡,有乙個操作this._value = obj[key]
,obj[key]在這裡也就是data.content。
這個操作被get()發現了!get()趕緊通知content的發布者。get:「dep!這裡有人要取我的值,它是乙個target,快來吸納它!」
dep:「我來啦!dep.addsubs(target)
,我已經把它加入了我的訂閱者陣列裡啦!」
2. 現在我們在輸入框輸入資料,觸發了keyup事件,執行了data.content = e.target.value
dep:「我來啦!dep.notify()
,我去訂閱陣列裡看看都有誰,再乙個個通知它們更新檢視去!」
3. 相關的watcher們都聽到了dep的呼喚this.subs[i].update()
,乖乖更新檢視去了。
這裡的watcher是手動新增的,在vue裡,通過編譯模板,識別了v-model以及},自動新增watcher js
window.onload = function()
// observe
function observe(obj)
}function definereactive(obj, key, val)
return val
},set(newval) ,
}) }
// dep
function dep()
dep.prototype.notify = function(newval) )
oinput.addeventlistener('keyup', function(e) ,false)
}
vue 資料雙向繫結實現
之前每件事都差不多,直到現在才發現差很多。現在才發現理清一件事的原委是多麼快樂的一件事,我們共同勉勵。紙上得來終覺淺,絕知此事要躬行 懶得扯淡,直接正題 ps 文章略長。model view編譯器 其基於 訂閱者 發布者模式,簡單的講就是訂閱者訂閱資料,一旦訂閱的資料變更過後,更新繫結的view檢視...
vue實現雙向資料繫結
object.defineproperty 方法會直接在乙個物件上定義乙個新屬性,或者修改乙個物件的現有屬性,並返回這個物件。object.defineproperty 方法有三個引數 引數 功能 作用 obj 要修改或定義key值的物件 key 對應obj物件的裡面某有已有或要修改的屬性 opti...
Vue如何實現資料雙向繫結
說明 index.html lang en head p p v text msg p v text car.color p v html msg p v html car.color p type text v model msg v on click clickfn 點我button div...