Vue双向数据绑定

79 阅读1分钟

一.定义

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

二.语法

Object.defineProperty(参数一, 参数2, 参数三)
参数一:要定义属性的对象
参数二:要定义或修改的属性的名称
参数三:要定义或修改的属性描述符

三.例子

    let object1 = { name: "", age: '' }
    let obj = { name: "", age: '' }
    let keys = Object.keys(object1)
    for (let i in keys) {
        let data = keys[i];
        Object.defineProperty(object1, data, {
            // writable: true, //可写
            enumerable: true, //可读
            configurable:true, //可删除
            get() {
                return obj[data]
            },
            set(value) {
                obj[data] = value
            }
        })
    }
    
  • 参数三里面有一些默认的配置属性为false

    1. enumerable:true,//控制属性是否可以枚举,默认为false

    2. writable:true,//控制属性是否可以被修改,默认为false

    3. configurable:true,//控制属性是否可以被删除,默认为false

四.Vue底层原理中使用

    class Vue {
        $options;
        $data;
        constructor(options) {
            this.$options = options
            this.$data = options.data
            this.obj()
        }
        obj() {
            let keys = Object.keys(this.$data)
            for (let i in keys) {
                let key = keys[i];
                Object.defineProperty(this.$options, key,{
                    enumerable:true, //可读
                    configurable: true,
                    set(value) {
                        this.$options[key] = value;
                    },
                    get() {
                        return this.$options[key];
                    }
                })
            }
        }
    }
    let vm = new Vue({
        data: { name: '张三', age: 18 }
    })
    

总结实现原理:通过Object.defineProperty()把data对象中所有属性添加到vm上。 为每一个添加到vm上的属性,都指定一个getter/setter。 在getter/setter内部去操作(读/写)data中对应的属性。

五.Vue中的数据代理


const vm= new Vue({
    el: "#root",
    data: {
        name:"清华大学",
        address:"北京",
    },
  });

注意:
1.Vue中的数据代理
通过vm对象来代理data对象中属性的操作
2.Vue中数据代理的好处:
更加方便的操作data中的数据