\r\n```\r\n\r\nThese are just some personal suggestions, welcome to discuss them together",[],1204,"Suggestion: Is vueuse consider to create some directives?","2022-01-31T00:43:08Z","https://github.com/vueuse/vueuse/issues/1204",0.6892807,{"description":3072,"labels":3073,"number":3075,"owner":3022,"repository":3022,"state":3023,"title":3076,"updated_at":3077,"url":3078,"score":3079},"### Clear and concise description of the problem\n\nThinking of `createEventHook`, it allows us to trigger registered hooks (by using `on`) with given value. All the registered hooks can receive that given value and do theirselves logic.\r\n\r\nIn some cases, we need to collect execution result of those registered hooks. Therefore, registered hooks can return value which will be collected. But, here is different from `createEventHook`: All hooks won't be received the same initial value (when using `trigger`). Instead, each hook will receive the value which is returned by the previous hook. Certainly, the first hook will receive an initial value we give. Finally, `trigger` will return the value which is returned by the last hook.\r\n\r\nSee the example below.\n\n### Suggested solution\n\nIt should provide a utility function which is similar to `createEventHook`, but allows to return value.\r\n\r\nExample usage:\r\n\r\n```ts\r\nimport { createWaterfallHook } from '@vueuse/core'\r\n\r\nconst hook = createWaterfallHook\u003Cstring>()\r\nconst result = hook.trigger('')\r\nconsole.log(result) // 'ab'\r\n```\r\n\r\n```ts\r\nhook.on(s => s + 'a')\r\n```\r\n\r\n```ts\r\nhook.on(s => s + 'b')\r\n```\n\n### Alternative\n\nWithout this, I must use `createEventHook` then pass a mutable object:\r\n\r\n```ts\r\nimport { ref, type Ref } from 'vue'\r\nimport { createEventHook } from '@vueuse/core'\r\n\r\nconst hook = createEventHook\u003CRef\u003Cstring>>()\r\nconst state = ref('')\r\nhook.trigger(state)\r\nconsole.log(state.value) // 'ab'\r\n```\r\n\r\n```ts\r\nhook.on(state => {\r\n state.value += 'a'\r\n})\r\n```\r\n\r\n```ts\r\nhook.on(state => {\r\n state.value += 'b'\r\n})\r\n```\n\n### Additional context\n\nThere are two possible names for this function:\r\n\r\n- `createWaterfallHook`: The concept of \"waterfall\" comes from the core of webpack: [Tapable](https://github.com/webpack/tapable). Tapable has [\"waterfall\" hooks](https://github.com/webpack/tapable#hook-types). They pass an initial value to a plugin, and get the return value, then pass that return value to next plugin.\r\n- `createFilterHook`: The concept of \"filter\" comes from a famous CMS: [Wordpress](https://wordpress.org/). Its plugin system supports [\"filter\" hooks](https://developer.wordpress.org/plugins/hooks/filters/) which does similar things.\n\n### Validations\n\n- [X] Follow our [Code of Conduct](https://github.com/vueuse/vueuse/blob/main/CODE_OF_CONDUCT.md)\n- [X] Read the [Contributing Guidelines](https://github.com/vueuse/vueuse/blob/main/CONTRIBUTING.md).\n- [X] Read the [docs](https://vueuse.org/guide).\n- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.",[3074],{"name":3019,"color":3020},1480,"New utility: createWaterfallHook / createFilterHook","2022-09-21T20:39:27Z","https://github.com/vueuse/vueuse/issues/1480",0.6901596,{"description":3081,"labels":3082,"number":3084,"owner":3022,"repository":3022,"state":3023,"title":3085,"updated_at":3086,"url":3087,"score":3088},"### Clear and concise description of the problem\r\n\r\nWhen using `useThrottleFn` or `useDebounceFn` with an `async` callback, if the callback throws an error, the error is not handled by the [global error handler](https://vuejs.org/api/application.html#app-config-errorhandler) nor [errorCaptured](https://vuejs.org/api/options-lifecycle.html#errorcaptured) component instance (if configured).\r\n\r\n### Suggested solution\r\n\r\nAdd an `async` variant and check for the [global error handler](https://vuejs.org/api/application.html#app-config-errorhandler) or [errorCaptured](https://vuejs.org/api/options-lifecycle.html#errorcaptured).\r\n\r\nBeware, check the `Error Propagation Rules` on [errorCaptured](https://vuejs.org/api/options-lifecycle.html#errorcaptured).\r\n\r\nVue 2 and Vue 3 seems to be in sync.\r\n\r\n### Alternative\r\n\r\ncapture the error inside the callback, but them, we need to handle the error on each usage instead globally, a lot of work.\r\n\r\n### Additional context\r\n\r\n_No response_\r\n\r\n### Validations\r\n\r\n- [X] Follow our [Code of Conduct](https://github.com/vueuse/vueuse/blob/main/CODE_OF_CONDUCT.md)\r\n- [X] Read the [Contributing Guidelines](https://github.com/vueuse/vueuse/blob/main/CONTRIBUTING.md).\r\n- [X] Read the [docs](https://vueuse.org/guide).\r\n- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.",[3083],{"name":3019,"color":3020},1697,"add async variant for `useThrottleFn` and `useDebounceFn`","2022-09-21T16:38:13Z","https://github.com/vueuse/vueuse/issues/1697",0.6974006,{"description":3090,"labels":3091,"number":3093,"owner":3022,"repository":3022,"state":3023,"title":3094,"updated_at":3095,"url":3096,"score":3097},"### Clear and concise description of the problem\r\n\r\nThe current v10 implementation of `createEventHook`'s `EventHookOn` parameter `fn` should be typed as `(param: T) => void | Promise\u003Cvoid>`. The current type `(param: T) => void` will trigger some ESLint rules that can be avoided with the correct type, such as `@typescript-eslint/no-misused-promises`.\r\n\r\n\r\n### Suggested solution\r\n\r\n`fn` should be typed as `(param: T) => void | Promise\u003Cvoid>`\r\n\r\n### Alternative\r\n\r\nAnother type for `fn` that could be used is `(param: T) => unknown` which would accept promises and non-promises and allow the `trigger` return of `Promise\u003Cunknown[]>` to be more useful.\r\n\r\n### Additional context\r\n\r\n_No response_\r\n\r\n### Validations\r\n\r\n- [X] Follow our [Code of Conduct](https://github.com/vueuse/vueuse/blob/main/CODE_OF_CONDUCT.md)\r\n- [X] Read the [Contributing Guidelines](https://github.com/vueuse/vueuse/blob/main/CONTRIBUTING.md).\r\n- [X] Read the [docs](https://vueuse.org/guide).\r\n- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.",[3092],{"name":3019,"color":3020},2877,"EventHookOn should support accepting functions that return promises as well as void","2023-08-17T11:34:39Z","https://github.com/vueuse/vueuse/issues/2877",0.700231,{"description":3099,"labels":3100,"number":3102,"owner":3022,"repository":3022,"state":3023,"title":3103,"updated_at":3104,"url":3105,"score":3106},"### Clear and concise description of the problem\n\nAdd a new composable for one-shot event listeners, which behaves like `watchOnce`. It can be useful in scenes like:\r\n```js\r\nfunction onClick() {\r\n elStyle.value = { height: '100px' };\r\n useEventListener(el, 'transitionend', () => {\r\n // ...\r\n })\r\n}\r\n```\n\n### Suggested solution\n\nAdd a new composable called `useEventListenerOnce`, which has the same signature as `useEventListener`, and can be simply implemented as:\r\n```ts\r\nlet stop\r\nfn = (...args) => {\r\n fn(...args)\r\n stop()\r\n}\r\nstop = useEventListener(..., fn, ...);\r\nreturn stop\r\n```\n\n### Alternative\n\n_No response_\n\n### Additional context\n\n_No response_\n\n### Validations\n\n- [X] Follow our [Code of Conduct](https://github.com/vueuse/vueuse/blob/main/CODE_OF_CONDUCT.md)\n- [X] Read the [Contributing Guidelines](https://github.com/vueuse/vueuse/blob/main/CONTRIBUTING.md).\n- [X] Read the [docs](https://vueuse.org/guide).\n- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.",[3101],{"name":3019,"color":3020},2429,"New Feature: `useEventListenerOnce`","2022-11-11T09:46:34Z","https://github.com/vueuse/vueuse/issues/2429",0.7003284,["Reactive",3108],{},["Set"],["ShallowReactive",3111],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fZbQeENpLzOQDn8wV10orC5Fzamw5D47nRu9UYLFF2NQ":-1},"/vueuse/vueuse/496"]