Vue 响应式 / 双向数据绑定

2020-12-08  本文已影响0人  行走的蛋白质

一、关于双向数据绑定

双向数据绑定

二、双向数据绑定的实现

v-model 实现双向数据绑定
<input v-model="something">
// 等价于
<input
  v-bind:value="something"
  v-on:input="something = $event.target.value">

三、双向数据绑定的原理

2.0 版
<div>
    <input type="text" id="userName" name="">
    <br>
    <span id="view"></span>
</div>

<script type="text/javascript">
    let defineObject = {
        userInfo: {
            userName: '',
            password: '123456'
        }
    }
    let input = document.getElementById('userName')
    let view = document.getElementById('view')

    // 更新视图
    function update() {
        view.innerText = defineObject.userInfo.userName
    }
    //更新数据
    input.oninput = function () { 
        defineObject.userInfo.userName = this.value
    }

    observerData(defineObject)

    // 属性循环绑定
    function observerData(target) {
        if(!target || typeof target !== 'object') return target;

        Object.keys(target).forEach(item => {
            bindProps(target, item, target[item])
        })
    }

    // 属性绑定监听
    function bindProps(target, prop, value) {
        observerData(value) // 循环绑定

        Object.defineProperty(target, prop, {
            get() {
                console.log('getProp: ', value)
                return value
            },
            set(newValue) {
                console.log('setProp: ', newValue)
                if(newValue  === value) return

                value = newValue
                update()
            }
        })
    }
</script>
3.0版
    let defineObject = {
        userInfo: {
            userName: '',
            password: '123456'
        }
    }
    let input = document.getElementById('userName')
    let view = document.getElementById('view')

    // 更新视图
    function update(newValue) {
        view.innerText = newValue
    }
    //更新数据
    input.oninput = function () { 
        newProxy.userName = this.value
    }

    let newProxy = new Proxy(defineObject, {
        get(target, key, receiver) {
            console.log('getProp: ', target[key])
            return Reflect.get(target, key);
        },
        set(target, key, newValue, receiver) {
            console.log('setProp: ', target[key])
            if(key === 'userName') {
                update(newValue)
            }
            return Reflect.set(target, key, newValue)
        }
    });

三、思考的问题

1、Vue 为什么不能检测数组变动
上一篇 下一篇

猜你喜欢

热点阅读