removing event listeners in Nuxt/Vue - vue.js

I'm on Nuxtjs 2.13 and i wanna know "how should I remove event listeners (is there a need??)".
I'm not talkinkg about js addEventListener and removeEventListener . I'm more curious about this.$emit() , $nuxt.$emit() and $nuxt.$on() . is there a way to remove $nuxt.$on() or listener on component <mycomp #myevent="do()" /> in beforeDestroy() and is it necessary?
as my Nuxt project using so much RAM on my server, i kindda think there are some optimization needed.

https://v3.vuejs.org/api/options-lifecycle-hooks.html#unmounted
When this hook (unmounted - OP) is called, all directives of the component instance have been unbound, all event listeners have been removed, and all child component instance have also been unmounted.
However, there is vm.$off which can
Remove custom event listener(s).
https://v2.vuejs.org/v2/api/#vm-off
I saw it used here in a Nuxt context to remove $nuxt.$on listeners:
https://medium.com/#aneesshameed/event-bus-in-nuxt-7728315e81b6
So, if need be, use $nuxt.$off to remove custom events in Nuxt.

Related

How can I remove manually added event listeners on beforeDestory hook of one component before redirecting to any another component, in Vuejs2?

I want to know the concept of the below thing-
I have created one component and set up its respected event listeners. Now, I want to remove those listeners on this component's beforeDestroy hook before redirecting to another route that will create another component.
but what I noticed is, beforeDestory hook of the first component is calling even after the second component's created hook.
I want to destroy the first component completely and then create another component.
// To set up the event listeners
created() {
this.EventBus.$on('myCustomEvent', payload => {
// some code here
)}
}
// To destroy the event listeners
beforeDestroy() {
this.EventBus.$off('myCustomEvent');
}
Any suggestions?
In search of an answer to your question, I came to the conclusion that it is better to refuse to use EventBus altogether.
Here is some information on this and some thoughts from there:
I have that feeling that having an EventBus in Vue is an anti-pattern, especially if you’re using VueX but I can’t quite put my finger on it. At the point you want to be sharing data like that, wouldn’t it be better to use a store to handle all of those “events” / “mutations”?
Also, looking at the solution to this issue, you are doing everything right and there is no other way.

can not get element by getElementById in beforeDestroy lifecycle vue

I use document.getElementById in beforeDestroy lifecycle to get an element. But getElementById returns null. If I use ref, I can get the element. Is there any difference between them? Why document.getElementById can't get the element?
There is an issue with the timing and there could be many reasons for that.
But in your case , The ref was still in the virtual DOM object, which will be destroyed within the destroy event (Unlike the document template).
That would be one reason Vue recommends to use $refs if possible.
I had the same problem. I thought the beforeDestroy hook was the right place to kill event listeners before leaving the component. For my surprise, when the route changes, the component is already unmounted when this hook is called.
This is vue.js version 2, I don’t know if it is better in version 3.

What is the difference between the beforeMount and the created lifecycle hook in vuejs

I am still unclear on where I should use the beforeMount and where the created lifecycle hook. It seems to me that in both, the reactive data has been loaded and it is before the DOM has been mounted.
In most cases it doesn't matter whether you use beforeMount or created but there are some where it matters:
Accessing original DOM element your root Vue component is mounting on
can be useful for integration with any server-side rendered framework (php, rails etc.)
explanation and example - When to use the lifecycle method beforeMount in vue.js?
in created hook this.$el is undefined, in beforeMount it's the original unmodified element, in mounted it's root element created by your component/template
Server-side rendering (Nuxt, Vuepress etc.)
docs
beforeCreate and created are only hooks called on the server
that means you should not use any code which needs window, document or any browser API in created as those will not be present on the server
on the other hand code placed in the beforeMount (or mounted) is executed only on the client (browser)
The beforeMount hook runs right before the initial render happens and after the template or render functions have been compiled(when vm.$el has not been created yet).
created is the step after initialization of your component(where you are able to access reactive data and events that are active with the created hook. Templates and Virtual DOM have not yet been mounted or rendered)

Vue Single page app Router, what happens with the components when we change route?

Let's suppose I have a component called FirstPage, which is my default route, now FirstPage triggers an asynchronous call, with the help of an action of the vuex store, to be made each minute to a backend Api (it's triggered when the component is loaded as a route), now let's say I go to an about route that goes to an About component, is FirstPage still making the calls?
Edit:
I'm not developing an app with that yet, so I can't provide examples.
It's on my interest to know the behavior in these cases of the router, because whenever I change the route I would want to stop making the constant calls (as they won't be necessary).
The reason is that Depending on this I'd have to switch tooling for a project I have in mind.
In general, a component's instance will be destroyed when you navigate away from it. However, there are two exceptions to this ..
When you use routes with params. From the Vue Router docs
One thing to note when using routes with params is that when the user navigates from /user/foo to /user/bar, the same component instance will be reused. Since both routes render the same component, this is more efficient than destroying the old instance and then creating a new one. However, this also means that the lifecycle hooks of the component will not be called.
When you wrap your router-view component within a keep-alive element. Since the <router-view> is essentially a dynamic component.
Generally Vue does a very good job of housekeeping and cleaning up after a component's instance when it gets destroyed. But sometimes you'll have to do some manual cleanup, especially if you use some kind of external library. This is usually handled in the beforeDestroy hook of an instance's lifecycle.
In normal conditions, any logic/scripts/etc done at creation inside said component will be "purged" on the on destroy/close hooks (not only pertinent to vue but seen in lots of other tools), if there is a need to persist something then it should be in a higher scope (or other solution)
Any script written for the respective component only runs if the component is rendered in page. Once you go to about component replacing the previous component then previous script wont run.
you can make a parent component with a router-view and load in your page you always want to get loaded, so your FirstPage component, but this component should just have logic behind it, and no html because otherwise you will always see that rendered. Router-view the page you want to display the real html and stuff. I hope you get the idea, if not i could make an example for you. Goodluck.

Vue.js router-view mounted callback

I'm using Vue.js with Vue-router in a project and I'm trying to have a callback whenever the routed-to component is ready. Usually you would do it inside each component in the mounted() hook, but for this case I want it for every component that has been routed to.
I tried with router.OnReady() and router.afterEach() but it did not work since they happen after routing but before the component is mounted. I also tried changing the vue-router source code adding mounted() to the router-view component, but it's not getting called.
There is no on-router event for this but according to this issue you can get around this by using Vue.nextTick inside router.afterEach.