Differences between vue instance and vue component? - vue.js

I'm new to vue js and have some questions when learning it.
I'm now a little confused about the relationship between its instance and component. As far as I learned, every app build by vue should only have one instance and one instance only, it can have as many components as you like if needed. But recently I've seen a demo, and in that demo it has more than one instance.
So my question is, is that ok to have multiple intances in one app( the demo code works fine, but is that the correct way)? What's the best practice to use instance and component in vue app?

It's ok to have two instances in the same project, however, you probably don't want to do that.
A good scenario is to have one main instance to control your app, specially if you are creating a Single Page Application (SPA). Then use as many components as you want.
Components are a great way to reuse code and keep it organized, and, with Vue.js, is very easy to communicate between your components and your "main" Vue instance.

It depends very much on your situation.
I work on a large web project which is not an SPA. We have a Vue instance for each "silo" of the application. We are slowly transitioning an older project from a mostly jQuery frontend so it's possible that as it evolves We'll be able to condense down to a single Vue instance but we're having no trouble with multiple instances. The ease of using Vue in existing projects was one of the biggest deciding factors in choosing it over another library such as react.
I have taken a different approach with green development, one instance and many components.

There are something in common, and some difference between Vue instance and Vue component.
From Vue docs:
all Vue components are also Vue instances, and so accept the same options object (except for a few root-specific options).
The root Vue instances accept properties like el, router, the Vue components cannot.
The data property in root Vue instances is an object, but in Vue components must be a function.
The design target is different:
A root Vue instance is a Vue application launcher, Vue component is an extension of the Vue instance.
Vue components can create elements to be reused in many places. This is Vue characteristic of componentization mainly reflect point.

Vue instance can associated with and manipulate an element which is already exist.
Vue component more suitable for create new element and reuse it at anywhere.

Think of a Vue Component as a blueprint or set of rules on how to create something that can be inserted into the DOM that the user can interact with.
So when you create a Vue file you are going to define exactly one component with a set of rules that tells Vue how to display stuff on the screen and tells a user how to interact with it.
On the other hand is a Vue instance, its an instance of a Vue component, it represents something that has been inserted into the DOM and is something that a user can interact with.
If you have a background in Object-Oriented Programming, think of a Vue Component as being like a class and a Vue instance as an instance of that class.

What has not been mentioned in previous answers that I will cover in regards to the difference between Vue instance and Vue component is how we define the data property that we are working with.
If we are working with a Vue instance, then we can define the data property as an object or a function that returns an object like so:
With a Vue Component that data property must be a function that returns an object.
So for example this is a Vue component:
export default {
name: "App",
components: {
SearchBar,
VideoList
},
And if we want to make use of data inside of that Vue component, we have to make a function that returns an object.

Vue components extends Vue instances
but Vue instances accept properties like el, router, the Vue components cannot.
best practice:
one Vue instance
many Vue component

Related

How to Access the Vue instance in the Script Tag Before the Export default, Nuxt.js

I would like to to access some properties from a plugin which was registered on my vue instance in the script tag, just before the export
Obviously i can't use the this keyword to refer to my vue instance from there, so how can I access the current vue instance?
it is not a best practice, but you can access the nuxt (so also the vue instance) with the
window.$nuxt
here you have everything you need, but you have to consider that if you're using nuxt in an SSR context, this does not work, since you cannot use the window object.

Attaching a vuex store from within a vue component

I'm having a situation where I use a specific Vue component in multiple ways. Sometimes I initialize it as an SPA with new Vue({store}) and sometimes I use it from within another vue component.
E.g.
<template>
<component/>
</template>
How would I go about attaching a vuex store to the component in the above situation? Manually overriding the $store property obviously does not work and the Vue instance itself doesn't really shed any light on the matter. Is there a way to achieve this?
I've written a simple store factory which creates a new instance of the vuex store but I need a way to attach this to a component from within a vue template/comp.
Said component is complex enough to warrant vuex.
Apparently setting the $store property manually does do the trick.
this.$store = store

Vue - Is it better to keep all props in one large mixin

I have a component library where i would like to standardize the props, component etc.
Thoughts on combining them props/methods/other mixins/etx into one larger mixin
All property names would be the same
Remove duplicated code on refactoring to adjust components from local props/methods/computed/ to "global"
Not all components would have need for every piece of data contained within the mixin - point 4
Would tree shaking remove the unused code on Rollup?
Is this a good idea?
If your component library is not constrained to using Vue 2 you might want to take a look at Vue Composition API to share functionality (methods + reactive state) between different components.
Mixins might not be what you really want to be using because you kind of lose information as to what features/props/methods really will be put inside your component without re-checking the mixin code. You also might run into issues when component options get merged by Vue at runtime. Check out these posts for more information:
https://css-tricks.com/how-the-vue-composition-api-replaces-vue-mixins/
https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
As for sharing props: What I've seen just yesterday (but not yet tried!) in a talk by John Leider - creator of Vuetify - is create a function that returns the props you want to reuse between components. Then you just call said function inside your props definition and use the spread operator.

Differences between Vue.component and new Vue?

Please tell me what are the differences between Vue.component and new Vue.
The second parameter of the Vue.component method ( the options object ), is the same first parameter of new Vue constructor. right?
Are there any differences between two methods, in meaning and parameter options?
Thanks
Let's introduce both of them first and we'll talk about the difference after it.
What is New Vue?
using new Vue we create a new vue instance; Every Vue application starts by creating a new Vue instance with the Vue function like following:
var vm = new Vue({
// you'r options here
})
According to official docs(this link):
A Vue application consists of a root Vue instance created with new Vue, optionally organized into a tree of nested, reusable components.
now that we know what vue instance is let's take a look at components.
What is Vue.component?
Components are reusable Vue instances with a name and we can use them as custom elements inside a root Vue instance
What are the differences?
Since components are reusable Vue instances, they accept the same options as new Vue, such as data, computed, watch, methods, and lifecycle hooks. The only exceptions are a few root-specific options like el.
A root Vue instance is a Vue application launcher, Vue component is an extension of the Vue instance.
Read this post for additional info.
When you call new Vue(), you're creating what is called a vue instance. A Vue instance basically is a JavaScript object that has some capabilities to interact with the DOM.
Vue components happen to be Vue instances, too. But the main difference is that components belong to other components/vue instances, while bare instances are mounted directly into an existing element of the DOM (with existing, I mean HTML that is not generated by Vue and existed previously to the instance creation).
So, basically, the main difference comes from the use: you usually create a bare Vue instance with new Vue when you need to attach that instance directly to the DOM as your root element. Vue components, on the other hand, are always attached to ** other components**.
In general, it is really common to have a single root vue instance in your Vue application, but you could have several bare instances in the same web page: you could get creative and span several Vue instances and make them interact with the DOM at the same time, as if they were components.
However, it is better to have a single root element with several components, since it is easier to reason about your code in that way, and also facilitates the use of plugins like Vuex or Vue-router.
Maybe this link about this matter can serve you as well.

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.