(1)vue2.0的响应式
实现原理
对象类型:通过Object.definedProperty()对属性的读取、修改进行拦截(数据劫持)
数组类型:通过重写更新数据的一系列方法来实现拦截。(对数组的方法进行了包裹)
Object.defineProperty(data,"count",{get(){},set(){} })
存在问题:
-
新增属性,删除属性都不会刷新界面
-
直接通过下标修改数组,界面不会自动更新 (可以用$set来刷新页面)
let person = {name:"李国栋",age:18}let p = {};Object.defineProperty(p,"name",{get(){console.log("有人读取数据时调用");return person.name},set(value){console.log("有人修改了数据,我要去更新页面");person.name = value}})
(2)vue3.0的响应式
实现原理
通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写,属性的添加,属性的删除等
通过Reflect(反射):对被代理对象的属性进行操作
MDN文档中描述的Proxy与Reflect:
Proxy:
https://developer.mozilla.org/zhCN/docs/Web/JavaScript/Reference/Global_Objects/ProxyReflect:
https://developer.mozilla.org/zhCN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
let person = {name:"李国栋",age:18}let p = new Proxy(person,{// 读取get(target,proname){// target表示原对象 proname表示对象名console.log("有人读取了person上的属性",target);return target[proname]},// 修改或者增加set(target,proname,value){console.log("有人修改了person上的属性,我要去更新了");target[proname] = value},// 删除deleteProperty(target,proname){console.log("有人删除了person上面的属性,我要去调用了");return delete target[proname]},});