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>

 

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