当前位置:   article > 正文

vue中的数据的响应Object.defineProperty_let methodname=params.shift();

let methodname=params.shift();

在vue中v-model是通过Object.defineProperty来实现的,如下:

const data = {};
let name = '张三';
// 对对象定义属性
// 需要3个参数
// 参数1:对象本身
// 参数2:定义的属性
// 参数3:定义属性的选项
Object.defineProperty(data, 'name', {
  get(){
    console.log('get执行了');
    return name;
  },
  set(newVal){
    console.log('set执行了:', newVal);
    name = newVal;
  }
})
console.log(data.name);
data.name = '李四';
console.log(data.name);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

上面是最简单的一种体现方法,通过对属性进行新增(Vue.set)和(Vue.delete)不能做到完全响应式。
复杂的对象,需要自己实现深度监听,进行递归监听。需要一次性监听到底的。

数量多的情况下,会导致页面卡死。 解决:vue3.0 采用 proxy polyfill

promise babel polyfill
function Promise(){
}
Promise()

对数组没有办法进行监听。需要进行额外的处理,所以数组主要是通过给数据重新定义原型,再创建新的原型,再通过循环遍历给它添加数组的一些方法

定义一个对象,封装一个函数监听对象属性
const data = {
  name: 'zhangsan',
  age: 20,
  info: {
    height: 180
  },
  list: ['a', 'b', 'c']
}
// 监听对象属性的方法
function observer(target){
  // 判断监听数据的类型
  if(typeof target !== 'object' || target === null){
    // 不是对象或者数组就被过滤了
    return target;
  }

  if(Array.isArray(target)){
    target.__proto__ = arrProto;
    return;
  }

  for( let key in target ){
    defineReactive(target, key, target[key]);
  }

}
// 监听数据的变化
observer(data);

/* data.age = {
  value: 20
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
定义原型重新创建原型调用Object.defineProperty方法并监听
function updateView(){
  console.log('视图更新了....');
}

// 重新定义数组的原型
const oldArrayProperty = Array.prototype;
// 创建新的对象,原型指向的是oldArrayProperty
// 在这个对象上扩展方法不会影响Array.prototype
const arrProto = Object.create(oldArrayProperty);
const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
// arrProto.push
// arrProto.pop
// arrProto.shift
// arrProto.unshift
// arrProto.splice
// arrProto.sort
// arrProto.reverse
methods.forEach(methodName=>{
  arrProto[methodName] = function(){
    oldArrayProperty[methodName].call(this, ...arguments);
    // 更新dom
    updateView();
  }
})
// 对每一个属性进行观测
function defineReactive(target, key, value){

  // 深度监听
  observer(value);

  Object.defineProperty(target, key, {
    get(){
      console.log('get执行了');
      return value;
    },
    set(newValue){
      console.log(key, 'set执行了');

      // 对新设置的属性值还需要进行深度监听
      observer(newValue);

      value = newValue;
      // 更新视图
      updateView();
    }
  })
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

给data改变属性验证是否发生改变

// 设置
data.info.height = 190;

data.age.value = 30; //

data.info.address = '深圳';//Vue.set

delete data.name;//Vue.delete


// data.list.push('hello');

// data.list[1] = 'xx';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号