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>