<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<p></p>
<button>Click</button>
<script>
//创建自定义事件实例,第一个参数是自定义事件名称
const customEvent = new CustomEvent('countChange', {
detail: '计数值发生改变', //detail 是初始化时传入的额外信息
bubbles: true, //是否冒泡
cancelable: true,
})
const ref = new Proxy(
{ count: 0 },
{
get(target, property, receiver) {
return Reflect.get(...arguments)
},
set(arget, property, value, receiver) {
customEvent.value = ref.count
window.dispatchEvent(customEvent)
return Reflect.set(...arguments)
},
}
)
const pElement = document.querySelector('p')
function change(content) {
pElement.innerHTML = content
}
document.querySelector('button').addEventListener('click', () => {
ref.count += 1
})
window.addEventListener('countChange', (e) => {
console.log(e)
change(e.value)
})
</script>
</body>
</html>
这个自定义事件的概念和vue的差不多,都是创建一个事件对象,然后进行事件发布
api 和 proxy 结合起来,可以很轻松搞定一些逻辑比较简单的发布-订阅模式
效果就是我点击按钮的时候, count 的计数 +1,触发了 proxy里面的set访问器
然后 dispatchEvent 发布了一个事件
在这个里面, ref 的 proxy 作为一个发布者,进行信息的发布,而 customEvent 自定义事件作为中介者, window.addEventListener 作为订阅者
Reflect 这个叫反射,是用来在 proxy 里面快速进行操作的东西,这个基本只会和 proxy 一起用