Reputation: 481
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
Upvotes: 0
Views: 701
Reputation: 10390
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:
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.
Upvotes: 2