vue2的数据拦截Object.defineProperty和vue3的proxy

zhuanbike 11月前 419

Object.defineProperty这种方法的缺点是无法直接拦截数组(当然,也有点长),我们先看一个Object.defineProperty()的案例:

let obj = {}
let other = '';
 
Object.defineProperty(obj,'name',{
    enumerable:true,//设置是否可枚举
    configurable:true,//能不能删除这个属性
    get(){//读取方法
        console.log('--------');
        return other;
    },
    set(val){//设置方法
        other = val
    }
 
 
// })
obj.name=789
console.log(obj.name);
 
 
 
let obj = {
    other:'123',
    get name(){
        return this.other;
    },
    set name(val){
        this.other = val
    }
}
obj.name = '456'
console.log(obj.name);
// 对象的 setter和getter
 
// vue的数据劫持 (把所有属性都给成 get 和set方法)
function update(){
    console.log('更新视图');
}
let data = {
    name:'hj',
    age:90,
    adress:{
        location:'昌平'
    }
}
function observer(obj){
   
    if(typeof obj !=='object') return obj;
    for (let key in obj) {
        deineReactive(obj,key,obj[key])
    }
}
function deineReactive(obj,key,value){
    observer(value)
    Object.defineProperty(obj,key,{
        get(){
            return value
        },
        set(val){
            if(val!==value){
                observer(val)
                update()
                value = val
            }
           
        }
    })
}
observer(data);
data.age = 82;
data.adress = [1,2,3];
 
let methods = ['push','slice','pop','sort','reverse','unshift'];
methods.forEach(method=>{
    let oldMethod = Array.prototype[method];
    Array.prototype[method] = function(){
        update()
        oldMethod.call(this,...arguments)
    }
})
data.adress.push(4)

下面细讲一下 Proxy 代理方法:

function vue(){
    this.$data ={
        a:1
     };
    this.el = document.getElementById("app");
    this._html = "";
    this.observe(this.$data)
    this.render()
}
vue.prototype.observe = function(obj){
    var self = this;
    this.$data=new Proxy(this.$data,{
        get:function(target, key) {
            return target[key]
        },
        set: function(target, key, newvalue){
            target[key] = newvalue
            self.render()
        }
    })
}
vue.prototype.render = function(){
    this._html="i am" + this.$data.a;
    this.el.innerHTML = this._html;
}

两种比较

defineProperty只能监听某个属性,不能全局对象监听,而proxy就可以,所以省去for-in;

defineProperty get中没有值;

,提高效率,可以监听数组,不需要再去单独对数组做操作


最新回复 (2)
  • zhuanbike 11月前
    0 引用 2
    参考文章(重要):https://www.cnblogs.com/ldq678/p/13854113.html   
    Object.defineProperty详解
  • zhuanbike 11月前
    0 引用 3
    参考文章(重要):https://blog.csdn.net/weixin_44420276/article/details/102387234
    vue3 使用proxy实现数据响应
发新帖