Vue做数据和视图相关变化,原理是用以下两个方法实现“数据劫持”。
-
-
Object.defineProperties() 可以劫持多个对象
定义Vue中组件对象data中的所有变量的setter,让他们在被设置的时候,刷新相关视图。
使用Object.defineProperty()方法实现数据劫持:
<body> <button>按我改A</button> <button>按我改B</button> </body> <script type="text/javascript"> //只要这个对象被赋值,立马触发set和get函数(被它们劫持) var obj = { a: 100, b: 200 } var objA = obj['a'] var objB = obj['b'] Object.defineProperty(obj, 'a', { configurable: true, //表示属性可以配置 enumerable: true, //表示这个属性可以遍历 //setter 每次设置这个对象的属性时,都会被set方法劫持 set:function(value){ alert("set执行了,修改了a"); objA = value console.log(value) }, //getter 每次获取对象的这个属性时,都会被get方法劫持 get:function(){ alert("get执行了,读取了a"); return objA; //被set函数接收 } }) document.getElementsByTagName("button")[0].onclick = function(){ obj.a++; //obj.a的值变化Object.definePropertie()函数的set和get就能拦截到 } </script>
使用Object.defineProperties()方法实现数据劫持:
<body> <button>按我改A</button> <button>按我改B</button> </body> <script type="text/javascript"> var obj = { //只要这个对象被赋值,立马触发set和get函数 a: 100, b: 200 } var objA = obj['a'] var objB = obj['b'] Object.defineProperties(obj, { a:{ //setter 每次设置这个对象的属性时,都会被set方法劫持 set:function(value){ alert("A的set执行了,修改了a"); objA = value console.log(value) }, //getter 每次获取对象的这个属性时,都会被get方法劫持 get:function(){ alert("A的get执行了,读取了a"); return objA; } }, b:{ set:function(value){ alert("B的set执行了,修改了b"); objB = value console.log(value) }, get:function(){ alert("B的get执行了,读取了b"); return objB; } }, }) document.getElementsByTagName("button")[0].onclick = function(){ obj.a++; //obj.a的值变化Object.definePropertie()函数的set和get就能拦截到 } document.getElementsByTagName("button")[1].onclick = function(){ obj.b++; } </script>