Vue响应式原理之——Object.defineProperty

2018-12-10  本文已影响0人  李牧敲代码
先了解一下Object.defineProperty()这个方法:

这个方法主要是用

直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
先写一个demo

    let person = {
        _data: {
            name: 'wcx',
            age: 122
        }
    }
    Object.defineProperty(person, 'name', {
        get() {
            console.log(`name被获取了`);
            console.log(person);
            return person._data.name
        },
        set(value) {
            console.log(`name的值被修改了`)
            person._data.name = value;
            console.log(person);
        }
    })

这段代码可以直接写在HTML的<script>标签里,然后用浏览器运行这个HTML。接着,你可以打开F12控制台,在控制台里输入person['name']和 person['name']=‘wry’

图1.1
可以看到,Object.defineProperty可以监听到属性被获取和修改,这也就意味着你能做很多“数据驱动的事”,比如说双向绑定
什么是双向绑定?

单向绑定就是把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。
而双向绑定就是如果用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。

下面我们就实现下双向绑定:

<body>
    <form action="" class="form">
        <p>name: <input type="text" name="name"></p>
        <p>age: <input type="text" name="age"></p>
        <p>name_result: <input type="text" class="name"></p>
        <p>age_result: <input type="text" class="age"></p>
    </form>
<script>
    let person = {
        _data: {
            name: 'wcx',
            age: 13
        }
    }
    Object.defineProperty(person, 'name', {
        get() {
            console.log(`name被获取了`);
            console.log(person);
            return person._data.name
        },
        set(value) {
            console.log(`name的值被修改了`)
            person._data.name = value;
            console.log(person);            
        }
    })
    Object.defineProperty(person, 'age', {
        get() {
            console.log(`age被获取了`);
            console.log(person);
            return person._data.age
        },
        set(value) {
            console.log(`age的值被修改了`)
            person._data.age = value;
            console.log(person);            
        }
    })
    let form = document.querySelector('.form');
    form.addEventListener('input', (e) => {
        let _value = e.target.value;
        let nameDom = document.querySelector('.name');
        nameDom.value = _value;
        person['name'] = _value;
        console.log('person', person)
    })
</script>
</body>
image.png

可以看到在name输入框输入的值会影响到person里name的值,这样双向绑定就实现了。name_result主要是为了更方便的展示结果,不写也没关系。

(完)

上一篇下一篇

猜你喜欢

热点阅读