proxy对象实现数据双向绑定

proxy对象顾名思义是对象的代理,对目标对象进行封装成代理对象,以达到读取、修改、查询目标对象属性等操作时起到拦截作用,对目标对象的默认操作进行重新定义。下面看一个例子:

let obj = {name: 'zhangsan', age: 20}
let objHandler = {
    get: function(target,propKey){
        return '您访问的属性: obj.' + propKey + ": " + target[propKey] 
    },
    set: function(target,propKey,value){
        if(propKey === 'name'){
            typeof value !== 'string' ? console.log('你设置的值类型错误,请输入字符串类型') : target[propKey] = value
        } else {
            target[propKey] = value
        }
    }
}
let objProxy = new Proxy(obj, objHandler)
objProxy.name   // "您访问的属性: obj.name: zhangsan"
objProxy.name = 222   // 你设置的值类型错误,请输入字符串类型

我们可以看到对obj对象封装成objProxy代理对象后,读取或者设置obj的name属性时,objProxy对象进行了拦截,改变了obj的默认行为,根据需要相应的重定义行为。这就给我们一个启发,vue的数据双向绑定是不是可以用proxy对象来实现呢?答案是肯定的,见代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>proxy实现数据双向绑定</title>
</head>
<body>
    <div id='demotext'></div>
    <button id="buttonclick">click</button>
    <div><input type="text" id="inputtext"/></div>
    <script>
        let data = {
            proxyText: ''
        }
        let demoText = document.querySelector('#demotext')
        let inputText = document.querySelector('#inputtext')
        let buttonClick = document.querySelector('#buttonclick')
        let dataHandler = {
            set: function(target, propKey, value){
                target[propKey] = value
                inputText.value = value
                demoText.innerHTML = value
            }
        }
        // 将data对象封装成代理对象
        let dataProxy = new Proxy(data, dataHandler)
        // 监听输入框的输入事件,将输入值赋值给代理对象实例,触发set方法拦截,
        // 实现从输入框值到data对象proxyText属性值绑定
        inputText.addEventListener('input',function(e){
            dataProxy.proxyText = e.currentTarget.value
        })
        // js中动态改变data对象proxyText属性值,实现从data对象到input输入框的绑定
        buttonClick.addEventListener('click',function(e){
            dataProxy.proxyText = 'you have clicked me!'
        })
    </script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章