zl程序教程

您现在的位置是:首页 >  前端

当前栏目

vue系列:数据双向绑定的原理

Vue数据原理 系列 绑定 双向
2023-09-27 14:27:09 时间

第一阶段:认识Object.defineProperty()

vue双向绑定的底层应用的是 Object.defineProperty() 这个函数

定义

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

语法

Object.defineProperty(obj, prop, descriptor)

参数名解释
obj要在其上定义属性的对象。
prop要定义或修改的属性的名称。
descriptor将被定义或修改的属性描述符。

返回值: 被传递给函数的对象。

举例

let person = {}
let name = 'zy'
Object.defineProperty(person, 'name', {
    get(){
        console.log('name属性被读取了')
        return name
    },
    set(newName){
        console.log('name属性被修改了')
        name = newName
    }
})

在这里插入图片描述
这就意味着,person的数据对象已经是可观测的了。

第二阶段:改写函数,让所有属性可观测

/**
 * 把一个对象的每一项都转化成可观测对象
 * @param { Object } obj 对象
 */
function observable (obj) {
    if (!obj || typeof obj !== 'object') {
        return;
    }
    let keys = Object.keys(obj);
    keys.forEach((key) =>{
        defineReactive(obj,key,obj[key])
    })
    return obj;
}
/**
 * 使一个对象转化成可观测对象
 * @param { Object } obj 对象
 * @param { String } key 对象的key
 * @param { Any } val 对象的某个key的值
 */
function defineReactive (obj,key,val) {
    Object.defineProperty(obj, key, {
        get(){
            console.log(`${key}属性被读取了`);
            return val;
        },
        set(newVal){
            console.log(`${key}属性被修改了`);
            val = newVal;
        }
    })
}
// 这时,person的两个属性都可以观测了
let person = observable({
    'name':'zy',
    'age':20
})

第三阶段:未完待续

参考资料

https://github.com/ljianshu/Blog/issues/70
https://www.cnblogs.com/wangjiachen666/p/9883916.html

在这里插入图片描述