Vue2和Vue3响应式数据的理解

319 阅读2分钟

什么是响应式

响应式就是数据改变,对应的视图也会改变。打个比方vue那些是响应式数据呢,是不是data里的数据,computed计算属性的数据是响应式数据,还有vuex里state也是响应式数据

vue2

调用observer函数判断data是不是对象,因为我们的data必须是对象对吧,如果不是对象或者是空的直接返回出去,之后对数据进行劫持

function observer(data) {
//对data进行判断
  if (typeof data !== 'object' || data == null) {
    return 
  }
 //判断用户是否已经观测
  if(data.__ob__){
   return data;
  }
  //对这个数据进行劫持,通过一个类
  return new observer(data)
}

内部使用defineReactive函数,里面使用defineProperty对我们的对象中的某个属性进行劫持,所以vue2数据响应式是通过Object.defineProperty来实现响应式的,注意他是对我们的对象中的某一个属性进行劫持,打个比方你的data数据嵌套许多层(data:{lists:{goods:{}})它就需要递归 性能就会降低

// 对数据进行劫持
function defineReactive(data, key, value) {
  // 获取到数组对应的dep
  let chilidDep = Observer(value)
  // 1.给我们的每一个属性添加一个dep
  let dep =new Dep()
  // 2.将dep 存放起来,当页面取值时,说明这个值用来渲染,在将这个watcher和这个属性关联起来
  Object.defineProperty(data, key, {
  })
}

vue3

采用的是proxy,他有个好处就是不管你是对象还是数组都会进行劫持,如果是多层数据,用户不使用,就不会递归,proxy比Object.defineProperty高效,响应也更快。

// 模拟Vue3中的数据代理
let user = {
        name: '小宁',
        age: 28
        };
    const proxyUser = new Proxy(user,{
            get(target,prop){
                console.log('get方法!');
                return Reflect.get(target,prop);
            },
            // 修改目标对象的属性值/为目标对象添加新的属性
            set(target,prop,value){
                return Reflect.set(target,prop, value);
            },
            // 删除目标对象上的某个属性
            deleteProperty(target,prop){
                console.log('delete方法');
                return Reflect.deleteProperty(target, prop);
            }
        });
        // 修改对象中的属性
        proxyUser.name = '小宋';
        //给对象添加一个新的属性
        proxyUser.sex = '男';
        //删除新添加的属性
        delete proxyUser.gender;