Differences between Vue.component and new Vue? - vue.js

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.

Related

Vue mount multiple applications vs using Teleport in loop

I'm writing a browser extension to add a check mark on multiple elements on the current page.
I want to build this check mark (and its own tooltip) with Vue.
Assume I have a document.querySelectorAll('selector for multiple') to attach my Vue component to it, I see two options:
Loop through the element, and for each, create a new App:
const div = document.createElement('div')
element.parentElement.insertBefore(div, element)
createApp(App).mount(div)
Mount the App once, and inside the App use Teleport to mount a component to each element:
<Teleport v-for="element in elements" :to="element">
<my-check-mark />
</Teleport>
I think the second option is better, since I'm using only one Vue engine, but Vue recommendation is to create multiple instances:
If you are using Vue to enhance server-rendered HTML and only need Vue to control specific parts of a large page, avoid mounting a single Vue application instance on the entire page. Instead, create multiple small application instances and mount them on the elements they are responsible for.
Why it is better?
Is it more efficient?

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.

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.

what is the right way or the vuejs way to data bind the entire page?

Coming from the knockoutJs background. If you don't specific the binding to an element. You can use the model to cover the whole page of elements. For example, i can make a div visible if a click event happened. I'm learning VueJs and from the documentation. I see the vue instance required you to speicif an element with el.
like this:
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
what if my button is not in the same div as the '#app' div. How do i communicate between two vue instance or can I use one vue instance to cover more than one element. what's the vuejs way?
It's very common to bind to the first element inside <body>. Vue won't let you bind to body, because there are all sorts of other things that put their event listeners on it.
If you do that, Vue is managing your whole page, and away you go. The docs cover the case where you have more than one Vue instance on a page, but I haven't come across this outside the docs, and I can't think of a good reason off the top of my head. More commonly, you will be constantly chopping bits out of your root Vue instance and refactoring them into "child" components. This is how you keep file sizes manageable and structure your app.
This is where a lot of folk needlessly complicate things, by over-using props to pass stuff to components. When you start refactoring into components, you will have a much easier time if you keep all your state in a store, outside vue, then have your components talk directly to your store. (put the store in the data element of all components). This pattern (MVVM) is fabulous, because many elements of state will end up having more than one representation on screen, and having a "single source of truth", normalized, with minimal relationships between items in the store, radically reduces the complexity and the amount of code for most common purposes. It lets you structure your app state independently of your DOM.
So, to answer your question, Vue instances (and vue components), don't need to (and shouldn't) talk much to each other. When they do need to (third party components and repeated components), you have props and events, refs and method calls (state outside the store), and the $parent and $root properties (usage frowned on!). You can also create an event bus. This page is a really good summary of the options.
Should your store be Flux/Redux? Vuex is the official implementation of the flux/redux pattern for vue. The common joke goes: when you realize you need it, it's too late. If you do decide to leave Vuex for now, don't just put state in Vue components. Use a plain javascript object in window scope. The right way is easier than the wrong way, and when you do transition to Vuex, your job will be much simpler. Your downstream references might be alright as they are.
Good luck. Enjoy the ride.
You usually put the main Vue instance on the first tag inside the body, then build the rest of your site within it. Everything directly inside that instance (not in a nested component) will have access to the same data.
You can then do this in your HTML:
<body>
<div id="#app">
<p v-if="showMessage">{{message}}</p>
<button v-on:click="showMessage = !showMessage"></button>
</div>
</body>
And set your data to something like this:
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
showMessage: true
}
})
If you want to pass data between components later on you'll have to look up how to emit events, use props, or possibly use Vuex if you got Vue running with the Vue-CLI (which I highly recommend).
If you want to reach tags (such as head tags) outside of the main Vue instance, then there are tools for that. For example you could try: https://github.com/ktquez/vue-head
I haven't tested it thought.

Differences between vue instance and vue component?

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