赞
踩
在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);
上面是最简单的一种体现方法,通过对属性进行新增(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 }
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(); } }) }
给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';
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。