vue 2.0与3.0的双向数据绑定实现原理

一、vue 2.0双向数据绑定

  在vue2.0中实现双向数据绑定,主要通过数据劫持的方式来实现。通过Object.defineProperty来劫持对象属性的gettersetter操作,当数据发生变化时发出通知。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title>vue2.0实现双向绑定</title>
 6     </head>
 7     <body>
 8         姓名:<span id="spanName"></span>
 9         <br/>
10         <input type="text" id="inputName"/>
11     </body>
12     <script>
13         let obj={
14             name:''
15         }
16         let newObj = JSON.parse(JSON.stringify(obj));  //进行深拷贝
17         
18         // 数据劫持
19         Object.defineProperty(obj,'name',{   //监听obj中的name属性
20             get(){
21                 return newObj.name;     //不能直接返回obj.name防止无限循环
22             },
23             set(val){
24                 if(val === newObj.name)  return;     //如果相同就不进行赋值   
25                 newObj.name = val;
26                 setInner()  
27             }
28         })
29         
30          //设置页面元素的值
31         function setInner(){ 
32             spanName.innerHTML = obj.name;   
33             inputName.value = obj.name;
34         }
35         
36         //监听input的输入,设置obj中name的值
37         inputName.oninput = function (){
38             obj.name = this.value
39         }
40     
41     </script>
42 </html>

二、vue 3.0双向数据绑定

  3.0的双向绑定的实现比2.0更加简单,是通过es6语法中的proxy代理来进行实现。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>vue3.0实现双向绑定</title>
    </head>
    <body>
        姓名:<span id="spanName"></span>
        <br/>
        <input type="text" id="inputName"/>
    </body>
    <script>
        let obj = {};
        
        obj = new Proxy(obj,{
            get(target,prop){
                return target[prop]
            },
            // target 原先的值   prop代表对象的key值  value最新的值['']
            set(target,prop,value){
                target[prop] = value;
                setInner()
            }
        })
        
        
        
         //设置页面元素的值
        function setInner(){ 
            spanName.innerHTML = obj.name;   
            inputName.value = obj.name;
        }
        
        //监听input的输入,设置obj中name的值
        inputName.oninput = function (){
            obj.name = this.value
        }
    
    </script>
</html>

三、相比于vue2.x,使用proxy的优势如下

  • 1 defineProperty只能监听某个属性,不能对全对象监听
  • 2 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
  • 3 可以监听数组,不用再去单独的对数组做特异性操作
  • vue3.x可以检测到数组内部数据的变化
posted @ 2022-03-16 16:00  前端小小瀚  阅读(902)  评论(0编辑  收藏  举报