vue数据变化的监控是如何做到的
mvvm框架里的数据监控对象,包括 基本数据类型和对象, 对象分为对象和数组.
首先是对普通数据类型和对象的监控.其次是对数组的监控.
对对象的监控需要用到递归;
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9 </head> 10 11 <body> 12 q请输入:<input id="oInput" type="text"> 13 <div> 14 <p>我是绑定的输出框</p> 15 <div id="show"></div> 16 </div> 17 18 19 <script> 20 //创建一个data对象作为数据层model 21 //输入时,将input的值传给data,data接到值后,触发通知函数,并将值传给show 22 //当data的值被修改时候,触发data的set,将input的值修改,并传值给show 23 const data = { 24 value: '', 25 demo: '' 26 } 27 oInput.oninput = function () { 28 data.value = this.value; 29 } 30 31 function observe(data) {//监控对象属性发生变化 32 if (!data || typeof data !== 'object') { 33 return; 34 } 35 Object.keys(data).forEach(function (ele) {//对象的所有属性 36 definePro(data, ele, data[ele]) //形成闭包; 37 }) 38 39 } 40 function definePro(data, key, value) { 41 observe(value) //用递归监控value是object的情况. 42 Object.defineProperty(data, key, { 43 get() { 44 getProx(); 45 return value; 46 }, 47 set(newVal) { 48 if(value === newVal){//判断改没改 49 return ; 50 } 51 setProx(); 52 value = newVal;//这一步最重要!!!!形成闭包,返回value就可以 53 update(); 54 } 55 }) 56 57 58 } 59 function update(){ 60 var value = data.value 61 show.innerText = value; 62 oInput.value = value; 63 } 64 function getProx() { 65 console.log('get') 66 } 67 function setProx() { 68 console.log('set') 69 } 70 observe(data) 71 </script> 72 73 </body> 74 75 76 </html>
对应数组,利用defineProperty监控Array.prototype.
1 let arr = []; 2 let { push } = Array.prototype;//仅以push为例
7 function update() { 8 console.log('更新了') 9 } 10 function observe(data) { 11 Object.defineProperty(Array.prototype, 'push', { 12 value: function (...arg) { 13 update(); 14 push.apply(this, arg); 15 } 16 17 }) 18 } 19 observe();