diff --git a/src/v2/guide/components-edge-cases.md b/src/v2/guide/components-edge-cases.md index 9126a51722..9c180c05c1 100644 --- a/src/v2/guide/components-edge-cases.md +++ b/src/v2/guide/components-edge-cases.md @@ -1,61 +1,61 @@ --- -title: Handling Edge Cases +title: Gérer les cas limites type: guide order: 106 --- -> This page assumes you've already read the [Components Basics](components.html). Read that first if you are new to components. +> Cette page présume que vous connaissez déjà les bases sur les [Composants](components.html). Lisez cette section en premier si vous découvrez les composants. -

All the features on this page document the handling of edge cases, meaning unusual situations that sometimes require bending Vue's rules a little. Note however, that they all have disadvantages or situations where they could be dangerous. These are noted in each case, so keep them in mind when deciding to use each feature.

+

Toutes les fonctionnalités sur cette page documentent la gestion de cas limites, c'est-à-dire des situations peu ordinaires qui requièrent parfois de contourner légèrement les règles de Vue. Notez cependant qu'elles ont toutes des inconvénients ou des situations où elles peuvent s'avérer dangereuses. Celles-si sont décrites dans chaque cas, donc gardez-les en tête quand vous décidez d'utiliser chaque fonctionnalité.

-## Element & Component Access +## Élément et accès au composant -

Cette page est en cours de traduction mais vous pouvez en trouver une ancienne version ici. Pour nous aider, vous pouvez participer sur le dépôt GitHub dédié de Vuejs-FR.

In most cases, it's best to avoid reaching into other component instances or manually manipulating DOM elements. There are cases, however, when it can be appropriate.

+Dans la plupart des cas, il vaut mieux éviter d'accéder à d'autres instances de composant ou de manipuler manuellement des éléments du DOM. Cependant, il y a des cas où cela peut être approprié. -### Accessing the Root Instance +### Accéder à l'instance racine -In every subcomponent of a `new Vue` instance, this root instance can be accessed with the `$root` property. For example, in this root instance: +Dans chaque sous-composant d'une nouvelle instance de Vue (`new Vue`), on peut accéder à cette instance racine via la propriété `$root`. Par exemple, dans cette instance racine : ```js -// The root Vue instance +// l'instance Vue racine new Vue({ data: { foo: 1 }, computed: { bar: function () { /* ... */ } - } + }, methods: { baz: function () { /* ... */ } } }) ``` -All subcomponents will now be able to access this instance and use it as a global store: +Tous les sous-composants pourront accéder à cette instance et l'utiliser comme un espace de stockage global : ```js -// Get root data +// Récupérer une donnée de la racine this.$root.foo -// Set root data +// Affecter une donnée de la racine this.$root.foo = 2 -// Access root computed properties +// Accéder aux propriétés calculées de la racine this.$root.bar -// Call root methods +// Appeler des méthodes de la racine this.$root.baz() ``` -

This can be convenient for demos or very small apps with a handful of components. However, the pattern does not scale well to medium or large-scale applications, so we strongly recommend using Vuex to manage state in most cases.

+

Cela peut être pratique pour des démos ou des applications très petites avec une poignée de composants. Cependant, ce pattern se prête mal aux applications de moyenne à grande échelle, c'est pourquoi nous recommandons fortement d'utiliser Vuex pour gérer l'état dans la plupart des cas.

-### Accessing the Parent Component Instance +### Accéder à l'instance de composant parente -Similar to `$root`, the `$parent` property can be used to access the parent instance from a child. This can be tempting to reach for as a lazy alternative to passing data with a prop. +Comme `$root`, la propriété `$parent` peut être utilisée pour accéder à l'instance parente à partir d'un enfant. Il peut être tentant de l'utiliser par fainéantise plutôt que de passer les données via une prop. -

In most cases, reaching into the parent makes your application more difficult to debug and understand, especially if you mutate data in the parent. When looking at that component later, it will be very difficult to figure out where that mutation came from.

+

Dans la plupart des cas, accéder au parent rend votre application plus difficile à déboguer et à comprendre, surtout si vous mutez des données dans le parent. En regardant ce composant plus tard, il sera très difficile de découvrir d'où vient cette mutation.

-There are cases however, particularly shared component libraries, when this _might_ be appropriate. For example, in abstract components that interact with JavaScript APIs instead of rendering HTML, like these hypothetical Google Maps components: +Il y a des cas cependant où cela _pourrait_ être approprié, notamment dans des bibliothèques de composants liés entre eux. Par exemple, dans des composants abstraits qui interagissent avec des APIs JavaScript plutôt que de produire du HTML, tels que ces composants Google Maps : ```html @@ -63,9 +63,9 @@ There are cases however, particularly shared component libraries, when this _mig ``` -The `` component might define a `map` property that all subcomponents need access to. In this case `` might want to access that map with something like `this.$parent.getMap`, in order to add a set of markers to it. You can see this pattern [in action here](https://jsfiddle.net/chrisvfritz/ttzutdxh/). +Le composant `` peut définir une propriété `map` à laquelle tous les sous-composants ont besoin d'accéder. Dans ce cas, `` peut vouloir accéder à cette carte avec quelque-chose comme `this.$parent.getMap`, afin d'ajouter des marqueurs dessus. Vous pouvez voir ce pattern [en démonstration ici](https://jsfiddle.net/chrisvfritz/ttzutdxh/). -Keep in mind, however, that components built with this pattern are still inherently fragile. For example, imagine we add a new `` component and when `` appears within that, it should only render markers that fall within that region: +Gardez en tête, toutefois, que les composants conçus avec ce pattern sont toujours intrinsèquement fragiles. Par exemple, imaginons que nous ajoutons un nouveau composant `` et que lorsque `` apparaît à l'intérieur, il affiche uniquement les marqueurs de cette région : ```html @@ -75,58 +75,58 @@ Keep in mind, however, that components built with this pattern are still inheren ``` -Then inside `` you might find yourself reaching for a hack like this: +Alors, à l'intérieur de ``, vous pourriez vous retrouver à devoir recourir à des bricolages comme ceci: ```js var map = this.$parent.map || this.$parent.$parent.map ``` -This has quickly gotten out of hand. That's why to provide context information to descendent components arbitrarily deep, we instead recommend [dependency injection](#Dependency-Injection). +Cela a rapidement mal tourné. C'est pourquoi nous recommandons plutôt d'utiliser l'[injection de dépendances](#Dependency-Injection) pour fournir des informations contextuelles à des composants enfants à un niveau de profondeur arbitraire. -### Accessing Child Component Instances & Child Elements +### Accéder à des instances de composants enfants et des éléments enfants -Despite the existence of props and events, sometimes you might still need to directly access a child component in JavaScript. To achieve this you can assign a reference ID to the child component using the `ref` attribute. For example: +Malgré l'existence des props et des événements, parfois vous pouvez toujours avoir besoin d'accéder directement à un composant enfant en JavaScript. Pour y parvenir, vous pouvez assigner un ID référence au composant enfant en utilisant l'attribut `ref`. Par exemple : ```html ``` -Now in the component where you've defined this `ref`, you can use: +Ensuite, dans le composant où vous avez défini cette `ref`, vous pouvez utiliser : ```js this.$refs.usernameInput ``` -to access the `` instance. This may be useful when you want to, for example, programmatically focus this input from a parent. In that case, the `` component may similarly use a `ref` to provide access to specific elements inside it, such as: +pour accéder à l'instance ``. Cela peut être utile si vous voulez, par exemple, donner programmatiquement le focus à ce champ depuis le parent. Dans ce cas, le composant `` peut de la même façon utiliser une `ref` pour fournir l'accès à des éléments spécifiques à l'intérieur, tels que : ```html ``` -And even define methods for use by the parent: +Et même définir des méthodes à utiliser par le parent : ```js methods: { - // Used to focus the input from the parent + // utilisé pour mettre le focus sur ce champ à partir du parent focus: function () { this.$refs.input.focus() } } ``` -Thus allowing the parent component to focus the input inside `` with: +Et ainsi permettre au composant parent de mettre le focus sur le champ à l'intérieur de `` avec : ```js this.$refs.usernameInput.focus() ``` -When `ref` is used together with `v-for`, the ref you get will be an array containing the child components mirroring the data source. +Quand `ref` est utilisé conjointement avec `v-for`, la ref que vous obtenez sera un `Array` contenant les composants enfants reflétant les données source. -

$refs are only populated after the component has been rendered, and they are not reactive. It is only meant as an escape hatch for direct child manipulation - you should avoid accessing $refs from within templates or computed properties.

+

Les références $refs sont renseignées seulement après le rendu initial du composant, et elles ne sont pas réactives. Il s'agit seulement d'une trappe de sortie pour faire de la manipulation directe d'enfants - vous devriez éviter d'accéder aux $refs depuis l'intérieur de templates ou depuis des propriétés calculées.

-### Dependency Injection +### Injection de dépendances -Earlier, when we described [Accessing the Parent Component Instance](#Accessing-the-Parent-Component-Instance), we showed an example like this: +Précédemment, quand nous avons décrit l'[accès à l'instance de composant parente](#Acceder-a-l’instance-de-composant-parente), nous avons montré un exemple comme ceci : ```html @@ -136,9 +136,9 @@ Earlier, when we described [Accessing the Parent Component Instance](#Accessing- ``` -In this component, all descendants of `` needed access to a `getMap` method, in order to know which map to interact with. Unfortunately, using the `$parent` property didn't scale well to more deeply nested components. That's where dependency injection can be useful, using two new instance options: `provide` and `inject`. +Dans ce composant, tous les descendants de `` avaient besoin d'accéder à une méthode `getMap`, afin de savoir avec quelle carte interagir. Malheusement, utiliser la propriété `$parent` s'adapte mal avec des composants imbriqués plus profondément. C'est là où l'injection de dépendances peut s'avérer utile, en utilisant deux nouvelles options d'instance : `provide` et `inject`. -The `provide` options allows us to specify the data/methods we want to **provide** to descendent components. In this case, that's the `getMap` method inside ``: +Les options `provide` nous permettent de spécifier quelles données/méthodes nous voulons **fournir** aux composants descendants. Dans ce cas, il s'agit de la méthode `getMap` à l'intérieur de ``: ```js provide: function () { @@ -148,56 +148,56 @@ provide: function () { } ``` -Then in any descendants, we can use the `inject` option to receive specific properties we'd like to add to that instance: +Ensuite, dans n'importe quel descendant, nous pouvons utiliser l'option `inject` pour récupérer des propriétés spécifiques que nous voulons ajouter à cette instance : ```js inject: ['getMap'] ``` -You can see the [full example here](https://jsfiddle.net/chrisvfritz/tdv8dt3s/). The advantage over using `$parent` is that we can access `getMap` in _any_ descendant component, without exposing the entire instance of ``. This allows us to more safely keep developing that component, without fear that we might change/remove something that a child component is relying on. The interface between these components remains clearly defined, just as with `props`. +Vous pouvez voir l'[exemple complet ici](https://jsfiddle.net/chrisvfritz/tdv8dt3s/). L'avantage par rapport à `$parent` est que nous pouvons accéder à `getMap` dans _n'importe quel_ composant descendant, sans avoir à exposer l'instance entière de ``. Cela nous permet de continuer à développer ce composant de façon plus sûre, sans crainte de devoir changer/supprimer quelque-chose sur lequel repose un composant enfant. L'interface entre ces composants reste clairement définie, tout comme avec les `props`. -In fact, you can think of dependency injection as sort of "long-range props", except: +En fait, vous pouvez vous représenter l'injection de dépendances comme une sorte de « props à longue distance », sauf que : -* ancestor components don't need to know which descendants use the properties it provides -* descendant components don't know need to know where injected properties are coming from +* les composants ancêtres n'ont pas besoin de connaître quels descendants utilisent les propriétés qu'ils fournissent +* les composants descendants n'ont pas besoin de savoir d'où proviennent les propriétés injectées -

However, there are downsides to dependency injection. It couples components in your application to the way they're currently organized, making refactoring more difficult. Provided properties are also not reactive. This is by design, because using them to create a central data store scales just as poorly as using $root for the same purpose. If the properties you want to share are specific to your app, rather than generic, or if you ever want to update provided data inside ancestors, then that's a good sign that you probably need a real state management solution like Vuex instead.

+

Cependant, il y a des inconvénents à l'injection de dépendances. Cela vient entériner la manière dont les composants sont actuellement organisés dans votre application, rendant plus difficile le remaniement de code. De plus, les propriétés fournies avec `provide` ne sont pas réactives. Cela a été intentionnellement conçu de cette façon, car les utiliser pour créer un espace de stockage global est tout aussi peu évolutif que d'utiliser $root dans le même but. Si les propriétés que vous voulez partager sont spécifiques à votre application et non génériques, ou si jamais vous voulez mettre à jour des données fournies par des ancêtres, alors c'est un signe que vous avez probablement besoin d'une réelle solution de gestion d'état telle que Vuex à la place.

-Learn more about dependency injection in [the API doc](https://vuejs.org/v2/api/#provide-inject). +Apprenez-en plus sur l'injection de dépendances dans [la documentation de l'API](https://vuejs.org/v2/api/#provide-inject). -## Programmatic Event Listeners +## Écouteurs d'événements programmatiques -So far, you've seen uses of `$emit`, listened to with `v-on`, but Vue instances also offer other methods in its events interface. We can: +Jusqu'à présent, vous avez vu des utilisations de `$emit`, écoutés avec `v-on`, mais les instances de Vue proposent aussi d'autres méthodes dans leur interface d'événements. Nous pouvons : -- Listen for an event with `$on(eventName, eventHandler)` -- Listen for an event only once with `$once(eventName, eventHandler)` -- Stop listening for an event with `$off(eventName, eventHandler)` +- Écouter un événement avec `$on(eventName, eventHandler)` +- Écouter un événement une seule fois avec `$once(eventName, eventHandler)` +- Arrêter d'écouter un événement avec `$off(eventName, eventHandler)` -You normally won't have to use these, but they're available for cases when you need to manually listen for events on a component instance. They can also be useful as a code organization tool. For example, you may often see this pattern for integrating a 3rd-party library: +Vous n'aurez pas à les utiliser normalement, mais ils sont disponibles dans les cas où vous avez besoin d'écouter manuellement des événements sur une instance de composant. Ils peuvent aussi être utiles comme outil d'organisation de code. Par exemple, vous pouvez souvent voir ce pattern pour intégrer une bibliothèque tierce : ```js -// Attach the datepicker to an input once -// it's mounted to the DOM. +// Attache un sélecteur de date à un champ +// une fois celui-ci monté sur le DOM. mounted: function () { - // Pikaday is a 3rd-party datepicker library + // Pikaday est une bibliothèque tierce de sélecteur de date this.picker = new Pikaday({ field: this.$refs.input, format: 'YYYY-MM-DD' }) }, -// Right before the component is destroyed, -// also destroy the datepicker. +// Juste avant que le composant soit détruit, +// on détruit également le sélecteur de date. beforeDestroy: function () { this.picker.destroy() } ``` -This has two potential issues: +Il y a deux problèmes potentiels : -- It requires saving the `picker` to the component instance, when it's possible that only lifecycle hooks need access to it. This isn't terrible, but it could be considered clutter. -- Our setup code is kept separate from our cleanup code, making it more difficult to programmatically clean up anything we set up. +- Cela requiert d'enregistrer le `picker` dans l'instance de composant, alors qu'il est possible que seuls les hooks de cycle de vie aient besoin d'y accéder. Ce n'est pas très grave, mais cela peut être considéré comme de l'encombrement. +- Notre code de montage du composant est séparé du code de nettoyage, ce qui rend plus difficile de nettoyer programmatiquement tout ce que nous avons mis en place avant. -You could resolve both issues with a programmatic listener: +Vous pouvez résoudre ces deux problèmes avec un écouteur programmatique : ```js mounted: function () { @@ -212,7 +212,7 @@ mounted: function () { } ``` -Using this strategy, we could even use Pikaday with several input elements, with each new instance automatically cleaning up after itself: +En utilisant cette stratégie, nous pouvons même utiliser Pikaday sur plusieurs champs, avec chaque nouvelle instance qui nettoiera automatiquement après son passage : ```js mounted: function () { @@ -233,42 +233,42 @@ methods: { } ``` -See [this fiddle](https://jsfiddle.net/chrisvfritz/1Leb7up8/) for the full code. Note, however, that if you find yourself having to do a lot of setup and cleanup within a single component, the best solution will usually be to create more modular components. In this case, we'd recommend creating a reusable `` component. +Consultez [ce fiddle](https://jsfiddle.net/chrisvfritz/1Leb7up8/) pour le code complet. Notez cependant que si vous vous trouvez à devoir faire beaucoup de code de montage et de nettoyage au sein d'un seul composant, la meilleure solution sera souvent de créer des composants plus modulaires. Dans le cas présent, nous recommanderions de créer un composant réutilisable ``. -To learn more about programmatic listeners, check out the API for [Events Instance Methods](https://vuejs.org/v2/api/#Instance-Methods-Events). +Pour en apprendre plus sur les écouteurs programmatiques, allez voir l'API des [méthodes d'événements d'une instance](https://vuejs.org/v2/api/#Instance-Methods-Events). -

Note that Vue's event system is different from the browser's EventTarget API. Though they work similarly, $emit, $on, and $off are not aliases for dispatchEvent, addEventListener, and removeEventListener.

+

Notez que le système d'événements de Vue est différent de celui de l'API EventTarget du navigateur. Bien qu'ils fonctionnent de façon similaire, $emit, $on, et $off ne sont pas des alias pour dispatchEvent, addEventListener, et removeEventListener.

-## Circular References +## Références circulaires -### Recursive Components +### Composants récursifs -Components can recursively invoke themselves in their own template. However, they can only do so with the `name` option: +Les composants peuvent récursivement s'invoquer eux-mêmes dans leur propre template. Cependant, ils peuvent seulement le faire avec l'option `name` : ``` js -name: 'unique-name-of-my-component' +name: 'nom-unique-de-mon-composant' ``` -When you register a component globally using `Vue.component`, the global ID is automatically set as the component's `name` option. +Quand vous inscrivez globalement un composant en utilisant `Vue.component`, l'ID global est automatiquement assigné comme option `name` du composant. ``` js -Vue.component('unique-name-of-my-component', { +Vue.component('nom-unique-de-mon-composant', { // ... }) ``` -If you're not careful, recursive components can also lead to infinite loops: +Si vous n'êtes pas prudents, les composants récursifs peuvent mener à des boucles infinies : ``` js name: 'stack-overflow', template: '
' ``` -A component like the above will result in a "max stack size exceeded" error, so make sure recursive invocation is conditional (i.e. uses a `v-if` that will eventually be `false`). +Un composant comme ci-dessus résultera en une erreur « Taille maximale de la pile dépassée », donc assurez-vous de rendre conditionnelle l'invocation récursive (par ex. avec un `v-if` qui sera `false` à la fin). -### Circular References Between Components +### Références circulaires entre composants -Let's say you're building a file directory tree, like in Finder or File Explorer. You might have a `tree-folder` component with this template: +Supposons que vous construisez un arbre de répertoires de fichiers, comme le Finder ou l'explorateur de fichiers. Vous pourriez avoir un composant `tree-folder` avec ce template : ``` html

@@ -277,7 +277,7 @@ Let's say you're building a file directory tree, like in Finder or File Explorer

``` -Then a `tree-folder-contents` component with this template: +Puis un composant `tree-folder-contents` avec ce template: ``` html
    @@ -288,17 +288,17 @@ Then a `tree-folder-contents` component with this template:
``` -When you look closely, you'll see that these components will actually be each other's descendent _and_ ancestor in the render tree - a paradox! When registering components globally with `Vue.component`, this paradox is resolved for you automatically. If that's you, you can stop reading here. +Si vous regardez de plus près, vous verrez que ces composants sont en fait les descendants __et__ ancêtres l'un de l'autre dans l'arbre de rendu - un paradoxe ! Quand vous inscrivez des composants globalement avec `Vue.component`, ce paradoxe est résolu automatiquement pour vous. Si c'est votre cas, vous pouvez arrêter de lire ici. -However, if you're requiring/importing components using a __module system__, e.g. via Webpack or Browserify, you'll get an error: +Cependant, si vous importez des composants en utilisant un __système de modules__, p.ex. via Webpack ou Browserify, vous aurez une erreur : ``` Failed to mount component: template or render function not defined. ``` -To explain what's happening, let's call our components A and B. The module system sees that it needs A, but first A needs B, but B needs A, but A needs B, etc. It's stuck in a loop, not knowing how to fully resolve either component without first resolving the other. To fix this, we need to give the module system a point at which it can say, "A needs B _eventually_, but there's no need to resolve B first." +Pour expliquer ce qui se passe, appelons nos composants A et B. Le système de modules sait qu'il a besoin de A, mais A a d'abord besoin de B, mais B a besoin de A, mais A a besoin de B, etc. Il est alors bloqué dans une boucle, ne sachant pas comment résoudre un composant sans devoir d'abord résoudre l'autre. Pour corriger cela, nous devons donner au système de modules un point où il peut dire, "A aura _prochainement_ besoin de B, mais il n'y a pas besoin de résoudre B en premier." -In our case, let's make that point the `tree-folder` component. We know the child that creates the paradox is the `tree-folder-contents` component, so we'll wait until the `beforeCreate` lifecycle hook to register it: +Dans notre cas, faisons de ce point le composant `tree-folder`. Nous savons que l'enfant qui crée le paradoxe est le composant `tree-folder-contents`, donc nous allons attendre le hook de cycle de vie `beforeCreate` avant de l'inscrire : ``` js beforeCreate: function () { @@ -306,7 +306,7 @@ beforeCreate: function () { } ``` -Or alternatively, you could use Webpack's asynchronous `import` when you register the component locally: +Ou comme alternative, vous pouvez utiliser l'`import` asynchrone de Webpack lorsque vous inscrivez le composant localement : ``` js components: { @@ -314,28 +314,28 @@ components: { } ``` -Problem solved! +Problème résolu ! -## Alternate Template Definitions +## Définitions alternatives de template -### Inline Templates +### Templates inline -When the `inline-template` special attribute is present on a child component, the component will use its inner content as its template, rather than treating it as distributed content. This allows more flexible template-authoring. +Quand l'attribut spécial `inline-template` est présent sur un composant enfant, le composant utilisera son contenu interne comme template, plutôt que de le traiter comme contenu distribué. Cela permet plus de flexibilité dans la création de templates. ``` html
-

These are compiled as the component's own template.

-

Not parent's transclusion content.

+

Ces éléments sont compilés en tant que propre template du composant.

+

Et non le contenu du parent par transclusion.

``` -

However, inline-template makes the scope of your templates harder to reason about. As a best practice, prefer defining templates inside the component using the template option or in a <template> element in a .vue file.

+

Cependant, inline-template rend la portée de vos templates plus difficile à appréhender. Une bonne pratique est de préférer la définition de templates à l'intérieur du composant en utilisant l'option template ou dans un élément <template> dans un fichier .vue.

### X-Templates -Another way to define templates is inside of a script element with the type `text/x-template`, then referencing the template by an id. For example: +Une autre façon de définir des templates est à l'intérieur d'un élément script avec le type `text/x-template`, puis en référencant le template par un id. Par exemple : ``` html