Vue2.0/3.0雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理詳解
Vue2.0/3.0 雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理
雙向數(shù)據(jù)綁定簡(jiǎn)意 即數(shù)據(jù)的改變能讓頁(yè)面重新渲染
Vue2.0 ES5的原理:
Object.defineProperty 對(duì)數(shù)據(jù)進(jìn)行攔截
簡(jiǎn)單小案例
<body> 姓名: <span id="name"></span> <br /> <input type="text" id="inputName" /> </body>
改變input框的值 讓span里面的值隨之改變 數(shù)據(jù)的改變可以讓視圖
<script> let obj ={ name:'' } Object.defineProperty(obj,'name',{ get(){ return this.name //注意錯(cuò)誤示范 不可以用this 形成死循環(huán) 要準(zhǔn)備一個(gè)新的值 }, set(val){ } }) </script>
正確寫(xiě)法
<script> let obj = { name: "" }; let newObj = JSON.parse(JSON.stringify(obj)); Object.defineProperty(obj, "name", { get() { return newObj.name; }, set(val) { if (val === newObj.name) return; //增加判斷優(yōu)化性能 判斷新值與舊值是否一樣 一樣就返回 不一樣的話的再次賦值 newObj.name = val; obServer(); } }); // 重新賦值的方法 function obServer() { spanName.innerHTML = newObj.name; //獲取obj.name的值 inputName.value = newObj.name; } obServer(); //開(kāi)始就執(zhí)行一次 setTimeout(() => { obj.name = "大左"; }, 1000); </script>
執(zhí)行邏輯
1.setTimeout執(zhí)行1秒后修改數(shù)據(jù) 觸發(fā)obj.name的set(val)
2.拿到最新的值給到newObj.name 執(zhí)行 obServer()方法
3.拿到最新的值賦值 spanName.innerHTML = newObj.name; inputName.value = newObj.name;
input框的值改變 span框的值隨著改變
inputName.oninput = function() { obj.name = this.value; };
這個(gè)操作在Vue 里面叫v-model
Vue2.0不足之處
1.需要對(duì)原始數(shù)據(jù)進(jìn)行克隆 不然死循環(huán) 上面有提到
2.如果我們想給對(duì)象中的數(shù)據(jù)進(jìn)行g(shù)et和set的攔截 就要一個(gè)個(gè)設(shè)置 對(duì)象中的屬性都要單獨(dú)的監(jiān)聽(tīng)一下 如果有多個(gè)就要循環(huán)遍歷了 分別來(lái)監(jiān)聽(tīng)了
反看vue2.0中的data
data(){ return{ obj:{} } } this.obj.name='XXX' //這個(gè)操作行不通 因?yàn)閯傞_(kāi)始的時(shí)候obj里面沒(méi)有name所以就沒(méi)有進(jìn)行監(jiān)聽(tīng) 都是以上第二條造成的
ok 那我們?cè)倏匆幌?/p>
3.0的特點(diǎn)以及好處
主要用到了SE6里面的proxy
<script> let obj = {}; obj = new Proxy(obj, { get(target, prop) { console.log("D"); return target[prop]; }, set(target, prop, value) { console.log("Z"); target[prop] = value; } }); //監(jiān)聽(tīng)整個(gè)對(duì)象 不需要指定屬性 相當(dāng)于把對(duì)象里所有的屬性都監(jiān)聽(tīng)了 So 直接寫(xiě)整體的set get </script>
1.獲取obj.name 觸發(fā)get 這里沒(méi)有name 但是可以走 因?yàn)闆](méi)有值所以返回undefine
2. 設(shè)置給name值看一下 觸發(fā)set
3.再次獲取obj.name看看有沒(méi)有值
So 不管你現(xiàn)在對(duì)象里有沒(méi)有某個(gè)屬性 因?yàn)檫@里監(jiān)聽(tīng)的是整個(gè)對(duì)象 對(duì)象里面未來(lái)有的都有了 彌補(bǔ)2.0不足之處
1.不需要clone
2.也不需要給每一個(gè)對(duì)象里面的屬性單獨(dú)設(shè)置 給整體對(duì)象設(shè)置就ok了 干凈又衛(wèi)生啊
再次實(shí)現(xiàn)上面2.0的操作
<script> let obj = {}; obj = new Proxy(obj, { get(target, prop) { console.log("D"); return target[prop]; }, set(target, prop, value) { console.log("Z"); target[prop] = value; obServer(); } }); //監(jiān)聽(tīng)整個(gè)對(duì)象 不需要指定屬性 相當(dāng)于把對(duì)象里所有的屬性都監(jiān)聽(tīng)了 So 直接寫(xiě)整體的set get // 重新賦值的方法 function obServer() { spanName.innerHTML = obj.name; //獲取obj.name的值 inputName.value = obj.name; } obServer(); //開(kāi)始就執(zhí)行一次 setTimeout(() => { obj.name = "大左"; }, 1000); inputName.oninput = function() { obj.name = this.value; }; </script>
總結(jié)
到此這篇關(guān)于Vue2.0/3.0雙向數(shù)據(jù)綁定的實(shí)現(xiàn)原理的文章就介紹到這了,更多相關(guān)Vue雙向數(shù)據(jù)綁定原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中使用element-ui進(jìn)行表單驗(yàn)證的實(shí)例代碼
這篇文章主要介紹了vue中使用element-ui進(jìn)行表單驗(yàn)證的實(shí)例代碼,本文給大家分享實(shí)現(xiàn)思路,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06vue 解決mintui彈窗彈起來(lái),底部頁(yè)面滾動(dòng)bug問(wèn)題
這篇文章主要介紹了vue 解決mintui彈窗彈起來(lái),底部頁(yè)面滾動(dòng)bug問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11Nuxt.js實(shí)現(xiàn)一個(gè)SSR的前端博客的示例代碼
這篇文章主要介紹了Nuxt.js實(shí)現(xiàn)一個(gè)SSR的前端博客的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09vue開(kāi)發(fā)實(shí)現(xiàn)評(píng)論列表
這篇文章主要為大家詳細(xì)介紹了vue開(kāi)發(fā)實(shí)現(xiàn)評(píng)論列表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04vue.js動(dòng)畫(huà)中的js鉤子函數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了vue.js動(dòng)畫(huà)中的js鉤子函數(shù)的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07springboot?vue接口測(cè)試前端動(dòng)態(tài)增刪表單功能實(shí)現(xiàn)
這篇文章主要為大家介紹了springboot?vue接口測(cè)試前端動(dòng)態(tài)增刪表單功能實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Vue 用Vant實(shí)現(xiàn)時(shí)間選擇器的示例代碼
這篇文章主要介紹了Vue 用Vant實(shí)現(xiàn)時(shí)間選擇器的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10