本篇內(nèi)容主要講解“vue中observer數(shù)據(jù)雙向綁定原理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“vue中observer數(shù)據(jù)雙向綁定原理”吧!
創(chuàng)新互聯(lián)專注于丹陽網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供丹陽營銷型網(wǎng)站建設(shè),丹陽網(wǎng)站制作、丹陽網(wǎng)頁設(shè)計(jì)、丹陽網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造丹陽網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供丹陽網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
vue
數(shù)據(jù)雙向綁定原理和簡單的實(shí)現(xiàn)
1)vue數(shù)據(jù)雙向綁定原理-observer
2)vue數(shù)據(jù)雙向綁定原理-wather
3)vue數(shù)據(jù)雙向綁定原理-解析器 Complie
vue
數(shù)據(jù)雙向綁定原理, 和簡單的實(shí)現(xiàn)
去他喵的底層原理,框架內(nèi)核,老夫?qū)懘a只用Jquery
。
個人覺得,不論是否是長期與之交集,還是應(yīng)該看下核心的東西。多多了解高人是如何實(shí)現(xiàn)的,這樣才能學(xué)到更多的知識,才能成長進(jìn)步。倘若某天被人問起,某種框架內(nèi)褲,其實(shí)現(xiàn)原理,那么只能是一臉懵逼了。
實(shí)現(xiàn)數(shù)據(jù)綁定的做法有大致如下幾種:
發(fā)布者-訂閱者模式(backbone.js
)
臟值檢查(angular.js
)
數(shù)據(jù)劫持(vue.js
)
vue.js
則是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()
來劫持各個屬性的setter,getter
,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。
假如寫過C#winform
自定義控件的,我想更好理解之后的邏輯和實(shí)現(xiàn)原理
在C#
中當(dāng)控件的某個屬性發(fā)生了變化,就刷新視圖
priveate int a ; public int A { get { return a; } set { if(a!=value){a = value; Invalidate(); } } } # 當(dāng)a的值發(fā)生變化, 就重繪視圖
再來看看Object.defineProperty(obj, prop, descriptor) 方法
地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty()
方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性,并返回這個對象。
obj
需要被操作的目標(biāo)對象
prop
目標(biāo)對象需要定義或修改的屬性的名稱。
descriptor
將被定義或修改的屬性的描述符
descriptor
configurable
當(dāng)且僅當(dāng)該屬性的configurable
為true
時,該屬性描述符才能夠被改變,同時該屬性也能從對應(yīng)的對象上被刪除。默認(rèn)為false
。
enumerable
當(dāng)且僅當(dāng)該屬性的enumerable
為true
時,該屬性才能夠出現(xiàn)在對象的枚舉屬性中。默認(rèn)為false
。數(shù)據(jù)描述符同時具有以下可選鍵值:
value
該屬性對應(yīng)的值??梢允侨魏斡行У?code>JavaScript值(數(shù)值,對象,函數(shù)等)。默認(rèn)為undefined
。
writable
當(dāng)且僅當(dāng)該屬性的writable
為true
時,該屬性才能被賦值運(yùn)算符改變。默認(rèn)為false
。 存取描述符同時具有以下可選鍵值:
get
一個給屬性提供getter
的方法,如果沒有getter
則為undefined
。該方法返回值被用作屬性值。默認(rèn)為undefined
。
set一個給屬性提供setter
的方法,如果沒有setter
則為undefined
。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。默認(rèn)為undefined
。
先來實(shí)現(xiàn)一個簡單數(shù)據(jù)劫持
var A = {}; var a = ""; Object.defineProperty(A, "a", { set: function (value) { a = value; }, get: function () { return "My name is " + a; }, }); A.a = "chuchur"; console.log(A.a); // My name is chuchur
不光是這么簡單,來看下vue
的代碼
{{word}}
已經(jīng)實(shí)現(xiàn)的簡單的數(shù)據(jù)劫持,那么有多個屬性,就要實(shí)現(xiàn)一個數(shù)據(jù)監(jiān)聽器Observer
,能夠?qū)?shù)據(jù)對象的所有屬性進(jìn)行監(jiān)聽,還需要一個訂閱器Dep
來收集這些屬性的變動來通知訂閱者
元素節(jié)點(diǎn)的v-model,v-on:click
,就需要實(shí)現(xiàn)一個指令解析器Compile
,對每個元素節(jié)點(diǎn)的指令進(jìn)行掃描和解析,根據(jù)指令模板替換數(shù)據(jù),以及綁定相應(yīng)的更新函數(shù)
最后實(shí)現(xiàn)一個訂閱者Watcher
,作為連接Observer
和Compile
的橋梁,能夠訂閱并收到每個屬性變動的通知,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù),從而更新視圖
大概的流程圖如下:
Observer
將需要observe
的數(shù)據(jù)對象進(jìn)行遞歸遍歷,包括子屬性對象的屬性,都加上setter
和getter
這樣的話,給這個對象的某個值賦值,就會觸發(fā)setter
,那么就能監(jiān)聽到了數(shù)據(jù)變化
// observe function observe(data) { if (data && typeof data === "object") { // 取出所有屬性遍歷 Object.keys(data).forEach(function (key) { defineReactive(data, key, data[key]); }); } return; } function defineReactive(data, key, val) { observe(val); // 監(jiān)聽子屬性 Object.defineProperty(data, key, { enumerable: true, // 可枚舉 configurable: false, // 不能再define get: function () { return val; }, set: function (value) { console.log("監(jiān)聽到值變化了: ", val, "==>", value); val = value; }, }); } var A = { fristName: "chuchur", age: 29, }; observe(A); A.fristName = "nana"; //監(jiān)聽到值變化了: chuchur ==> nana A.age = 30; //監(jiān)聽到值變化了: 29 ==> 30
這樣就實(shí)現(xiàn)了多個屬性的監(jiān)聽,接下來就是實(shí)現(xiàn)訂閱器Dep
,當(dāng)這些屬性變化的時候,觸發(fā)通知notify
,告訴執(zhí)行訂閱者執(zhí)行更新函數(shù)
//Dep function Dep() { this.subs = []; } Dep.prototype = { addSub: function (sub) { this.subs.push(sub); }, notify: function () { this.subs.forEach(function (sub) { sub.update(); }); }, };
把訂閱器植入到監(jiān)聽器里
function defineReactive(data, key, val) { var dep = new Dep() observe(val); //監(jiān)聽子屬性 Object.defineProperty(data, key, { set: function(value) { dep.notify() //發(fā)出通知, 我被改變了 } }); }
至此,簡陋的監(jiān)聽器就實(shí)現(xiàn)完成了,接下來繼續(xù)完成Watcher
。
到此,相信大家對“vue中observer數(shù)據(jù)雙向綁定原理”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!