成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

基于Object.defineProperty實(shí)現(xiàn)雙向數(shù)據(jù)綁定

fredshare / 1219人閱讀

摘要:雙向數(shù)據(jù)綁定可算是前端領(lǐng)域經(jīng)久不衰的熱詞,不管是前端開(kāi)發(fā)還是面試都會(huì)有所涉及。因此,中的挺身而出,拯救了中對(duì)數(shù)組數(shù)據(jù)處理的不足。有興趣的朋友請(qǐng)期待筆者的下一篇博客,討論下用實(shí)現(xiàn)雙向數(shù)據(jù)綁定。

雙向數(shù)據(jù)綁定可算是前端領(lǐng)域經(jīng)久不衰的熱詞,不管是前端開(kāi)發(fā)還是面試都會(huì)有所涉及。而且不同的框架也想盡一切辦法去實(shí)現(xiàn)這一特性,比如:
Knockout / Backbone --- 發(fā)布-訂閱模式
Angular --- ‘臟檢查’
Vue --- "Object.defineProperty"

那么雙向數(shù)據(jù)綁定到底是什么?沒(méi)圖說(shuō)個(gè)卵,直接上圖

簡(jiǎn)單的說(shuō)就是在數(shù)據(jù)UI之間建立雙向的通信通道,當(dāng)用戶通過(guò)Function改變了數(shù)據(jù),那么這個(gè)改變也會(huì)立即反應(yīng)到UI上;或者說(shuō)用戶通過(guò)UI的操作,那么這些操作也會(huì)隨之引起對(duì)應(yīng)的數(shù)據(jù)變動(dòng)。emmmmmm...沒(méi)毛病!

既然本文標(biāo)題是討論Object.defineProperty,那么筆者就把當(dāng)前火熱的到Boom的國(guó)產(chǎn)框架:Vue.js 請(qǐng)出來(lái),然后在了解完她實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理之后,我們著手實(shí)現(xiàn)一個(gè)抽象派的雙向數(shù)據(jù)綁定。那么那位朋友就說(shuō)了,什么叫 抽象派 ?我估計(jì)吧,可能就是馬(Vue)和馬骨架的區(qū)別吧,TAT...

在介紹Vue的雙向數(shù)據(jù)綁定之前,筆者還想多叨叨幾句,如果某一天有人問(wèn)你:Vue是如何實(shí)現(xiàn)雙向數(shù)據(jù)綁定的? 姑且先在這里停頓下,思考下這個(gè)問(wèn)題的答案...................
或許有朋友會(huì)脫口而出“數(shù)據(jù)劫持”,說(shuō)的沒(méi)錯(cuò)!的確就是“數(shù)據(jù)劫持”,但是還不夠充分和不夠精確。筆者在這里也談下自己的一點(diǎn)點(diǎn)所見(jiàn)所聞所想:

不夠精確:與其說(shuō)是 數(shù)據(jù)劫持,更應(yīng)該說(shuō)是對(duì)數(shù)據(jù)對(duì)象的SetterGetter實(shí)現(xiàn)的劫持。

不夠充分:為什么說(shuō)不夠充分?是因?yàn)?Object.defineProperty 僅僅是實(shí)現(xiàn)了對(duì)數(shù)據(jù)的監(jiān)控,后續(xù)實(shí)現(xiàn)對(duì)UI的重新渲染并不是它做的,所以這里還涉及到 發(fā)布-訂閱模式(有興趣的朋友戳這里);過(guò)程是,當(dāng)監(jiān)控的數(shù)據(jù)對(duì)象被更改后,這個(gè)變更會(huì)被廣播給所有訂閱該數(shù)據(jù)的watcher,然后由該 watcher實(shí)現(xiàn)對(duì)頁(yè)面的重新渲染。

下面進(jìn)入正題,一起了解下Vue實(shí)現(xiàn)雙向數(shù)據(jù)綁定的原理,果斷上圖:

首先,Vue的Compile模塊會(huì)對(duì)Vue的 template 代碼進(jìn)行編譯解析并生成一系列的watcher,也可以稱之為“更新函數(shù)”,它負(fù)責(zé)把變更后的相關(guān)數(shù)據(jù)重新渲染到指定的地方。舉個(gè)栗子:

Compile會(huì)解析出 v-moel 這個(gè)指令并且生成 watcher 并連接數(shù)據(jù)中的 message 和當(dāng)前這個(gè)Dom對(duì)象,一旦收到這個(gè)message被變更的通知,watcher就會(huì)根據(jù)變更對(duì)這個(gè)Dom進(jìn)行重新渲染。

當(dāng)然一個(gè)頁(yè)面或者一個(gè)項(xiàng)目中肯定有很多watcher,因此Vue使用了Dep這個(gè)對(duì)象來(lái)存儲(chǔ)每一個(gè)watcher,當(dāng)數(shù)據(jù)發(fā)生變更,Observer會(huì)調(diào)用Dep的notify方法以通知所有訂閱了該數(shù)據(jù)的watcher,讓它們醒醒該干活了...

Vue的雙向數(shù)據(jù)綁定也說(shuō)得差不多了,下面就開(kāi)始順著這個(gè)思路著手寫(xiě)一個(gè)吧,畢竟說(shuō)得多不如code來(lái)得好?。。?!具體的實(shí)現(xiàn)效果如下,Let‘s do it

不知道為什么GIF上傳不了,所以只能將就用圖片了,QAQ....

功能就用文字解釋下:
第一個(gè)行的 title 0 直接顯示的是數(shù)據(jù),以便觀察;我們可以在輸入框中輸入任何int, 然后點(diǎn)擊“加”可以實(shí)現(xiàn)對(duì)數(shù)值的 +1 操作,同時(shí)輸入框的數(shù)值和 title 也會(huì)隨之變化;當(dāng)然,通過(guò)輸入數(shù)值,title也會(huì)跟著變化。

首先把Html代碼呈上來(lái):





    
    
    
    Object.defineProperty實(shí)現(xiàn)雙向綁定



    

然后開(kāi)始一步一步在index.js里寫(xiě)代碼吧
1) 首先我們先定義一個(gè)數(shù)據(jù)源

//數(shù)據(jù)源
let vm = {
    value: 0
}

2) 然后定義一個(gè)Dep,用于存儲(chǔ)watcher

//用于管理watcher的Dep對(duì)象
let Dep = function () {
    this.list = [];
    this.add = function(watcher){
        this.list.push(watcher)
    },
    this.notify = function(newValue){
        this.list.forEach(function (fn) {
            fn(newValue)
        })
    }
};

3) 模擬Compile出來(lái)的watchers,該demo涉及到兩個(gè)地方的重新render,一個(gè)是title,另一個(gè)是輸入框。所以寫(xiě)兩個(gè)watcher,然后存入Dep

// 模擬compile,通過(guò)對(duì)Html的解析生成一系列訂閱者(watcher)
function renderInput(newValue) {
    let el = document.getElementById("inp");
    if (el) {
        el.value = newValue
    }
}

function renderTitle(newValue) {
    let el = document.getElementById("h1");
    if (el) {
        el.innerHTML = newValue
    }
}

//將解析出來(lái)的watcher存入Dep中待用
let dep = new Dep();
dep.add(renderInput);
dep.add(renderTitle)

4) 使用 Object.defineProperty 定義一個(gè)Observer

function observer(vm, key, value) {
    Object.defineProperty(vm, key, {
        enumerable: true,
        configurable: true,
        get: function () {
            console.log("Get");
            return value
        },
        set: function (newValue) {
            if (value !== newValue) {
                value = newValue
                console.log("Update")

                //將變動(dòng)通知給相關(guān)的訂閱者
                dep.notify(newValue)
            }
        }
    })
}

5) 再將頁(yè)面使用的兩個(gè)方法寫(xiě)出來(lái)。(Vue使用的是指令對(duì)事件進(jìn)行綁定,但是本文不涉及指令,所以用最原始的方法綁定事件)

//頁(yè)面引用的方法
function inputChange(ev) {
    let value = Number.parseInt(ev.target.value);
    vm.value = (Number.isNaN(value)) ? 0 : value;
}

function btnAdd() {
    vm.value = vm.value + 1;
}

主要的代碼都寫(xiě)好后,下面第一件事就是初始化

//數(shù)據(jù)初始化方法
function initMVVM(vm) {
    Object.keys(vm).forEach(function (key) {
        observer(vm, key, vm[key])
    })
}

//初始化數(shù)據(jù)源
initMVVM(vm)

//初始化頁(yè)面,將數(shù)據(jù)源渲染到UI
dep.notify(vm.value);

這樣一個(gè)簡(jiǎn)單的基于 Object.defineProperty 的雙向數(shù)據(jù)綁定就完成了??赐甑呐笥延袥](méi)有對(duì)雙向數(shù)據(jù)綁定有了更多的理解了呢?如果沒(méi)有理解的話,可以將代碼復(fù)制到本地,然后循著代碼再運(yùn)行下,或許能容易理解。當(dāng)然這里的代碼并不高深,只是從淺層去談?wù)摿穗p向數(shù)據(jù)綁定,所以有不足或者表達(dá)錯(cuò)誤的地方,煩請(qǐng)各位朋友多多指正。

這里是源碼,由于放不了動(dòng)圖,所以有興趣的小伙伴可以拿下來(lái)

最后還是補(bǔ)充一句,Object.defineProperty雖然好用,但并不是無(wú)懈可擊的,它對(duì)數(shù)組數(shù)據(jù)的處理并沒(méi)有想象中的好甚至表現(xiàn)很差,因此Vue團(tuán)隊(duì)專門為Vue中的數(shù)組類型編寫(xiě)了額外的方法以實(shí)現(xiàn)對(duì)數(shù)組的正確監(jiān)控
。因此,ES6中的Proxy挺身而出,拯救了ES5 中 Object.defineProperty對(duì)數(shù)組數(shù)據(jù)處理的不足。有興趣的朋友請(qǐng)期待筆者的下一篇博客,討論下用Proxy實(shí)現(xiàn)雙向數(shù)據(jù)綁定。

咱們下期再見(jiàn)??!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/95800.html

相關(guān)文章

  • 最近老是有兄弟問(wèn)我,Vue雙向綁定的原理,以及簡(jiǎn)單的原生js寫(xiě)出來(lái)實(shí)現(xiàn),我就來(lái)一個(gè)最簡(jiǎn)單的雙向綁定,

    摘要:廢話不多說(shuō)直接看效果圖代碼很好理解,但是在看代碼之前需要知道雙向綁定的原理其實(shí)就是基于實(shí)現(xiàn)的雙向綁定官方傳送門這里我們用官方的話來(lái)說(shuō)方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性,并返回這個(gè)對(duì)象。 廢話不多說(shuō)直接看效果圖 showImg(https://segmentfault.com/img/bVbiYY5?w=282&h=500); 代碼很好理解,但是在看代碼之前...

    zhangfaliang 評(píng)論0 收藏0
  • 最近老是有兄弟問(wèn)我,Vue雙向綁定的原理,以及簡(jiǎn)單的原生js寫(xiě)出來(lái)實(shí)現(xiàn),我就來(lái)一個(gè)最簡(jiǎn)單的雙向綁定,

    摘要:廢話不多說(shuō)直接看效果圖代碼很好理解,但是在看代碼之前需要知道雙向綁定的原理其實(shí)就是基于實(shí)現(xiàn)的雙向綁定官方傳送門這里我們用官方的話來(lái)說(shuō)方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性,并返回這個(gè)對(duì)象。 廢話不多說(shuō)直接看效果圖 showImg(https://segmentfault.com/img/bVbiYY5?w=282&h=500); 代碼很好理解,但是在看代碼之前...

    aristark 評(píng)論0 收藏0
  • JavaScript 進(jìn)階之深入理解數(shù)據(jù)雙向綁定

    摘要:當(dāng)我們的視圖和數(shù)據(jù)任何一方發(fā)生變化的時(shí)候,我們希望能夠通知對(duì)方也更新,這就是所謂的數(shù)據(jù)雙向綁定。返回值返回傳入函數(shù)的對(duì)象,即第一個(gè)參數(shù)該方法重點(diǎn)是描述,對(duì)象里目前存在的屬性描述符有兩種主要形式數(shù)據(jù)描述符和存取描述符。 前言 談起當(dāng)前前端最熱門的 js 框架,必少不了 Vue、React、Angular,對(duì)于大多數(shù)人來(lái)說(shuō),我們更多的是在使用框架,對(duì)于框架解決痛點(diǎn)背后使用的基本原理往往關(guān)注...

    sarva 評(píng)論0 收藏0
  • vue.js源碼 - 剖析observer,dep,watch三者關(guān)系 如何具體的實(shí)現(xiàn)數(shù)據(jù)雙向綁定

    摘要:雙向數(shù)據(jù)綁定的核心和基礎(chǔ)是其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有和基于和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程收集依賴流程依賴收集會(huì)經(jīng)過(guò)以上流程,最終數(shù)組中存放列表,數(shù)組中存放列表。 Vue雙向數(shù)據(jù)綁定的核心和基礎(chǔ)api是Object.defineProperty,其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有Obderver、Dep和Watcher,基于d...

    mo0n1andin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

fredshare

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<