欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用 Object.defineProperty (vue2)和 Proxy(vue3)实现Vue双向数据绑定

程序员文章站 2022-07-12 22:57:17
...
//html
<div id="app"><div>
  
//js 
var vm=new Vue();
setTimeout(function(){

   vm.$data.a=12345;
},2000)

function vue(){
    //初始化
    this.$data={a:1};
    this.el=document.getElementById('app');
    this.virtualdom="";   //语法树
    this.observe(this.$data)
    this.render();

}
//数据监听
vue.prototype.observe=function(obj){
     var self=this;
     var value;
     for(var key in obj){
         value=obg[key];
         if(typeof value==='object'){
             //如果是对象,继续调用自身,对里面的对象进行数据劫持
             this.observe(value)
         }else{
              //数据劫持
             Object.defineProperty(this.$data,key,{
                 get:function(){
                 //Vue里面在get方法里进行依赖收集,收集对应的变量,在哪些地方用到了,此处省略       
                    return value;
                 } ,
                 set:function(newValue){
                 //Vue里面在set方法里触发收集的依赖的更新
                    value=newValue;
                  //触发视图更新
                     self.render();
                 }
                  
             })
         }
     }
}
//视图更新方法
Vue.prototype.render=function(){
    this.virtualdom=`i am `+this.$data.a;
    this.el.innerHTML=this.virtualdom;

}

   vue3里面使用Proxy方法进行数据双向绑定:

   和defineProperty相比的优点:

    1.Proxy代理原对象,生成代理对象,不会污染原对象;defineProperty修改原对象;
    2.参数不同,defineProperty只能监听对象的某个属性;Proxy直接监听这个对象;
    3.不需要去外部定义value;

//html
<div id="app"><div>
  
//js 
var vm=new Vue();
setTimeout(function(){

   vm.$data.a=12345;
},2000)

function vue(){
    //初始化
    this.$data={a:1};
    this.el=document.getElementById('app');
    this.virtualdom="";   //语法树
    this.observe(this.$data)
    this.render();

}
//数据监听
vue.prototype.observe=function(obj){
     var self=this;
   /*
     1.Proxy代理原对象,生成代理对象;defineProperty修改原对象
     2.参数不同,defineProperty只能监听对象的某个属性;Proxy直接监听这个对象
     3.不需要去外部定义value
   */
     this.$data=new Proxy(this.$data,{
       get:function(target,key,receiver){
          //target是obj2原对象,key是属性,receiver是代理对象
           return target[key];
       },
       set:function(target,key,value,receiver){
          //value 是新的值
          //return target[key]=value;
          //代替上述方法,Proxy 对应的方法
           Reflect.set(target,key,value);
            self.render();
       }

     })
      
}
//视图更新方法
Vue.prototype.render=function(){
    this.virtualdom=`i am `+this.$data.a;
    this.el.innerHTML=this.virtualdom;

}

 

 

相关标签: vue javascript