一.前言
在用vue的兄弟們始終繞不開vue的數據雙向綁定,在vue的2.x版本中用object.defineProperty來實現雙向數據綁定原理,而在vue3.0版本中用Proxy這個對象來代替object.defineProperty實現數據的雙向綁定。但是換湯不換葯,這倆種數據雙向綁定都是基於數據劫持來實現的。
數據劫持:當訪問或者設置對象的屬性的時候,觸發相應的函數,並且返回設置屬性的值。
1.VUE2.0通過Object.defineProperty來劫持對象屬性的getter和setter操作,當數據發生變化時發出通知
2.VUE3.0通過Proxy來劫持數據,當數據發生變化時發出通知
3.數據劫持的優勢:
①不需要進行顯示調用,vue的雙向綁定原理就是通過數據劫持+發布訂閱來實現的,比如angular的臟檢查需要通過顯示調用markForCheck,react則需要通過setState來進行顯示調用
②通過屬性的劫持可以精准獲得變化的內容,這部分不需要額外的diff操作,減少性能消耗
二.VUE2.X與VUE3.0的數據雙向綁定的原理及實現
1.vue2.x雙向綁定實現
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="yingaxiang" content="width=device-width, initial-scale=1.0"> 6 <title>vue2.x數據雙向綁定</title> 7 </head> 8 <body> 9 <div> 10 <input type="text" id="input"> 11 <span id="text"></span> 12 </div> 13 </body> 14 </html> 15 <script> 16 var obj = {}; 17 Object.defineProperty(obj, 'prop', { 18 get: function () { 19 return val; 20 }, 21 set: function (newVal) { 22 val = newVal; 23 document.getElementById('text').innerHTML = val; 24 } 25 }); 26 document.addEventListener('keyup', function (e) { 27 obj.prop = e.target.value; 28 }); 29 </script>
2.vue3.0雙向綁定實現
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="yingaxiang" content="width=device-width, initial-scale=1.0"> 6 <title>vue3.0數據雙向綁定</title> 7 </head> 8 <body> 9 <div> 10 <input type="text" id="input"> 11 <span id="text"></span> 12 </div> 13 </body> 14 </html> 15 <script> 16 var obj = {}; 17 var obj1 = new Proxy(obj, { 18 // target就是第一個參數obj, receive就是返回的obj(返回的proxy對象) 19 get: function (target, key, receive) { 20 // 返回該屬性值 21 return target[key]; 22 }, 23 set: function (target, key, newVal, receive) { 24 // 執行賦值操作 25 target[key] = newVal; 26 document.getElementById('text').innerHTML = target[key]; 27 } 28 }) 29 document.addEventListener('keyup', function (e) { 30 obj1[0] = e.target.value; 31 }); 32 </script>
3.proxy相較於object.defineProperty的優勢
- 直接監聽對象而非屬性
- 直接監聽數組的變化
- 攔截方式較多(有13種方式)
- Proxy返回一個新對象,可以只操作新對象達到目的,而Object.defineProperty只能遍歷對象屬性直接修改(需要用深拷貝進行修改)
- Proxy作為新標准將受到瀏覽器廠商重點持續的性能優化
不知道大家有這樣的疑問沒?既然proxy作為ES6的語法並且還有這么多的優點為啥不在之前2.X版本中就用Proxy?(ES6可比vue2.0版本出現的早哈)
其實還是兼容性的問題,畢竟作為es6的新語法兼容性不好,最主要就是proxy不能用polyfill來兼容(polyfill主要撫平不同瀏覽器之間對js實現的差異)
