-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Custom Directive API Change #33
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
Comments
I think it will make sense to still support directives on components, even if we receive an array of elements. Some DOM manipulations like v-focus or v-clickaway are still valid for components. This will also make the adoption strategy a bit harder |
@posva making the first argument |
True, but it isn't much for existing directives to just extract the first element and throw if there are more (thinking of a possible codemod) const [el] = elements
if (elements.length > 1) throw new Error() For example, v-focus could lookup an input/select/button or explicitly tab-indexed element. For clickaway it could look up a But my point is, recreating those features with components is way more verbose: <Focus>
<v-text-field/>
</Focus> or isn't declarative: <v-text-field ref="mainInput"/> this.$refs.mainInput.focus() // a component method |
Just thinking out loud: Would this be achievable? And if so, would it make any sense? Would make the implementation treeshakable, right? import {
beforeMount,
mounted,
beforeUpdate,
update,
beforeUnmount,
unmounted,
} from 'vue/directives'
export default () => {
mounted((el, binding, vnode, prevVnode) => {
// do stuff
})
} |
@posva I just realized in v3 directives are in fact implemented as special VNode data hooks - that is to say in render functions you can do this: h('div', {
vnodeMounted() { ... },
vnodeUpdated() { ... }
}) And for template So they would be also included in the child component's |
Revised and published: vuejs/rfcs#32 |
Summary
Re-design custom directive API so that it better aligns with component lifecycle
Custom directives usage on components will follow the same rules as discussed in the Attribute Fallthrough Behavior RFC. It will be controlled by the child component via
v-bind="$attrs"
.Basic example
Before
After
Motivation
Make custom directive hook names more consistent with the component lifecycle.
Detailed design
Hooks Renaming
Existing hooks are renamed to map better to the component lifecycle, with some timing adjustments. Arguments passed to the hooks remain unchanged.
bind
->beforeMount
inserted
->mounted
beforeUpdate
new, called before the element itself is updatedremoved, useupdate
updated
insteadcomponentUpdated
->updated
beforeUnmount
newunbind
->unmounted
Usage on Components
In 3.0, with fragments support, components can potentially have more than one root nodes. This creates an issue when a custom directive is used on a component with multiple root nodes.
To explain the details of how custom directives will work on components in 3.0, we need to first understand how custom directives are compiled in 3.0. For a directive like this:
Will roughly compile into this:
Where
vFoo
will be the directive object written by the user, which contains hooks likemounted
andupdated
.applyDirective
returns a cloned VNode with the user hooks wrapped and injected as vnode lifecycle hooks (see Render Function API Changes for more details):As a result, custom directives are fully included as part of a VNode's data. When a custom directive is used on a component, these
vnodeXXX
hooks are passed down to the component as extraneous props and end up inthis.$attrs
.This is consistent with the attribute fallthrough behavior discussed in vuejs/rfcs#26. So, the rule for custom directives on a component will be the same as other extraneous attributes: it is up to the child component to decide where and whether to apply it. When the child component uses
v-bind="$attrs"
on an inner element, it will apply any custom directives used on it as well.Drawbacks
N/A
Alternatives
N/A
Adoption strategy
$attrs
as discussed in Attribute Fallthrough Behavior should apply as well.Unresolved questions
N/A
The text was updated successfully, but these errors were encountered: