-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
New issue
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
Add a way to pass reactive arguments to custom directives #8034
Comments
refs are unwrapped in templates, that's not going to change in the current major version at least. You can only work around that. i.e. by using a plain wrapper object (which is not being unwrapped). Also, custom directives are not set up to deal with reactive effects from So right now you have watchers that stay in memory forever. A more typical implementation of such a custom directive would look something like this: const elsColors = new WeakMap()
const elsHandlers = new WeakMap()
export default {
mounted(el, binding) {
elsColors.set(el, binding.value)
const handler = (event) => {
console.log('handler', event.type)
el.style.backgroundColor = event.type === 'mouseenter'
? elsColors.get(el)
: ''
}
elsHandlers.set(el, handler)
el.addEventListener('mouseenter', handler)
el.addEventListener('mouseleave', handler)
},
updated(el, binding) {
elsColors.set(el, binding.value)
// I can't find a way to tell `mounted()` to use a different backgroundColor from here
// Also: it would be tedious to manually keep state in sync using updated-hook
},
beforeUnmoun(el) {
const handler = elsHandlers.get(el)
el.removeEventListener('mouseenter', handler)
el.removeEventListener('mouseleave', handler)
}
}; For most instances, you could likely even drop the whole handling of the unmounting as the event listeners should stop working when the element is being unmounted anyway, and disappears with GC. However, Vue could re-use that element for other purposes (i.e. in a v-if /v-else scenario), so cleaning up like this is safer. |
Very interesting; I've tried something similar, since it felt wrong to use reactive properties in directives, but did not know about I'm wondering what the prefix Should you clean up inside PS: in case somebody copies your code: |
el(ement)s You dont have to clean up the maps because they are WeakMaps. When the element is being garbage collected, the maps entry is as well. |
What was new to me is that a DOM element can be key of an object; nice :) |
It can be the key of a Map, yes. |
What problem does this feature solve?
I created a minimal reproduction of the issue. I know that this minimal reproduction can be solved with both composables and component just fine, but please believe me that for my use case a directive is the most pleasant developer experience.
Arguments in custom directives can be dynamic, but unfortunately they seem to get
unref
d in the process?https://codesandbox.io/s/reactive-argument-in-custom-directives-6bpg7t?file=/src/directive.js
Here I would like the background color on hover to react to the state change when toggling.
What does the proposed API look like?
I am clueless to how the API would need to change, since we already do pass a reactive property.
Maybe when we pass a computed property it can keep its reactivity?
The text was updated successfully, but these errors were encountered: