Vuejs2: Resend the event for ENTER key - vuejs2

When in a custom component, I can re-emit click events as #click="$emit('click'). Later in the parent, I can directly react to #click without having to create a custom event:
<!-- In the Parent -->
<custom-component #click="myReaction" ... />
How can I re-emit the event for #keyup so that I can specifically listen for ENTER via #keyup.enter="myReaction" in the parent? Should it be #keyup="$emit('keyup')?

It should be #keyup="$emit('keyup', $event)" or otherwise you won't be able to get the key code.
You can also rely on the event bubbling for standard DOM events and just use #keyup.native.enter="myReaction" in your parent component.

Related

Use $emit without a click event

I'm new to Vue and there are some things I didn't understand yet.
In the first child there's a click event to $emit information to the next child. But in the other one, the second child, is there anyway to pass the information to the next child using $emit without a click event or any other event (like scroll, hover etc)? I just want to pass it ahead. Can I use mounted()?
Yes! What you're looking for is $emit(), in combination with the v-on directive, both of which it sounds like you're already using.
In the child component that you mention, the lowest one on the chain, you're already capturing a click event from some component, and then presumably using $emit('my-event', [...some data...]) to emit a new event out from the child component itself.
All you need to do now is to add event listeners and handlers in the components up the chain, using Vue's custom events mechanic, so that they can receive and emit their own events, and the data can make it up to the parent. Custom events allow your components to emit and listen for events of any name, which may carry any data they'd like (this means they're not limited to being click/ hover/ blur/ etc.).
Here's the step-by-step of that approach:
(Structure: Parent <--> Child #1 <--> Child #2 <--> Child #3)
Child #3 captures a click event, and emits an event in its handler
Child #2 is listening for this event on #3, captures it, and $emits its own event in its handler
Child #1 is listening for this event on #2, captures it, and emits own event in its handler
Parent captures event, and executes handler
In code, you'll have a listener and handler in each of your components, which can look something like this:
(I've used inline handlers here for brevity, but you can use defined methods as handlers too, just call this.$emit(...) from the method.)
Child #3:
<component ... #click="$emit('my-event-a', $event)" />
Child #2:
<ChildComponent3 ... #my-event-a="$emit('my-event-b', $event)" />
Child #1:
<ChildComponent2 ... #my-event-b="$emit('my-event-c', $event)" />
Parent:
<ChildComponent1 ... #my-event-c="myHandler" />
$event here is just special Vue syntax for referencing the event data in an inline handler, which in this case allows your new event to contain the same data.
The events in the various child components can be named whatever you'd like, just make sure that the respective listeners are listening for the correct event name (eg. #event-x="..." for $emit('event-x') and #pizza-eaten="..." for $emit('pizza-eaten')).
I also wanted to mention that passing the event object (or any data at all) with an emitted event is completely optional. To do so, just invoke $emit with the event name and no other arguments: $emit('my-event'). This is useful when you simply care that an event has occurred, and the handler requires no further info.
There are many ways to approach this problem, but this is the most straightforward to understand, and works great as long as you don't need tons of direct interaction between a component and its deeply nested children.
If you do find your component structure getting more complicated, then you may want to look into a fully realized state management solution, like Vuex, which allows your components to interact with a state manager rather than having to deal with tons of events through a complicated component structure.

Why does Vue's v-model update the data much more later after the click event was fired?

I have a very small checkbox component which I was trying to listen to via the #click event. But the v-model data updates 7ms later than the event callback. So I had to remove the #click listener and to add a computed property/method of the checked value and add a watch method for it to $emit the updated checked value. It works fine this way. But I just want to understand what's going behind the scenes. Can someone explain? Or maybe reference to a good resource on the net?
I also couldn't find the v-model methods in the Vue's source code. Where can I find v-model related code in the node_modules?
You should try using #change instead and then print it for testing. For Example:
<input
type="checkbox"
v-model="item"
#change="sendEvent"
/>
sendEvent () {
this.$emit('click', this.item);
},

unable to access child component $refs inside b-modal

I am attempting to access a child component's $refs inside a b-modal.
On page load, I can see with vue dev tools that "agent-edit" has not been created. If I put the component outside of b-modal, it does show and I can access it -- however I need this to load inside a modal. How can I access $refs.editAgent? Can I force this child component to load with the page?
<b-modal id="editModal" ref="editModal" title="Edit Agent" size="lg">
<agent-edit ref="editAgent"></agent-edit>
<div slot="modal-footer" class="w-100"></div>
</b-modal>
Refs are relative to the component they are created in (not the child components)
// use this
this.$refs.editAgent
// Not this
this.$refs.editModal.$refs.editAgent
Note that b-modal is lazy by default, meaning the content is not rendered (instantiated) in the document until the modal is shown.
Once the modal is finished opening, you should have access to the refs (they don't exist until they are rendered into the DOM)
Listen for the modal's shown event, and then access the refs once that event is emitted.
I guess, that there is no <agent-edit> inside <b-modal>, when you try to call the method.
When the modal is hidden, there is no need to render the child components. Try to first show the modal and then access its children (maybe even with a Vue.$nextTick to make sure everything is finished).
In your case, this.$refs.editModal.$refs.editAgent should work.
But pay attemption to the use of $refs and think about emitting events.

VueJS 2 - Default click event on component

Is it possible in VueJS to have a default click event on a custom component?
E.g. we have built a component called editable. Now on click, we always want it to fire the same function, no matter where we call that component.
<editable #click="doSomething" ...></editable>
Can I define that somewhere in the JS side?
In case of custom component, you need to bind to native event:
<editable #click.native="doSomething" ...></editable>
For documentation, refer to Vue.js docs here.

Why VueJs introduce .native Event modifier ? What are the use case of this? - Vue.js

I din't get any docs for native event modifiers. I have seen some where like this:
<router-link #click.native="pressThis()"> Press here </router-link>
what is the use of native modifier on router-link click event.
and what other use case native modifier can have ?
You can override Vue events in custom components. For instance, you might have a list component that once you click an item you call this.$emit('click', selectedItemData), and that will emit the click event to the parent component that is watching that.
However, sometimes you really want to bind to the native HTML/DOM event listener element.addEventListener('click', callThisMethod), and that's the use of .native. Also, make a note that it will handle cleaning the event listener once your component gets destroyed just like a non-native event.
In sum: use .native when you need the 'raw' event from DOM.