什么是数据响应式
“响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码。例如,视图渲染中使用了数据,数据改变后,视图也会自动更新。
要点:追踪数据的变化,在读取数据或者设置数据时能劫持一些操作
Vue2使用Object.defineProperty实现响应式
var obj = {}var ageObject.defineProperty(obj, 'age', {get: function(){console.log('get age...')return age},set: function(val){console.log('set age...')age = val}})obj.age = 100 // 'set age...'console.log(obj.age) // 'get age...', 100
总结来说就是,object.definePropety会把数据改为getter和setter。当读取数据的时候调用get,设置数据的时候调用set。同时还能在get和set中写入一些对数据的操作从而监听数据的变化,触发页面渲染。
Vue3使用Proxy实现响应式
Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(例如属性查找、赋值、枚举、函数调用等)
Reflect是一个内置的对象,它提供拦截JS操作的方法
const dinner = {meal: 'tacos'}const handler = {get(target, prop) {console.log('get...', prop)//return target[prop]return Reflect.get(...arguments)},set(target, key, value) {console.log('set...', key, value)//target[key] = valuereturn Reflect.set(...arguments)}}const proxy = new Proxy(dinner, handler)console.log(proxy.meal)
区别
Vue2的响应式中,如果给data添加新的属性,那么这个新的属性就不会被追踪拦截(不是响应式)。需要使用Vue.set或者this.$set把属性创建并添加代理才会响应式
而Vue3的响应式中,给data添加新属性也会被拦截监听(是响应式的)
总结来说就是:
Proxy能劫持整个对象,⽽Object.defineProperty只能 劫持对象的属性;前者递归返回属性对应的值的代理 即可实现响应式,后者需要深度遍历每个属性;后者 对数组的操作很不友好
