Vue2.0/3.0雙向數(shù)據(jù)綁定的實現(xiàn)原理詳解
Vue2.0/3.0 雙向數(shù)據(jù)綁定的實現(xiàn)原理
雙向數(shù)據(jù)綁定簡意 即數(shù)據(jù)的改變能讓頁面重新渲染
Vue2.0 ES5的原理:
Object.defineProperty 對數(shù)據(jù)進行攔截
簡單小案例
<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 //注意錯誤示范 不可以用this 形成死循環(huán) 要準備一個新的值
},
set(val){
}
})
</script>
正確寫法
<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(); //開始就執(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;
};

這個操作在Vue 里面叫v-model
Vue2.0不足之處
1.需要對原始數(shù)據(jù)進行克隆 不然死循環(huán) 上面有提到
2.如果我們想給對象中的數(shù)據(jù)進行g(shù)et和set的攔截 就要一個個設(shè)置 對象中的屬性都要單獨的監(jiān)聽一下 如果有多個就要循環(huán)遍歷了 分別來監(jiān)聽了
反看vue2.0中的data
data(){
return{
obj:{}
}
}
this.obj.name='XXX' //這個操作行不通 因為剛開始的時候obj里面沒有name所以就沒有進行監(jiān)聽 都是以上第二條造成的
ok 那我們再看一下
3.0的特點以及好處
主要用到了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)聽整個對象 不需要指定屬性 相當于把對象里所有的屬性都監(jiān)聽了 So 直接寫整體的set get
</script>
1.獲取obj.name 觸發(fā)get 這里沒有name 但是可以走 因為沒有值所以返回undefine

2. 設(shè)置給name值看一下 觸發(fā)set

3.再次獲取obj.name看看有沒有值

So 不管你現(xiàn)在對象里有沒有某個屬性 因為這里監(jiān)聽的是整個對象 對象里面未來有的都有了 彌補2.0不足之處
1.不需要clone
2.也不需要給每一個對象里面的屬性單獨設(shè)置 給整體對象設(shè)置就ok了 干凈又衛(wèi)生啊
再次實現(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)聽整個對象 不需要指定屬性 相當于把對象里所有的屬性都監(jiān)聽了 So 直接寫整體的set get
// 重新賦值的方法
function obServer() {
spanName.innerHTML = obj.name; //獲取obj.name的值
inputName.value = obj.name;
}
obServer(); //開始就執(zhí)行一次
setTimeout(() => {
obj.name = "大左";
}, 1000);
inputName.oninput = function() {
obj.name = this.value;
};
</script>

總結(jié)
到此這篇關(guān)于Vue2.0/3.0雙向數(shù)據(jù)綁定的實現(xiàn)原理的文章就介紹到這了,更多相關(guān)Vue雙向數(shù)據(jù)綁定原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Nuxt.js實現(xiàn)一個SSR的前端博客的示例代碼
這篇文章主要介紹了Nuxt.js實現(xiàn)一個SSR的前端博客的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-09-09
vue.js動畫中的js鉤子函數(shù)的實現(xiàn)
這篇文章主要介紹了vue.js動畫中的js鉤子函數(shù)的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
springboot?vue接口測試前端動態(tài)增刪表單功能實現(xiàn)
這篇文章主要為大家介紹了springboot?vue接口測試前端動態(tài)增刪表單功能實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05

