Table of Contents
URL: https://www.progressiverobot.com/vuejs-component-instancing/
If you have used Vue.js for any amount of time, or even read over the Hello World examples, you've probably wondered why on earth properties like "data" need to be functions, or why everything is declared in separate blocks, but mounted to the component at runtime. Well, here's your explanation.
Core Concepts
It turns out there is a very clear set of reasons for all of this. For one thing, Vue components are largely static! Yep! A component declaration, including its methods, property definitions, and computed properties, are shared between all instances of that component in the app. When Vue needs to run methods against a specific instance of a component, it <^>apply()*s them to get the the proper object as *this<^>.
Reason: Saving Memory
Many frameworks, such as <^>Angular 2<^> or, (at times) <^>React<^>, make each instance of a component a separate object. <^>Angular 2<^> [citation needed] being the extreme case where every component is an instance of a class. This means that everything each component needs is initialized for every component. Normally though, you really only need to keep a component's data separate for each initialization. Methods and such stay the same.
Vue avoids that pitfall by having <^>data<^> be a function that returns an object. That allows separate components to have separate internal state without needing to fully re-instantiate the entire component. Methods, computed property definitions, and lifecycle hooks are created and stored only once, and run against every instance of a component.
Reason: Static Components
Vue 2 fully embraces the idea of fast, lightweight static components. These have no internal state or data, and are generally rendered once or only on external state changes. This allows such functional components to be incredibly fast.
To take advantage of such features, you can use v-once in your templates to render a property only once, or declare your component to be functional with <^>functional: true<^> in the component definition.
Potential Confusion
It is often noticed by people new to Vue that while you declare your component state in <^>data<^>, computed properties in <^>computed<^>, methods in <^>methods<^>, they are all accessed on <^>this.thing<^> instead of <^>this.type.thing<^> (eg. <^>this.myMethod()<^> instead of <^>this.methods.myMethod()<^>.)
This, again, is because your component definition really is just a definition. The actual component your methods run in is different. Vue needs those <^>computed, methods, props, and data<^> definitions to be able to know how to assemble the component, but for convenience it maps them to the root of the component instead of those properties.
As a side note, you can actually access <^>this.$data.prop<^>, <^>this.$methods.method()<^>, at runtime, but this is not recommended.
Hopefully this article helps clear the matter up for you. 🙂