One of the powerful features of components is being able to create custom form elements. However, there is no easy way to set focus on them. Here is a mockup of the steps required http://jsfiddle.net/sv1ay748/1/. Because it is props down and events up it is pretty complicated to emit an even on the child from the parent. And I don't see any sane way of having focus be reactive data property.
One possible way of handling this is having a special directive that can only occur once in a component and only on inputs and textareas that is set on the form element that is supposed to receive the focus. Then vue also handles when a focus event is emitted on the custom component and focus is set to the input with the directive on it.
Another way is vue handles only the event and it is left to the developer to receive it and set the focus appropriately.
I realize this creates a special case scenario for vue, but form elements are special case scenarios. And I feel this would really help make programming them much more natural.
Why not just this.$refs.name.focus()?
That doesn't seem to work http://jsfiddle.net/sv1ay748/2/.
Also, I personally like the idea of a v-focus directive that can be added to this kind of component. Also, this directive could only listen to focus events initiated on the component so as not to interfere with any native focus events, or perhaps it should have a custom name to distinguish it.
@qw3n it seems to be working for me - does focus the custom input when the button is clicked.
Ok I must have done something wrong because it works for me now. So do you feel this is a sufficient work around or do you think a directive would be helpful?
I'm not sure how a v-focus directive would help in this situation - but I think calling a method on a ref seems straightforward enough for me. Closing this for now. But feel free to expand on how you think v-focus would help.
@yyx990803 basically v-focus would provide a standardized way of setting focus. While adding
focus(){
this.$refs.input.focus();
}
to every methods property isn't huge it would add up.
Idea of how it might look
<template
<div>
<input v-focus v-model="first">
<input v-model="last">
</div>
</template>
Then the parent could just
this.$refs.componentName.$emit('focus');
//or even something like
this.$refs.componentName.$focus();
I think the main benefits would be it would be a bit more intuitive since native inputs already have this functionality and it provides a standard way of doing it. That way if you are using someone else's component, since there is an official directive, they may be more likely to add that functionality.
I don't think what you want should be a directive - it could be a component mixin though.
@yyx990803
This is just an added suggestion off the top of my head (that could be possibly taking it to far), but multiple v-focus directives could also be used in place of tabindex. This would again encourage the component creators to add support for things like tab navigation. I'm thinking mainly in terms of writing components that are shareable and reusable. Since I feel that most component authors aren't going to be thinking about adding support for focus events or tab navigation. Maybe not this, but something like this could help in guiding authors to create more accessible components as well.
Actually, even if you don't have control over a 3rd party component, you can still do this.$refs.someInput.$el.querySelector('input').focus()
@yyx990803 yes, but that could is very dependent on the first input being the one you want. eg they didn't add a checkbox or hidden input first in the markup.
Sorry for going on so long. Maybe just give some consideration to how vue could promote fully functional and accessible components out the box. I'm not great at accessibility, but anything that could help me remember to add better support for it I think is a good thing.
@qw3n regarding focus as a reactive attribute, give vue-focus a whirl. For components you would pass a :focused prop and use it in the directive within the component.
@simplesmiler that's pretty cool. I'll have to try it out.
On Nov 17, 2016 2:39 AM, Denis Karabaza [email protected] wrote:@qw3n regarding focus as a reactive prop, give vue-focus a whirl. For components you would just pass a :focused prop and use it in the directive within the component.
—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or mute the thread.
Actually, even if you don't have control over a 3rd party component, you can still do
this.$refs.someInput.$el.querySelector('input').focus()
from VScode: Property '$el' does not exist on type 'Vue | Element | Vue[] | Element[]
facing same issue.
any solution
Did you guys tried something like this?
const inputLogin = this.$refs.inputLogin as HTMLInputElement;
inputLogin.focus();
Most helpful comment
Why not just
this.$refs.name.focus()?