Vue2.0 双向数据绑定原理代码


var oldArrayPrototype = Array.prototype;
let proto = Object.create(oldArrayPrototype);// 继承
var arrayMethods = [
    'pop',
    'push',
    'reverse',
    'shift',
    'sort',
    'splice',
    'unshift'
]

arrayMethods.forEach(method => {
    proto[method] = function() {
        updateView(); // 切片编程
        oldArrayPrototype[method].call(this,...arguments); 
        // 把 this 指向 oldArrayPrototype[method]
    }
})
function isObject(val) {
    return typeof val === 'object' && val !== null;
}

function observe(data) {
    if(!isObject(data)) {
        return data;
    }

    if(Array.isArray(data)) {
        Object.setPrototypeOf(data,proto);// 把 proto 设为 data 的原型

        for (var i = 0; i < data.length; i++) {
            observe(data[i]);
        } 
    }
    // 取出所有属性遍历
    Object.keys(data).forEach(function(key) {
        defineReactive(data, key, data[key]);
    });
};

function defineReactive(data, key, val) {
    observe(val); // 监听子属性
    Object.defineProperty(data, key, {
        // enumerable: true, // 可枚举
        // configurable: false, // 不能再define
        get: function() {
            return val;
        },
        set: function(newVal) {
            observe(newVal); // 监听子属性
            console.log('哈哈哈,监听到值变化了 ', val, ' --> ', newVal);
            updateView(); // 切片编程
            val = newVal;
        }
    });
}

function updateView(){
    console.log('更新视图');
}

// let data = {name:'zf',age:{n:100}};
// observe(data);
// data.name = 'dmq'; // 哈哈哈,监听到值变化了 kindeng --> dmq
// // data.age = {n:200};
// data.age.n = 300;

let data = {name:[1,2,3]}
observe(data);
data.name.push(4); // 需要对 数组上的方法进行重写 push shift unshift pop push reverse 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值