語法
let proxy = new Proxy(target, handler)
1工育、第一個參數(shù)target键兜,可以是對象和數(shù)組
2挚歧、第二個參數(shù)handler
{
get(obj, prop, receiver) {
return Reflect.get(obj, prop, receiver))
},
set(obj, prop, value, receiver) {
// obj 目標對象
// prop 屬性
// value 更改的值
// receiver proxy本身
return Reflect.set(obj, prop, value, receiver))
}
}
監(jiān)聽對象
<!-- proxy 代理 -->
<!DOCTYPE html>
<html>
<body>
<div class="personName"></div>
</body>
<script type="text/javascript">
let personName = document.getElementsByClassName('personName')[0]
let obj = {
name: 'jack',
}
let proxy = new Proxy(obj, {
get(obj, prop, receiver) {
return Reflect.get(obj, prop, receiver)
},
set(obj, prop, value, receiver) {
obj[prop] = value
personName.innerHTML = obj
return Reflect.set(obj, prop, value, receiver)
},
})
proxy.name = 'tom'
</script>
</html>
數(shù)據(jù)雙向綁定
<!-- proxy 代理響應式 -->
<!DOCTYPE html>
<html>
<body>
<input class="personAgeInput" />
<div class="personAge"></div>
</body>
<script type="text/javascript">
let personAge = document.getElementsByClassName('personAge')[0]
let personAgeInput = document.getElementsByClassName('personAgeInput')[0]
let obj = {
name: 'jack',
age: 12,
arr: [1,2,3,4],
m: {
n: 9
}
}
let proxy = new Proxy(obj, {
get(obj, prop, receiver) {
return Reflect.get(obj, prop, receiver)
},
set(obj, prop, value, receiver) {
obj[prop] = value
// 監(jiān)聽到輸入框輸入茎辐,給dom賦值
if (prop === 'age') {
personAgeInput.value = value
personAge.innerHTML = value
}
return Reflect.set(obj, prop, value, receiver);
},
})
// input 輸入事件
personAgeInput.oninput = function(e) {
proxy.age = e.target.value
}
</script>
</html>
深層監(jiān)聽對象
例如上面的監(jiān)聽對象缕允,如果這樣操作
proxy.arr.push(10)
proxy.m.n = 100
無法觸發(fā)set函數(shù)峡扩,即監(jiān)聽不到值的改變
這是因為Proxy只能監(jiān)聽一層對象屬性
為了能監(jiān)聽到整個對象,需要給該對象中的每一層對象添加監(jiān)聽
<!-- proxy 代理 -->
<!DOCTYPE html>
<html>
<body>
<div class="personArr"></div>
</body>
<script type="text/javascript">
let personArr = document.getElementsByClassName('personArr')[0]
let obj = {
name: 'jack',
age: 12,
arr: [1,2,3,4],
m: {
n: 9
}
}
function reactive(obj) {
return new Proxy(obj, {
get(obj, prop, receiver) {
// 給每個對象添加監(jiān)聽
if (typeof obj[prop] === 'object') {
return reactive(obj[prop])
}
return Reflect.get(obj, prop, receiver)
},
set(obj, prop, value, receiver) {
obj[prop] = value
if (Array.isArray(obj)) {
personArr.innerHTML = obj
}
return Reflect.set(obj, prop, value, receiver);
},
})
}
let proxy1 = reactive(obj)
// 會觸發(fā)dom重新渲染
proxy1.arr[4] = 9
proxy1.arr.push(10, 20)
</script>
</html>
初始化數(shù)據(jù)渲染
let proxy = new Proxy() 不會立刻出發(fā)set函數(shù)
通過給proxy的屬性賦值時才會觸發(fā)set
<!-- proxy 代理 -->
<!DOCTYPE html>
<html>
<body>
<div class="personName"></div>
<input class="personAgeInput" />
<div class="personAge"></div>
<div class="personArr"></div>
</body>
<script type="text/javascript">
let personAge = document.getElementsByClassName('personAge')[0]
let personAgeInput = document.getElementsByClassName('personAgeInput')[0]
let personArr = document.getElementsByClassName('personArr')[0]
let personName = document.getElementsByClassName('personName')[0]
let obj = {
name: 'jack',
age: 12,
arr: [1,2,3,4],
m: {
n: 9
}
}
function reactive(obj) {
return new Proxy(obj, {
get(obj, prop, receiver) {
if (typeof obj[prop] === 'object') {
return reactive(obj[prop])
}
console.log('讀取參數(shù)', prop, receiver)
return Reflect.get(obj, prop, receiver)
},
set(obj, prop, value, receiver) {
console.log(`${prop}更改`, obj, prop, value, receiver)
if (prop === 'age') {
personAgeInput.value = value
personAge.innerHTML = value
}
if (prop === 'name') {
personName.innerHTML = value
}
if (prop === 'arr') {
console.log('數(shù)組更改', value)
personArr.innerHTML = value.join(',')
}
obj[prop] = value
if (Array.isArray(obj)) {
personArr.innerHTML = obj
}
return Reflect.set(obj, prop, value, receiver);
},
})
}
let proxy1 = reactive(obj)
// 為proxy1初始化數(shù)據(jù)
function initData(proxy, obj) {
for (let key in obj) {
if (typeof obj[key] === 'object') {
initData(proxy[key], obj[key])
} else {
proxy[key] = obj[key]
}
}
}
initData(proxy1, obj)
proxy1.arr[4] = 9
proxy1.arr.push(10, 20)
console.log('更改后', proxy1.arr, proxy1.age)
personAgeInput.oninput = function(e) {
console.log(e.target.value)
proxy1.age = e.target.value
}
</script>
</html>