Home » vue » VueJS: are multiple Single file components each a vue instance or nested objects?

VueJS: are multiple Single file components each a vue instance or nested objects?

Posted by: admin November 26, 2021 Leave a comment

Questions:

In VueJS, are multiple Single file components (as parent-child), each a vue instance nested inside root instance? Why I’ve this assumption, is because each component can have the same properties i.e. data, methods, template, life-cycle hooks (mounted, created etc) akin to a root Vue instance or say like a vue instance in a non SFC setup.

To me it appears, any web-pack + vue-loader Single File Components setup are nested objects exported as JS objects and imported in parent component i.e. child is nested inside parent component which is nested inside a single root vue instance.

Basically, simply put there is only a single root instance and SFC are nested objects. As Sarah Drasner writes in the below linked css-tricks article:

You can have more than one instance in an application. Typically, we’ll have one instance and several components, as the instance is the main app. src

Can anybuddy shed more light on this as to which assertion is correct i.e SFC are each vue instances or they are nested objects inside a single root vue instance. If the latter turns out to be the correct case, why each can have lifecycle hooks akin to the root vue instance.

Technically, how does Vue make SFC act like separate Vue instances but still be nested objects inside a single root instance?

Thanks

Answers:

First of all, there is no difference between “single file components” and “global components” when it comes to their properties and lifecycle hooks. They only differ in how they are packaged, how they are referenced by other components and and how/where their HTML template is stored.

Secondly, all components, including the “root component” are Vue instances. If you look at the source code, you’ll see that the root instance is identified by the absence of any parents like this:

const isRoot = !vm.$parent

Have a look at this component tree from a Vue app using vue devtools:

enter image description here

Here is what the console shows:

> var root = $vm0
> var app = $vm0.$children[0]
> var link = $vm0.$children[0].$children[0]

// How they are named in vue dev tools
> link.$options._componentTag
< "router-link"
> app.$options.__file
< "src/App.vue"

// How the root instance is identified
> !root.$parent
< true
> !app.$parent
< false
> !link.$parent
< false

// Constructors
// Each component has its own class (or prototype), but they all extend the Vue base class
> Object.getPrototypeOf(root) === Object.getPrototypeOf(Object.getPrototypeOf(app))
< true
> Object.getPrototypeOf(root) === Object.getPrototypeOf(Object.getPrototypeOf(link))
< true

Therefore, components are both vue instances and nested objects inside a single root vue instance.