Vue2数据代理与数据劫持,你还不会吗?

数据代理

1. Object.defineproperty(对象名,属性名,配置项):vue实现的底层原理技术

即控制新增的属性,是否可以被增删改等等。getter和setter为重要函数

可将外部改变应用到内部

Object.defineProperty(person,'age',{
       // value:18,
       // enumerable:true, //控制属性是否可以枚举,默认值是false
      // writable:true, //控制属性是否可以被修改,默认值是false
      // configurable:true //控制属性是否可以被删除,默认值是false

      //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
      get(){
              console.log('有人读取age属性了')
              return number
       },

       //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
       set(value){
              console.log('有人修改了age属性,且值是',value)
              number = value
       }
2. 数据代理的定义:通过一个对象代理对另一个对象中属性的操作(读/写)

options.data=vm._data=dataVue2数据代理与数据劫持,你还不会吗?_第1张图片

3. 基本原理
  • 把data对象中所有属性添加到vm
  • 为每一个添加到vm上的属性,都指定getter和setter
  • 在getter/setter内部去操作data中对应的属性
    • setter为响应式setter,调用时会内部再调用方法,可以引起模板的重新解析,生成虚拟DOM,引起后续动作

数据劫持(监测数据原理)

当更新数据时:1. 加工data、2. vm._data=data

  1. vue会监视data中所有层次的数据
  2. 监测对象原理:
    在加工data中,通过setter实现监视,且要在new Vue时就传入监测数据
const obs=new Observer(data) //Observer实例对象
vm._data=data=obs //数据赋值
function Observer(obj){
  const keys=Object.keys(obj) //汇总所有属性,返回数组形式
  keys.forEach((k)=>{ //为每一个属性添加数据代理
    object.definProperty(this,k,{
      get(){ return obj\[k\] }
      set(val){ console.log( \`${k}被修改了\` ) }
    })
  })
}
  • Vue.set(),用于后续添加的新属性,做响应式处理
Vue.set( target, key, val ) 
//或vm.$set( vm.student,'sex','女' )
  • 局限:只能给data里某一个对象追加属性,而不能直接在data上追加
  • 即不允许为vm或vm.data追加属性
  1. 监测数组原理:
  • 不使用getter/setter,而是使用数组的方法

    • 注意:不可以只操作数组索引值进行修改
  • 通过包裹数组上的常用方法来实现

    • vue操作:1.调用Array.prototype的数组方法、2.重新解析模板、更新页面
    • 即这里的数组方法,不再是Array.prototype的数组方法
    • pop、push、shift、unshift、splice、sort、reverse
      • 即变更方法:能够引起数组变化的
      • 若使用非变更方法,则修改后重新赋值原数组即可
    hobby:['烫头''打游戏''玩']
    //方法1:splice修改值
    vm.student.hobby.splice( 0,1,'打台球' ) //['打台球','打游戏','玩']
    //方法2:set设置属性修改值
    Vue.set( vm.student.hobby,1,' 学习 ' ) //['烫头','学习','玩']
    
    friends:[{name:'jack',age:35},{name:'tony',age:36}]
    //1、修改其中的值
    this.student.frinends[0].name='张三' //即不要直接修改索引
    //2、添加新的数据
    this.student.frinendsun.unshift({ name:'jack',age:70 })
    

总结:

  • 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
  • 数据劫持:加工data,为每个属性添加getter和setter
  • 若该属性没有getter/setter,则vue无法监测并实时更新页面。若有则可以进行修改

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