78 votes

A quoi sert Vue.extend ?

Il s'agit d'une question assez simple, mais je ne trouve pas la réponse dont j'ai besoin dans la documentation. Je suis en train d'apprendre Vue.js, et je ne comprends pas vraiment la place de Vue.extend. Je comprends Vue.component, mais je ne vois pas ce qu'est Vue.extend. Vue.extend fait ce qui suit Vue.component ne le fait pas. S'agit-il simplement d'une fonctionnalité héritée de la version 1.0 ? Si non, où est-elle utile dans Vue 2.0 ?

0 votes

62voto

jfxiao Points 33

Leur guide dans l'ancien site Vuejs.org avait un document.

Copié de http://optimizely.github.io/vuejs.org/guide/composition.html qui est bifurqué de vuejs/Vuejs.org à la version 0.10.6 de Vuejs.

Il est important de comprendre la différence entre Vue.extend() et Vue.component() . Puisque Vue est lui-même un constructeur, Vue.extend() est un méthode d'héritage de classe . Sa tâche consiste à créer une sous-classe de Vue et retourner le constructeur. Vue.component() d'autre part, est un enregistrement des actifs méthode similaire à Vue.directive() et Vue.filter() . Sa tâche consiste à d'associer un constructeur donné à une chaîne d'identification afin que Vue.js puisse dans les modèles. Lorsque vous passez directement des options à Vue.component() il appelle Vue.extend() sous le capot.

Vue.js prend en charge deux paradigmes d'API différents : celui basé sur les classes, impérative, de style Backbone, et l'API de style Composants Web, déclarative et basée sur les balises. Components. Si vous êtes confus, pensez à la façon dont vous pouvez créer un élément image avec new Image() ou avec un <img> tag. Chacune est utile en soi et Vue.js tente de fournir les deux pour une flexibilité maximale. un maximum de flexibilité.

33voto

GuyC Points 4193

Je pense que la confusion vient du fait que extend et component sont étroitement liés. Pour créer un composant, Vue appelle extend en interne :

// register an options object (automatically call Vue.extend)
Vue.component('my-component', { /* ... */ })

Vous pouvez donc utiliser extend pour monter une sous-classe du constructeur Vue de base (un constructeur de composant) : https://vuejs.org/v2/api/#Vue-extend

Toutefois, il est peu probable que vous ayez à emprunter cette voie. Vous utiliserez plutôt les composants pour obtenir des sous-classes nommées que vous pourrez facilement référencer dans votre application.

Par conséquent, Extend n'est pas vraiment une fonctionnalité "héritée", elle est centrale aux composants Vue, mais le sucre ajouté que les composants fournissent en fait la manière par défaut de travailler.

33voto

Mattias Martens Points 128

En plus des réponses fournies, il existe un cas d'utilisation pratique pour appeler Vue.extend() directement si vous utilisez TypeScript.

Dans la plupart des cas, il est recommandé d'importer les définitions de composants à partir d'autres fichiers lorsqu'elles sont nécessaires, au lieu de les enregistrer globalement avec la fonction Vue.component() . Il permet d'organiser les choses dans les grands projets et facilite le dépistage des problèmes.

Avec la bonne bibliothèque, TypeScript peut regarder votre définition de composant et déterminer quel sera le type du composant lorsqu'il sera initialisé, ce qui signifie qu'il peut ensuite vérifier les fonctions que vous avez définies pour voir si elles ont un sens (c'est-à-dire que si vous faites référence à this.foo il existe en fait une prop, un champ de données, une valeur calculée ou une méthode nommée foo ). Si vous utilisez Vue.component() il pourra le faire, mais pas si vous utilisez l'autre moyen typique de rendre les composants disponibles, à savoir l'exportation de littéraux d'objets.

Cependant, une autre option consiste à exporter vos définitions de composants enveloppées dans des fichiers Vue.extend() . TypeScript sera alors capable de le reconnaître comme un composant Vue et d'exécuter sa vérification de type en conséquence, mais vous n'aurez pas à abandonner le modèle de meilleure pratique consistant à exporter les composants plutôt que de les enregistrer globalement.

4 votes

Ceci est également utile lorsque vous n'utilisez pas TS, mais un IDE qui recherche les définitions de type pour l'intellisense.

2 votes

Merci. c'est exactement ce que je pensais mais vous l'avez expliqué plus clairement que la documentation.

2 votes

Je me suis battu avec ça pendant des heures quand Typescript se plaignait de this.$refs et je n'arrivais pas à comprendre pourquoi. Envelopper mon objet simple avec Vue.extend({ ..... }) a résolu le problème.

29voto

Mariusz Pawelski Points 857

La documentation de Vue v2 est un peu maigre sur Vue.extends mais en bref :

Vous utilisez Vue.extend pour créer un composant définition (appelé "constructeur de composant" dans l'ancienne documentation) et Vue.component à enregistrez afin qu'il puisse être utilisé dans le modèle pour créer le composant. 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'
})

Cependant, partout dans l'API Vue où vous pouvez passer le "constructeur de composant" créé par Vue.extend vous pouvez passer un objet simple à la place et il appellera Vue.extend pour vous .

L'exemple précédent peut donc être écrit comme suit

// define
var MyComponent = {
  template: '<div>A custom component!</div>'
}
// register
Vue.component('my-component', MyComponent)
// create a root instance
new Vue({
  el: '#example'
})

Il semble que les gens préfèrent maintenant définir les composants comme de simples objets JS (appelés objet options dans le monde de Vue).

Vous pouvez constater que dans la documentation actuelle de Vue v2, on voit rarement Vue.extends mentionné alors que dans les docs de la v1 il est clairement expliqué dans un des premiers chapitres qui décrit Instance Vue (comparer avec v2 ) et très bien expliqué dans Composants chapitre. Il est explicitement indiqué que le passage direct d'un objet d'options est juste un sucre .

Je pense que, pour rester simple et plus facile à apprendre, la nouvelle documentation utilise simplement des objets simples partout. Pourquoi expliquer des concepts supplémentaires tels que "Vue constructor function", "component constructor" et qu'est-ce que le "Vue constructor" ? Vue.extend alors que 99 % du temps, vous n'avez pas besoin de le comprendre ? Vous pouvez définir tous les composants de votre application à l'aide d'objets d'options JS et d'objets de type enregistrez sans utiliser Vue.extends . Le seul endroit où vous devez utiliser la fonction constructeur de vue est lors de la création de Instance racine de Vue avec new Vue({...}) . Cela utilise la base Vue fonction constructeur. Vous n'avez pas besoin de savoir que Le constructeur Vue peut être étendu pour créer des constructeurs de composants réutilisables avec des options prédéfinies. parce que Bien que vous puissiez créer des instances étendues de manière impérative, dans la plupart des cas, vous enregistrerez un constructeur de composant en tant qu'élément personnalisé et les composerez dans des modèles de manière déclarative. ( source )

Les auteurs de la documentation ont donc décidé que vous n'aviez pas besoin d'apprendre à connaître Vue.extends . Mais existe-t-il des cas d'utilisation où il est utile d'utiliser Vue.extend au lieu d'un simple options objet ?

Oui.

Tapuscrit

Si vous voulez utiliser Typescript (et que vous n'aimez pas style de classe ), alors pour avoir une inférence de type correcte, il faut devrait utiliser Vue.extend au lieu d'objets ordinaires. Il utilise ThisType<T> fonctionnalité pour obtenir une inférence appropriée pour this objet.

image showing code with Vue.extend function where we see it's recognized by Typescript

Héritage des composants (et encore Typescript)

Vous pouvez utiliser .extend pas seulement sur la base Vue mais aussi sur votre composant personnalisé. Ceci est moins flexible que mixins parce que vous pouvez utiliser de nombreux mixins dans les composants et les .extend Cette approche ne fonctionne qu'avec un seul composant. Toutefois, elle fonctionne mieux avec Typescript pour lequel les mixins semblent ne pas bien jouer . Avec .extend La prise en charge de Typescript est probablement "suffisante" dans de nombreux cas. Vous pouvez accéder aux champs d'un composant hérité, mais si votre composant a des noms en collision avec le composant "de base", cela ne fonctionne pas bien (par exemple, j'ai un type de never pour des noms d'accessoires contradictoires).

<div id="appBar">
    {{fooMessage}} || {{barMessage}} || {{ additionalData}}
    <button v-on:click="changeAllMessages">Change</button>
</div>

var FooComponent = Vue.extend({
    data: () => ({
        fooMessage: 'Foo message'
    }),
    methods: {
        changeFooMessage() {
            this.fooMessage = "Foo message changed";
        }
    }
})
var BarComponent = FooComponent.extend({
    data: () => ({
        barMessage: "Bar message",
    }),
    methods: {
        changeAllMessages() {
            this.barMessage = "Bar message changes";
            this.changeFooMessage();
        }
    }
});
new BarComponent({ el: "#appBar", data: { additionalData: "additional data passed" } });

Ici, j'ai également montré que vous pouvez utiliser votre composant personnalisé pour créer Instance racine de Vue ( new BarComponent({...}) ). Comme vous pouvez le faire avec new Vue({...}) . Peut-être que ce n'est pas très utile mais cela montre que BarComponent et FooComponent sont juste étendu base Vue et vous pouvez l'utiliser de la même manière que vous le feriez avec les fonctions du constructeur Vue .

3voto

JNN Points 23

Une façon simple de comprendre Vue.extend est qu'il crée un objet qui étend la classe Vue.

Typiquement, pour créer une nouvelle instance de Vue,

vm = new Vue( {/* ...*/})

Vue.extend crée également une instance de Vue ie

var page = Vue.extend ({ /* ... */}) ;

est autant une instance de Vue que vm ci-dessus.

Pour monter une page, vous devez la monter sur un div, c'est-à-dire, new page().$mount('#page-div')

Où #page-div est le I'd d'un div dans votre page

Aussi, pour les programmeurs ayant des connaissances en programmation orientée objet, disons que

var ext = Vue.extend({/ ... /})

Nous pouvons alors interpréter ext comme

classe ext extends Vue{

}

Notez que lorsque vous créez un composant, c'est-à-dire Vue.component('my-component', { /* ... / }), il fait en réalité ce qui suit : Vue.component('my-component', Vue.extend({ / ... */})), donc Vue.component appelle Vue.extend sous le capot.

Si vous ne savez toujours pas quoi faire, considérez Vue.extend comme une fonction utilitaire permettant de créer des composants.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X