Vue做数据和视图原理(数据劫持)

Vue做数据和视图相关变化,原理是用以下两个方法实现“数据劫持”。

  • Object.defineProperty() 只能劫持一个对象

  • Object.defineProperties() 可以劫持多个对象

定义Vue中组件对象data中的所有变量的setter,让他们在被设置的时候,刷新相关视图。

 

使用Object.defineProperty()方法实现数据劫持:

 

<body>
    <button>按我改A</button>
    <button>按我改B</button>
</body>

<script type="text/javascript">
    //只要这个对象被赋值,立马触发set和get函数(被它们劫持)
    var obj = { 
        a: 100,
        b: 200
    }

    var objA = obj['a']
    var objB = obj['b']
    
    Object.defineProperty(obj, 'a', {
        configurable: true,    //表示属性可以配置
        enumerable: true,      //表示这个属性可以遍历
    
        //setter 每次设置这个对象的属性时,都会被set方法劫持
        set:function(value){
            alert("set执行了,修改了a");
            objA = value
            console.log(value)
        },
    
        //getter 每次获取对象的这个属性时,都会被get方法劫持
        get:function(){
            alert("get执行了,读取了a");
            return objA; //被set函数接收
        }
     })
    
     document.getElementsByTagName("button")[0].onclick = function(){
        obj.a++; //obj.a的值变化Object.definePropertie()函数的set和get就能拦截到
     }
</script>

 

使用Object.defineProperties()方法实现数据劫持:

<body>
    <button>按我改A</button>
    <button>按我改B</button>
</body>
<script type="text/javascript">
    var obj = { //只要这个对象被赋值,立马触发set和get函数
        a: 100,
        b: 200
    }

    var objA = obj['a']
    var objB = obj['b']
    
    Object.defineProperties(obj, {
        a:{
            //setter 每次设置这个对象的属性时,都会被set方法劫持
            set:function(value){
                alert("A的set执行了,修改了a");
                objA = value
                console.log(value)
            },
    
            //getter 每次获取对象的这个属性时,都会被get方法劫持
            get:function(){
                alert("A的get执行了,读取了a");
                return objA;
            }
        },
        b:{
            set:function(value){
                alert("B的set执行了,修改了b");
                objB = value
                console.log(value)
            },
    
            get:function(){
                alert("B的get执行了,读取了b");
                return objB; 
            }
        },
     })
    
     document.getElementsByTagName("button")[0].onclick = function(){
        obj.a++; //obj.a的值变化Object.definePropertie()函数的set和get就能拦截到
     }
    
     document.getElementsByTagName("button")[1].onclick = function(){
        obj.b++; 
     }
</script>

 

posted @ 2019-11-25 22:37  垚土土  阅读(559)  评论(0编辑  收藏  举报