We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
这篇文章的思路来源为 ahooks,因为 react 已经有相对应的实现了,所以这里主要介绍 vue 下如何实现一个 hook 的发布订阅。
假设有一个需求,当价格发生改变的时候刷新列表,在 vue 中很自然而然想到调用 watch 观察,但是这样的调用还是有点繁琐。例如下面一段伪代码
import { ref, watch } from 'vue'; const isChange = ref(false); const refreshList = () => { // 省略 isChange.value = false; }; const onClick = () => { isChange.value = true; }; watch(isChange, (val) => { if (!val) { return; } refreshList(); });
但是仔细观察一下,其实我们只是想让变化的时候通知一下,然后调用 refreshList 即可。
且我们也不希望每次都复制这样一段代码在其他组件中重复使用,基于上面的场景我们很容易想到可以写一个发布订阅的模块来实现我们需求。
class EventEmitter { subscriptions = new Set(); emit = (val) => { for (const subscription of this.subscriptions) { subscription(val); } }; useSubscription = (callback) => { this.subscriptions.add(subscription); }; }
上面的发布订阅模块很简单,useSubscription 来订阅,emit 来进行通知。下面是使用形式
useSubscription
emit
const event = new EventEmitter(); const refreshList = () => {}; const fn = (val) => { if (val !== 'refresh') { return; } refreshList(); }; event.useSubscription('refresh', fn); const onClick = () => { event.emit('refresh'); }; onUnmounted(() => { event.subscriptions.delete(fn); });
使用方式稍微简化了一下,不过也多出了 onUnmounted,这也谈不上方便,因为会有额外的心智负担,上面之所以单独写一个 fn 就是因为卸载的时候需要卸载对应的函数才行。
onUnmounted
fn
基于简化和不想重复管理的需求,我们再重新写一版,这里我们采用 hook 的形式来书写
class EventEmitter { subscriptions = new Set(); emit = (val) => { for (const subscription of this.subscriptions) { subscription(val); } }; useSubscription = (callback) => { this.subscriptions.add(callback); onUnmounted(() => { this.subscriptions.delete(callback); }); }; } const useEventEmitter = () => { const event = new EventEmitter(); return event; };
上面的逻辑改变了一下,我们在 useSubscription 中调用 onUnmounted 来完成一个自动的卸载。
之后使用方法
const event = useEventEmitter(); const refreshList = () => {}; event.useSubscription((val) => { if (val !== 'refresh') { return; } refreshList(); }); const onClick = () => { event.emit('refresh'); };
这里就达到我们期待的一个效果了,不过还是有需要改进的地方:
在使用发布订阅的场景基本上组件之间的层级会嵌套很多,例如上面每次调用 useEventEmitter 生成一个新的 event 所以通过单例简化为全局唯一的 event 即可,或者也可以借助 provide 和 inject 解决这一问题
useEventEmitter
event
provide
inject
class EventEmitter { subscriptions = new Set(); emit = (val) => { for (const subscription of this.subscriptions) { subscription(val); } }; useSubscription = (callback) => { this.subscriptions.add(callback); onUnmounted(() => { this.subscriptions.delete(callback); }); }; } const event = new EventEmitter(); const useEventEmitter = () => { return event; };
The text was updated successfully, but these errors were encountered:
你是否在搜索 mitt
Sorry, something went wrong.
No branches or pull requests
这篇文章的思路来源为 ahooks,因为 react 已经有相对应的实现了,所以这里主要介绍 vue 下如何实现一个 hook 的发布订阅。
假设有一个需求,当价格发生改变的时候刷新列表,在 vue 中很自然而然想到调用 watch 观察,但是这样的调用还是有点繁琐。例如下面一段伪代码
但是仔细观察一下,其实我们只是想让变化的时候通知一下,然后调用 refreshList 即可。
且我们也不希望每次都复制这样一段代码在其他组件中重复使用,基于上面的场景我们很容易想到可以写一个发布订阅的模块来实现我们需求。
EventEmitter
上面的发布订阅模块很简单,
useSubscription
来订阅,emit
来进行通知。下面是使用形式使用方式稍微简化了一下,不过也多出了
onUnmounted
,这也谈不上方便,因为会有额外的心智负担,上面之所以单独写一个fn
就是因为卸载的时候需要卸载对应的函数才行。基于简化和不想重复管理的需求,我们再重新写一版,这里我们采用 hook 的形式来书写
useEventEmitter
上面的逻辑改变了一下,我们在
useSubscription
中调用onUnmounted
来完成一个自动的卸载。之后使用方法
这里就达到我们期待的一个效果了,不过还是有需要改进的地方:
在使用发布订阅的场景基本上组件之间的层级会嵌套很多,例如上面每次调用
useEventEmitter
生成一个新的event
所以通过单例简化为全局唯一的 event 即可,或者也可以借助provide
和inject
解决这一问题改进之后
The text was updated successfully, but these errors were encountered: