Vue监测数据的原理

简单模拟Vue2监测对象数据:

     let data={
        name:"小王",
        address:"北京"
     }
     function Observer(obj){
        //汇总对象中所有的属性形成一个数组
       const keys=Object.keys(obj)
       //遍历
       keys.forEach((k)=>{
        Object.defineProperty(this,k,{
            get(){
                return obj[k]
            },
            set(val){
                obj[k]=val
            }
        })
       })
     }
     //创建一个监视实例对象,用于监视data中属性的变化
     const obs=new Observer(data)
     let vm={}
     vm._data=data=obs

Vue2监测数据的原理:

Vue监测数据原理:
   1、Vue会监视data中所有层次的数据
   2、如何监测对象中的数据?
       通过setter实现监视,且要在new Vue时就传入要监测的数据。
       (1):对象中后追加的属性,Vue默认不做响应式处理;
       (2):如需给后添加的属性做响应式,需要使用如下API:
          Vue.set(target,propertyName/index,value)或 
          vm.$set(target,propertyName/index,value)
           target:要加属性的对象或数组 
           propertyName/index:属性的名字或数组的索引
           value:属性或索引的值
   3、如何监测数组中的数据:
       通过包裹数组更新元素的方法实现,本质就是做了两件事:
       (1):调用原生对应的方法对数组进行更新;
       (2):重新解析模板,进行页面更新;
   4、在Vue中修改数组中的某个元素一定要使用如下方法:
     (1)使用这些API:push(),pop(),shift(),unshift(),splice(),sort(),reverse();
     (2)、Vue.set()或vm.$set();
   特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性

数据代理与数据劫持:

在vue中的数据代理,实际上是通过vm上的属性代理对_data中属性的操作

在vue中的数据劫持,实际上是劫持vm上属性的变化,去重新解析模板,更新页面,实现响应式效果

Vue3.0的响应式: 

实现原理:

  • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
  • 通过Reflect(反射): 对源对象的属性进行操作。
            let person={
                name:"张三",
                age:18
            }
            //模拟Vue3中实现响应式
            const p=new Proxy(person,{
                //有人读取p的某个属性时调用
                get(target,propName){
                    console.log(`有人读取了p身上的${propName}属性`)
                    return Reflect.get(target,propName)
                },
                //有人修改或添加p的某个属性时调用
                set(target,propName,value){
                    console.log(`有人修改了p身上的${propName}属性`)
                    Reflect.set(target,propName,value)
                },
                //有人删除p的某个属性时调用
                deleteProperty(target,propName){
                    console.log(`有人删除了p身上的${propName}属性`)
                    return Reflect.defineProperty(target,propName)
                }
            })

你可能感兴趣的:(Vue,vue.js,前端,javascript)