vue2.0响应式原理的实现(数据改变触发更新事件)

  1. vue响应式原理 vue2.0的响应式原理依靠的es5的Object.defineProperty来实现的 Object.defineProperty传入3个参数,第一个是要监听的,第二个是要监听的属性,第三个是一个对象包含两个函数set和get,分别在获取和改变这个对象的属性时调用。 我们在这里使用这个函数实现以下vue响应式原理(页面更新即触发log输出)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue2响应式原理</title>
</head>

<body>

</body>
<script>
    const data = {
        name: 杰哥,
        age: 20,
        friend: {
            friendName: 灼子,
            girlFriend: { girlFriendName: 娟子 },
        },
        color: [red, orange, green]
    }

    // 重写一个数组原型,来重写数组的一些基本方法如push等,来监听数组元素这些方法的调用
    const oldArrayProto = Array.prototype;
    const newArrayProto = Object.create(oldArrayProto);
    [push, pop, unshift, shift].forEach(menthodName => {
        newArrayProto[menthodName] = function () {
            console.log(更新视图 + menthodName);
            oldArrayProto[menthodName].call(this, ...arguments);
        }
    })
    // 绑定监听事件
    observer(data);
    function observer(target) {
        //如果是非引用数据直接返回
        if (typeof target !== object || target === null) {
            return target;
        }
        //如果这个被监听的属性是数组,那就他的原型改为我们新创建的数组原型,来达到监听的目的
        if (Array.isArray(target)) {
            target.__proto__ = newArrayProto;
        }
        for (let key in target) {
            defineReactive(target, key, target[key]); //为每个对象属性设置监听函数,监听对象的每个属性值
        }
    }
    // 我们要做的是 监听这个对象当前的所有属性,这个对象属性发生变化之后,监听也要随之变化
    function defineReactive(target, key, value) {
        //这里是处理深层对象的数据,进行深层监听
        observer(value);
        Object.defineProperty(target, key, {
            get: function () {
                return value;
            },
            set: function (newValue) {
                // 数据改变的时候也要更新监听
                observer(newValue);
                if (newValue !== value) {
                    console.log(更新视图: + value + => + newValue);
                    value = newValue;
                }
            }
        })
    }

    // 正常测试
    data.name = 杰哥2.0;
    data.friend.friendName = 灼子2.0;
    data.friend.girlFriend.girlFriendName = 娟子2.0;

    // 数组测试
    // data.color[0] = blue;
    data.color.push(blue);

    // 弱点测试
    delete data.age;
    //的时候不会触发监听事件,这是vue2.0的弱点,在vue2中使用 Vue.delete
    data.test = something;
    // 这种情况也不会触发监听事件,在vue中使用Vue.set


</script>

</html>
经验分享 程序员 微信小程序 职场和发展