This is a simple enough one, but I'm not getting the answer I need from the documentation. I'm in the process of learning Vue.js, and I don't really understand where Vue.extend fits in. I get Vue.component, but I don't see what Vue.extend does which Vue.component doesn't. Is it just a legacy feature from 1.0? If not, where is it useful in Vue 2.0?
5 Answers
Their guide in the previous Vuejs.org site had a document.
Copied from which is forked from vuejs/Vuejs.org at version 0.10.6 of Vuejs.
It is important to understand the difference between
Vue.extend()andVue.component(). SinceVueitself is a constructor,Vue.extend()is a class inheritance method. Its task is to create a sub-class ofVueand return the constructor.Vue.component(), on the other hand, is an asset registration method similar toVue.directive()andVue.filter(). Its task is to associate a given constructor with a string ID so Vue.js can pick it up in templates. When directly passing in options toVue.component(), it callsVue.extend()under the hood.Vue.js supports two different API paradigms: the class-based, imperative, Backbone style API, and the markup-based, declarative, Web Components style API. If you are confused, think about how you can create an image element with
new Image(), or with an<img>tag. Each is useful in its own right and Vue.js tries to provide both for maximum flexibility.
In addition to the answers provided, there is a practical use case for calling Vue.extend() directly if you are using TypeScript.
It is recommended in most cases to import component definitions from other files when they are needed, instead of registering them globally with Vue.component(). It keeps things organized in larger projects and makes it easier to trace problems.
With the right library, TypeScript can look at your component definition and figure out what the type of the component will be when it's initialized, meaning it can then check the functions you've defined to see if they make sense (i.e. if you reference this.foo there is actually a prop, data field, computed value, or method named foo). If you use Vue.component() it will be able to do this, but not if you use the other typical way of making components available, which is exporting object literals.
However, another option is to export your component definitions wrapped in Vue.extend(). TypeScript will then be able to recognize it as a Vue component and run its type checking accordingly, but you won't have to abandon the best-practice pattern of exporting components rather than registering them globally.
The documentation for Vue v2 is a bit sparse on Vue.extends but in short:
You use Vue.extend to create component definition (called "component constructor" in old documentation) and Vue.component to register it so it can be used in template to actually create component instance.
<div id="example">
<my-component></my-component>
</div>
// define
var MyComponent = Vue.extend({
template: '<div>A custom component!</div>'
})
// register
Vue.component('my-component', MyComponent)
// create a root instance
new Vue({
el: '#example'
})
However, everywhere in Vue API where you can pass "component constructor" created by Vue.extend you can pass plain object instead and it will call Vue.extend for you.
So the previous example can be written as
// define
var MyComponent = {
template: '<div>A custom component!</div>'
}
// register
Vue.component('my-component', MyComponent)
// create a root instance
new Vue({
el: '#example'
})
It seams that people now prefer to define components just as plain JS object (called options object in Vue world).
You can see that in current documentation for Vue v2 you rarely see Vue.extends mentioned while in docs for v1 it is clearly explained in one of the first chapters that describes Vue Instance (compare it with v2) and very well explained in Components chapter. It is explicitly stated that passing options object directly is just a sugar.
My guess is, to keep it simple and easier to learn, the new documentation just use plain objects everywhere. Why explain additional concept like "Vue constructor function", "component constructor" and what is Vue.extend when 99% of time you don't need to understand it? You can define all your app's components with plain JS options objects and register them without using Vue.extends. The only place when you must use vue constructor function is when creating root Vue instance with new Vue({...}). This uses base Vue constructor function. You don't need to know that Vue constructor can be extended to create reusable component constructors with pre-defined options because although you can create extended instances imperatively, in most cases you will be registering a component constructor as a custom element and composing them in templates declaratively.(source)
So documentation authors decided you don't need to learn about Vue.extends. But are there any use case where it's worth to use Vue.extend instead of plain options object?
Yes.
Typescript
If you want to use Typescript (and don't like class-style components) then to have proper type inference you should use Vue.extend instead of plain objects. It uses ThisType<T> feature to get proper inference for this object.