What is the difference between the beforeMount and the created lifecycle hook in vuejs - vue.js

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)

Related

Nuxt 2.14: wait until everything inside `fetch` will be done

I have a question. Inside Nuxt's fetch hook I have some asynchronous calls that are performed by Nuxt content API.
Some pieces of this data are then used inside mounted hook.
But while Nuxt handles first request inside fetch, the control flow passes to the mounted hook and hence there's no needed data.
Yes, I tried uses something like if (!this.$fetchState.pending) return; but obviously mounted is called only once. Does anybody knows how can I force Nuxt to wait? Btw, the app is using static site generation and the component has property fetchOnServer set to false.

setup() vs onMounted(),I need display a data when the page loads initialy...,where should i write the code for fetching the data form server (vuejs)

In options api,its obvious where we write code for fetching the data from server in mounted method.
With composition api,i am confused as the setup method is the one that loads first before the onMounted hook.
Check their docs: https://vuejs.org/guide/essentials/lifecycle.html#lifecycle-diagram
If you are doing DOM related actions, you would want to do it in onMounted() hooks, because setup() doesn't have access to DOM yet.
So I would probably do it in onMounted() methods since I would probably store result from API to component data or may update DOM as a side-effect.

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.

How can I fire component specific events from within a class in a Vue component?

I am trying to integrate Fine Uploader in my project which is built on Laravel & Vue. This project has a lot of legacy code that I have to support (such as old CSS classes, etc.) so I need to integrate Fine Uploader as a JS plugin, and can't use any existing 3rd party Vue Fine Uploader components that may be out there.
I've managed to get it to work for the most part. However, here is the challenge that I present to you. Below, you can see a screenshot of my code, in which I am instantiating the Fine Uploader instance inside my mounted hook.
As you can see I have highlighted the part of the code where I would emit an event when a new file is submitted for uploading. Here however, since I am inside the Fine Uploader instance, when I do this.$emit, it doesn't work (as it shouldn't).
I tried to circumvent this by using a global eventBus. This worked, but created issues when several files are dropped into the uploader at once. The event fires multiple times and often loses track of which event was fired by which instance, thus causing the 'thumbnails component' to perform duplicate actions.
I am convinced that I need to fire 'component-specific' events so that the thumbnail components that are generated and updated (onProgress and onComplete) only take their relevant actions once.
How can I fire component specific events from within another class instantiation?
Thank you.
Your function callbacks don't have their contexts bound, so this inside the callback does not refer to the Vue instance (which would result in $emit being undefined).
There are a few different solutions:
Use an arrow-function:
onSubmitted: (id, name) => {
// `this` is Vue instance
}
Bind the function context with Function#bind:
onSubmitted: function(id, name) {
// `this` is Vue instance
}.bind(this)
Use a cached reference to the Vue instance:
const vm = this;
const f = new qq.FineUploaderBasic({
// ...
onSubmitted: function(id, name) {
vm.$emit(...)
}
})

Does $destroy function removes the Vue Custom component from cache

I construct deep nested tree of parent and children Vue custom components using my top level component dynamically and then I am updating the data from which all tree is constructed. Which has an effect of rendering the entire tree (its a form with various custom components). I refresh/rebuild the whole form after fetching the data (which is what vue do for reactive data) that itself tell me how to regenerate the view (its like a JSON Schema from which I render the entire view).
This is related to my other issue here.
I am observing a very weird behavior in my Vue Application. When I destroy all my children components and rebuild the data to force rendering the form, it appears that even after I have called $destroy on every child component...Vue is not entirely removing them from cache?
Does vue remove the component from cache if a $destroy is called ?
Because I do not see multiple components of the same type in the Vue component list in the Chrome Vue DevTool extension panel. But I see that the same custom event is handled twice by the same component. Same function that handle the events is getting called twice even though there is only one component visible in Vue DevTools of this type.
This only happens after I render the form. When the page is loaded for the first time every thing works. Then after I reset the form by destroying the child component and resetting the data to re-render the form, magically this child component start handling the event twice.. and in 3rd render it handle the events thrice. But I see only one component in google chrome VueJS DevTool extension panel. So my guess is that vue is still keeping the previously destroyed component in cache. I am trying to figure out how should I destroy those components in the cache.
If anyone has observed something similar and found a solution please let me know.
At the moment I am going to dig little bit more on my component keys (this particular component does not have explicit key set by me).
First and foremost, the vue documentation states:
vm.$destroy
In normal use cases you shouldn’t have to call this method yourself.
Prefer controlling the lifecycle of child components in a data-driven
fashion using v-if and v-for.
So instead of destroying and rebuilding the components manually yourself, you should really letting vue handle that via v-if and v-for. If the components aren't updating to your changes, you might be dealing with a reactivity issue.
As you mentioned that this is a deeply nested structure, the reactivity is key to keeping the components up to data with the data.
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object using the Vue.set(object, key, value) method:
Vue.set(vm.someObject, 'b', 2)
Inside of a component:
this.$set(this.someObject, 'b', 2)
Also, keep in mind that Vue should be doing the heavy lifting in regards to component management, while you should define the parameters by which a component is rendered.