Vue2.0/3.0 雙向數據綁定的實現原理
雙向數據綁定簡意 即數據的改變能讓頁面重新渲染
Vue2.0 ES5的原理:
Object.defineProperty 對數據進行攔截
簡單小案例
<body> 姓名: <span id="name"></span> <br /> <input type="text" id="inputName" /> </body>
改變input框的值 讓span里面的值隨之改變 數據的改變可以讓視圖
<script> let obj ={ name:"" } Object.defineProperty(obj,"name",{ get(){ return this.name //注意錯誤示范 不可以用this 形成死循環 要準備一個新的值 }, 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; //增加判斷優化性能 判斷新值與舊值是否一樣 一樣就返回 不一樣的話的再次賦值 newObj.name = val; obServer(); } }); // 重新賦值的方法 function obServer() { spanName.innerHTML = newObj.name; //獲取obj.name的值 inputName.value = newObj.name; } obServer(); //開始就執行一次 setTimeout(() => { obj.name = "大左"; }, 1000); </script>
執行邏輯
1.setTimeout執行1秒后修改數據 觸發obj.name的set(val)
2.拿到最新的值給到newObj.name 執行 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.需要對原始數據進行克隆 不然死循環 上面有提到
2.如果我們想給對象中的數據進行get和set的攔截 就要一個個設置 對象中的屬性都要單獨的監聽一下 如果有多個就要循環遍歷了 分別來監聽了
反看vue2.0中的data
data(){ return{ obj:{} } } this.obj.name="XXX" //這個操作行不通 因為剛開始的時候obj里面沒有name所以就沒有進行監聽 都是以上第二條造成的
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; } }); //監聽整個對象 不需要指定屬性 相當于把對象里所有的屬性都監聽了 So 直接寫整體的set get </script>
1.獲取obj.name 觸發get 這里沒有name 但是可以走 因為沒有值所以返回undefine
2. 設置給name值看一下 觸發set
3.再次獲取obj.name看看有沒有值
So 不管你現在對象里有沒有某個屬性 因為這里監聽的是整個對象 對象里面未來有的都有了 彌補2.0不足之處
1.不需要clone
2.也不需要給每一個對象里面的屬性單獨設置 給整體對象設置就ok了 干凈又衛生啊
再次實現上面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(); } }); //監聽整個對象 不需要指定屬性 相當于把對象里所有的屬性都監聽了 So 直接寫整體的set get // 重新賦值的方法 function obServer() { spanName.innerHTML = obj.name; //獲取obj.name的值 inputName.value = obj.name; } obServer(); //開始就執行一次 setTimeout(() => { obj.name = "大左"; }, 1000); inputName.oninput = function() { obj.name = this.value; }; </script>
總結
到此這篇關于Vue2.0/3.0雙向數據綁定的實現原理的文章就介紹到這了,更多相關Vue雙向數據綁定原理內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_46719868/article/details/115829724