ES5-数据劫持

VUE双向数据绑定核心功能由Observer、Compile、Watcher三部分实现,其中Observer部分功能实现由Object.defineProperty实现。
1)Observer:监测数据变化进行相应回调(数据劫持);
实现一个简单的数据劫持,作为Object.defineProperty的练习。从而引出Proxy&Reflect

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <input type="text" id='demo'/>
    <div id='show'></div>
    <script>
        var oDiv = document.getElementById('show');
        var oInput = document.getElementById('demo');

        var oData = {
            //valueObj: {
              //  value: '你陈哥',
              // name: 'haha'
            //},
             value: '你陈哥',
            sex: 'aaa'  
        };
        oInput.oninput = function () {
            oData.value = this.value;
            //oData.valueObj.value = this.value;
        };
        function upDate () {
            oDiv.innerText = oData.value;
            //oDiv.innerText = oData.valueObj.value;
        }
         // 监控对象的某个属性是否发生改变
        function Observer (data) {
            if (!data || typeof data != 'object') {
                return data;
            };
            // for (var prop in data) {

            // }
            Object.keys(data).forEach(function (key) {
                definedRective(data, key, data[key]);
            });
        }

        function definedRective (data, key, val) {
            // AO
            //Observer(val);
            Object.defineProperty(data, key, {
                get () {
                    // console.log('get');
                    return val;
                },
                set (newValue) {
                    if (newValue == val) return;
                    val = newValue;
                    upDate();
                }
            })
        };

        Observer(oData);

我们一开始在定义一个oData对象,对象里面有个属性value,并设置了属性值。
接着绑定oninput事件,监听input框中值的改变将input框中的值赋给obj.value,并通过upData函数将input框中的值插入oDiv中。
构造Observer函数监控对象的某个属性是否发生改变(1.判断数据是否传进去、数据是不是对象2.VUE中Object.defineProperty一般不存在于Observer函数中,而是重新定义一个函数definedRective3.definedRective函数在判断数据是否改变,通过if操作判断重新输入个数据是否与输入前的数据相同,以优化性能)
完成这些操作对于VUE而言还不够,如何将数组中的数据展现在视图呢?
2)vue3.0以前的版本在数组上的操作,其实也很简单,就是把数组上的方法给重写了

        let arr = [];
        let {push} = Array.prototype;
        function upData () {
            console.log('更新');
        };
        // [
        //     'push',
        //     'pop'
        // ]
        // arr push pop unshift shift slice....
        Object.defineProperty(Array.prototype, 'push', {
            value: (function () {
                return (...arg) => {
                    push.apply(arr, arg);
                    upData();
                }
            })()
        });
        arr.push(1, 2);

image.png
当然VUE通过Observer监控数据变化是有额外的问题。当我们在前边加载Observer最后加上一句oData.aa = 10;难道Observer还要重新加载一遍吗?而在Proxy Reflect中就很好的解决了这一问题。但是,兼容性不是很好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值