From a5cdb8004bb640ef88347d2a28cce5e96f8d42f5 Mon Sep 17 00:00:00 2001 From: MachinisteWeb Date: Mon, 16 Apr 2018 18:20:41 +0200 Subject: [PATCH 1/9] Pattern pour traduction Signed-off-by: MachinisteWeb --- src/v2/guide/components.md | 901 ++++++++++++++++++++++++++++--------- 1 file changed, 680 insertions(+), 221 deletions(-) diff --git a/src/v2/guide/components.md b/src/v2/guide/components.md index 9d6cc9a02d..1cbb0747ff 100644 --- a/src/v2/guide/components.md +++ b/src/v2/guide/components.md @@ -1,9 +1,14 @@ --- +<<<<<<< HEAD title: Composants +======= +title: Components Basics +>>>>>>> upstream/master type: guide order: 11 --- +<<<<<<< HEAD ## Les composants, qu’est-ce que c’est ? Les composants sont l'une des plus puissantes fonctionnalités de Vue. Ils vous permettent d'étendre les éléments de base du HTML pour encapsuler du code réutilisable. À un haut niveau, les composants sont des éléments personnalisables auxquels le compilateur de Vue attache un comportement. Dans certains cas, ils peuvent aussi apparaitre comme des éléments HTML natifs étendus avec l'attribut spécial `is`. @@ -15,6 +20,11 @@ Tous les composants Vue sont également des instances de Vue. Ils acceptent le m ### Inscription globale Nous avons appris dans les sections précédentes que nous pouvions créer une nouvelle instance de Vue avec : +======= +## Base Example + +Here's an example of a Vue component: +>>>>>>> upstream/master ``` js // Define a new component called button-counter @@ -28,14 +38,19 @@ Vue.component('button-counter', { }) ``` +<<<<<<< HEAD Pour inscrire un composant global, vous pouvez utiliser `Vue.component(tagName, options)`. Par exemple : +======= +Components are reusable Vue instances with a name: in this case, ``. We can use this component as a custom element inside a root Vue instance created with `new Vue`: +>>>>>>> upstream/master -``` js -Vue.component('my-component', { - // options -}) +```html +
+ +
``` +<<<<<<< HEAD

Notez que Vue ne vous force pas à respecter les [règles du W3C](https://www.w3.org/TR/custom-elements/#concepts) en ce qui concerne les noms de balises personnalisées (tout en minuscules, obligation de contenir un trait d'union) bien que suivre cette convention est considéré comme une bonne pratique.

Une fois inscrit, un composant peut être utilisé dans le template d'une instance en tant qu'élément personnalisé, ``. Assurez-vous que le composant soit inscrit **avant** l'instanciation de l'instance racine de Vue. Voici un exemple complet : @@ -50,8 +65,30 @@ Une fois inscrit, un composant peut être utilisé dans le template d'une instan // inscrire Vue.component('my-component', { template: '
Un composant personnalisé !
' +======= +```js +new Vue({ el: '#components-demo' }) +``` + +{% raw %} +
+ +
+ +{% endraw %} +<<<<<<< HEAD // créer une instance racine new Vue({ el: '#example' @@ -63,18 +100,34 @@ Ce qui donnera comme rendu : ``` html
Un composant personnalisé !
+======= +Since components are reusable Vue instances, they accept the same options as `new Vue`, such as `data`, `computed`, `watch`, `methods`, and lifecycle hooks. The only exceptions are a few root-specific options like `el`. + +## Reusing Components + +Components can be reused as many times as you want: + +```html +
+ + + +>>>>>>> upstream/master
``` {% raw %} -
+
+ +
{% endraw %} @@ -85,17 +138,43 @@ Vous n'êtes pas obligé d'inscrire chaque composant de manière globale. Vous p ``` js var Child = { template: '
Un composant personnalisé !
' +======= +new Vue({ el: '#components-demo2' }) + +{% endraw %} + +Notice that when clicking on the buttons, each one maintains its own, separate `count`. That's because each time you use a component, a new **instance** of it is created. + +### `data` Must Be a Function + +When we defined the `` component, you may have noticed that `data` wasn't directly provided an object, like this: + +```js +data: { + count: 0 +>>>>>>> upstream/master } +``` +<<<<<<< HEAD new Vue({ // ... components: { // ne sera disponible que dans le template parent 'my-component': Child +======= +Instead, **a component's `data` option must be a function**, so that each instance can maintain an independent copy of the returned data object: + +```js +data: function () { + return { + count: 0 +>>>>>>> upstream/master } -}) +} ``` +<<<<<<< HEAD La même encapsulation s’applique pour les autres fonctionnalités de Vue pouvant être inscrites, comme les directives. ### Limitations de l'analyse d'un template à partir du DOM @@ -103,21 +182,51 @@ La même encapsulation s’applique pour les autres fonctionnalités de Vue pouv Quand vous utilisez le DOM en tant que template (par ex. : en utilisant l'option `el` pour monter un élément avec du contenu existant), vous êtes sujet à plusieurs restrictions dépendantes de la façon dont fonctionne le HTML, car Vue peut uniquement récupérer le contenu du template **après** qu'il ait été analysé et normalisé. Des éléments tels que `
    `, `
      `, `` et `
      - ... -
      -``` +{% raw %} +
      + + + +
      + +{% endraw %} + +## Organizing Components + +It's common for an app to be organized into a tree of nested components: +![Component Tree](/images/components.png) +>>>>>>> upstream/master + +For example, you might have components for a header, sidebar, and content area, each typically containing other components for navigation links, blog posts, etc. + +<<<<<<< HEAD Le composant personnalisé `` sera évalué comme du contenu invalide, ce qui causera des erreurs dans les éventuels rendus en sortie. Une solution de contournement est d'utiliser l'attribut spécial `is` : +======= +To use these components in templates, they must be registered so that Vue knows about them. There are two types of component registration: **global** and **local**. So far, we've only registered components globally, using `Vue.component`: +>>>>>>> upstream/master -``` html - - -
      +```js +Vue.component('my-component-name', { + // ... options ... +}) ``` +<<<<<<< HEAD **Il est à noter que ces limitations n'existent pas si vous utilisez des templates sous forme de chaine de caractères en provenance d'une des sources suivantes** : - les balises ` {% endraw %} +<<<<<<< HEAD Puisque nos trois instances de composant partagent le même objet `data`, l'incrémentation d'un compteur les incrémentera tous ! Aie. Corrigeons cela en retournant un nouvel objet de données : - -### `data` Must Be a Function - -When we defined the `` component, you may have noticed that `data` wasn't directly provided an object, like this: - -```js -data: { - count: 0 -} -``` - -Instead, **a component's `data` option must be a function**, so that each instance can maintain an independent copy of the returned data object: +======= +In a typical app, however, you'll likely have an array of posts in `data`: +>>>>>>> upstream/master ```js -data: function () { - return { - count: 0 +new Vue({ + el: '#blog-post-demo', + data: { + posts: [ + { id: 1, title: 'My journey with Vue' }, + { id: 2, title: 'Blogging with Vue' }, + { id: 3, title: 'Why Vue is so fun' }, + ] } -} +}) ``` +<<<<<<< HEAD Maintenant tous nos compteurs ont leur propre état interne : +======= +Then want to render a component for each one: +>>>>>>> upstream/master -{% raw %} -
      - - - -
      - -{% endraw %} +```html + +``` +<<<<<<< HEAD ### Composition de composants Les composants sont destinés à être utilisés ensemble, le plus souvent dans une relation parent-enfant : le composant A peut utiliser le composant B dans son propre template. Ils vont inévitablement avoir besoin de communiquer les uns avec les autres : le parent peut avoir besoin de passer des données à l'enfant, et l'enfant peut avoir besoin d'informer le parent que quelque chose s'est produit à l'intérieur. Cependant, il est également très important de garder le parent et l'enfant aussi découplés que possible via une interface clairement définie. Cela assure que le code de chaque composant peut être écrit de manière relativement isolée, cela les rend plus maintenables et potentiellement plus simples à réutiliser. Dans Vue.js, la relation parent-enfant peut être résumée ainsi : **descente de props, remontée d'évènements**. Le parent passe les données à l'enfant via les **props**, et l'enfant envoie des messages à son parent via les **évènements**. Voyons comment cela fonctionne ci-dessous. +======= +Above, you'll see that we can use `v-bind` to dynamically pass props. This is especially useful when you don't know the exact content you're going to render ahead of time, like when [fetching posts from an API](https://jsfiddle.net/chrisvfritz/sbLgr0ad). -For example, you might have components for a header, sidebar, and content area, each typically containing other components for navigation links, blog posts, etc. +That's all you need to know about props for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Props](components-props.html). -To use these components in templates, they must be registered so that Vue knows about them. There are two types of component registration: **global** and **local**. So far, we've only registered components globally, using `Vue.component`: +## A Single Root Element +>>>>>>> upstream/master + +When building out a `` component, your template will eventually contain more than just the title: +```html +

      {{ post.title }}

      +``` + +<<<<<<< HEAD ### Passer des données avec props Chaque instance de composant a sa propre **portée isolée**. Cela signifie qu'on ne peut (et ne devrait) pas directement référencer des données du parent dans un template de composant enfant. Les données doivent être passées aux composants enfants en utilisant **props**. @@ -261,20 +397,41 @@ Résultat :
-{% endraw %} - -Props are custom attributes you can register on a component. When a value is passed to a prop attribute, it becomes a property on that component instance. To pass a title to our blog post component, we can include it in the list of props this component accepts, using a `props` option: +``` +<<<<<<< HEAD Les attributs HTML sont insensibles à la casse, donc quand vous utilisez des templates qui ne sont pas des chaines de caractères, le nom de la prop en camelCase a besoin de son équivalent en kebab-case (délimité par des traits d'union) : ``` js @@ -295,15 +452,50 @@ Encore une fois, si vous utilisez les templates sous forme de chaine de caractè ### Props dynamiques Tout comme la liaison d'un attribut ordinaire avec une expression, nous pouvons aussi utiliser `v-bind` pour dynamiquement lier les props aux données de leurs parents. À chaque fois que les données sont mises à jour dans le parent, elles seront également mises à jour dans l'enfant : +======= +Which can be used in the template to control the font size of all blog posts: -``` html -
- -
- +```html +
+
+ +
``` +Now let's add a button to enlarge the text right before the content of every post: + +```js +Vue.component('blog-post', { + props: ['post'], + template: ` +
+

{{ post.title }}

+ +
+
+ ` +}) +``` + +

The above example and some future ones use JavaScript's [template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) to make multi-line templates more readable. These are not supported by Internet Explorer (IE), so if you must support IE and are not transpiling (e.g. with Babel or TypeScript), use [newline escapes](https://css-tricks.com/snippets/javascript/multiline-string-variables-in-javascript/) instead.

+ +The problem is, this button doesn't do anything: +>>>>>>> upstream/master + +```html + +``` + +<<<<<<< HEAD ``` js new Vue({ el: '#prop-example-2', @@ -314,23 +506,58 @@ new Vue({ ``` Vous pouvez aussi utiliser la syntaxe abrégée pour `v-bind`: +======= +When we click on the button, we need to communicate to the parent that it should enlarge the text of all posts. Fortunately, Vue instances provide a custom events system to solve this problem. To emit an event to the parent, we can call the built-in [**`$emit`** method](../api/#Instance-Methods-Events), passing the name of the event: -``` html - +```html + +``` + +Then on our blog post, we can listen for this event with `v-on`, just as we would with a native DOM event: +>>>>>>> upstream/master + +```html + ``` +<<<<<<< HEAD Résultat : +======= +>>>>>>> upstream/master {% raw %} -
- - - +
+
+ +
{% endraw %} +<<<<<<< HEAD Si vous souhaitez passer toutes les propriétés dans un objet en tant que props, vous devez utiliser `v-bind` sans arguments (`v-bind` au lieu de `v-bind:prop-name`). Par exemple, avec un objet `todo` : ``` js @@ -354,20 +589,32 @@ todo: { ``` Alors : +======= +### Emitting a Value With an Event -``` html - +It's sometimes useful to emit a specific value with an event. For example, we may want the `` component to be in charge of how much to enlarge the text by. In those cases, we can use `$emit`'s 2nd parameter to provide this value: +>>>>>>> upstream/master + +```html + ``` +<<<<<<< HEAD Est équivalent à : +======= +Then when we listen to the event in the parent, we can access the emitted event's value with `$event`: +>>>>>>> upstream/master -``` html - +```html + ``` +<<<<<<< HEAD ### Littérale vs. Dynamique Une erreur répandue chez les débutants est d'essayer de passer un nombre en utilisant la syntaxe littérale : @@ -399,25 +646,51 @@ Il y a habituellement deux cas où il est tentant de changer une prop : Les réponses correctes pour ces cas d'utilisation sont : 1. Définir une propriété de donnée locale qui utilise la valeur initiale de la prop comme une valeur d'initialisation : +======= +Or, if the event handler is a method: - ``` js - props: ['initialCounter'], - data: function () { - return { counter: this.initialCounter } +```html + +``` + +Then the value will be passed as the first parameter of that method: + +```js +methods: { + onEnlargeText: function (enlargeAmount) { + this.postFontSize += enlargeAmount } - ``` +} +``` + +### Using `v-model` on Components + +Custom events can also be used to create custom inputs that work with `v-model`. Remember that: + +```html + +``` +>>>>>>> upstream/master +does the same thing as: + +<<<<<<< HEAD 2. Définir une propriété calculée qui est calculée à partir de la valeur de la prop : +======= +```html + +``` +>>>>>>> upstream/master - ``` js - props: ['size'], - computed: { - normalizedSize: function () { - return this.size.trim().toLowerCase() - } - } - ``` +When used on a component, `v-model` instead does this: +<<<<<<< HEAD

Notez que les objets et tableaux en JavaScript sont passés par référence, aussi si la prop est un tableau ou un objet, modifier l'objet ou le tableau lui-même à l'intérieur de l'enfant **va** affecter l'état du parent.

### Validation de prop @@ -463,49 +736,129 @@ Vue.component('example', { Le `type` peut être l'un des constructeurs natifs suivants : -```html - +- String +- Number +- Boolean +- Function +- Object +- Array +- Symbol + +De plus, `type` peut également être une fonction constructeur personnalisée et ainsi l'assertion sera faite avec une vérification `instanceof`. + +Quand une validation de prop échoue, Vue produira un avertissement dans la console (si vous utilisez le *build* de développement). Notez que cette props est validée __avant__ que l'instance du composant soit créée, donc à l'intérieur des fonctions `default` ou `validator`, les propriétés d'instance comme `data`, `computed`, ou `methods` ne seront pas disponibles. + +## Attribut non-prop + +Un attribut non-prop est un attribut qui est passé au composant, mais qui n'a pas de prop correspondante définie. + +Bien que définir explicitement les props soit conseillé pour passer les informations à un composant enfant, les auteurs des bibliothèques de composant ne suivent pas forcément cette règle dans leurs composants. C'est pour cela que les composants peuvent accepter des attributs arbitraires, qui sont ajoutés à l'élément racine du composant. + +Par exemple, imaginez que nous utilisions un composant tiers `bs-date-input` avec un plugin Bootstrap qui nécessite un attribut `data-3d-date-picker` sur l'`input`. Nous pouvons ajouter cet attribut dans l'instance de notre composant : +======= +``` html + +``` + +For this to actually work though, the `` inside the component must: + +- Bind the `value` attribute to a `value` prop +- On `input`, emit its own custom `input` event with the new value + +Here's that in action: + +```js +Vue.component('custom-input', { + props: ['value'], + template: ` + + ` +}) ``` -De plus, `type` peut également être une fonction constructeur personnalisée et ainsi l'assertion sera faite avec une vérification `instanceof`. - -Quand une validation de prop échoue, Vue produira un avertissement dans la console (si vous utilisez le *build* de développement). Notez que cette props est validée __avant__ que l'instance du composant soit créée, donc à l'intérieur des fonctions `default` ou `validator`, les propriétés d'instance comme `data`, `computed`, ou `methods` ne seront pas disponibles. +Now `v-model` should work perfectly with this component: -## Attribut non-prop +```html + +``` -Un attribut non-prop est un attribut qui est passé au composant, mais qui n'a pas de prop correspondante définie. +That's all you need to know about custom component events for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Custom Events](components-custom-events.html). -Bien que définir explicitement les props soit conseillé pour passer les informations à un composant enfant, les auteurs des bibliothèques de composant ne suivent pas forcément cette règle dans leurs composants. C'est pour cela que les composants peuvent accepter des attributs arbitraires, qui sont ajoutés à l'élément racine du composant. +## Content Distribution with Slots -Par exemple, imaginez que nous utilisions un composant tiers `bs-date-input` avec un plugin Bootstrap qui nécessite un attribut `data-3d-date-picker` sur l'`input`. Nous pouvons ajouter cet attribut dans l'instance de notre composant : +Just like with HTML elements, it's often useful to be able to pass content to a component, like this: +>>>>>>> upstream/master ``` html - + + Something bad happened. + ``` +<<<<<<< HEAD Et l'attribut `data-3d-date-picker="true"` sera automatiquement ajouté à l'élément racine de `bs-date-input`. ## Remplacement et merge avec des attributs existants Imaginez que ceci est un template pour `bs-date-input`: +======= +Which might render something like: -``` html - +{% raw %} +
+ + Something bad happened. + +
+ + +{% endraw %} + +Fortunately, this task is made very simple by Vue's custom `` element: +>>>>>>> upstream/master + +```js +Vue.component('alert-box', { + template: ` +
+ Error! + +
+ ` +}) ``` +<<<<<<< HEAD Pour ajouter un thème spécifique à notre plugin date picker, nous allons avoir besoin d'ajouter une classe, comme cela : +======= +As you'll see above, we just add the slot where we want it to go -- and that's it. We're done! +>>>>>>> upstream/master -```html -
-

{{ post.title }}

-
-
-``` +That's all you need to know about slots for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Slots](components-slots.html). +<<<<<<< HEAD Dans ce cas, deux valeurs différentes pour `class` sont définies : - `form-control`, qui est la classe du composant dans ce template @@ -531,16 +884,113 @@ De plus, un composant parent peut écouter des évènements émis depuis un comp

Vous ne pouvez pas utiliser `$on` pour écouter les évènements émis par les enfants. Vous devez utiliser `v-on` directement dans le template, comme dans l'exemple ci-dessous.

Voici un exemple : +======= +## Dynamic Components + +Sometimes, it's useful to dynamically switch between components, like in a tabbed interface: + +{% raw %} +
+ + +
+ + +{% endraw %} + +The above is made possible by Vue's `` element with the `is` special attribute: + +```html + + +``` + +In the example above, `currentTabComponent` can contain either: + +- the name of a registered component, or +- a component's options object + +See [this fiddle](https://jsfiddle.net/chrisvfritz/o3nycadu/) to experiment with the full code, or [this version](https://jsfiddle.net/chrisvfritz/b2qj69o1/) for an example binding to a component's options object, instead of its registered name. + +That's all you need to know about dynamic components for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Dynamic & Async Components](components-dynamic-async.html). + +## DOM Template Parsing Caveats + +Some HTML elements, such as `
    `, `
      `, `` and ``, and `
      + +
      +``` + +The custom component `` will be hoisted out as invalid content, causing errors in the eventual rendered output. Fortunately, the `is` special attribute offers a workaround: ``` html -
      + + +
      +``` + +<<<<<<< HEAD +{% raw %} +

      {{ total }}

      -``` - -``` js + +{% endraw %} Dans cet exemple, il est important de noter que le composant enfant est toujours complètement découplé de ce qui se passe en dehors de celui-ci. Tout ce qu'il fait, c'est rapporter des informations sur sa propre activité, juste au cas où le composant parent écouterait. @@ -596,18 +1048,16 @@ Vue.component('button-message', { } }) -```js -Vue.component('blog-post', { - props: ['post'], - template: ` -
      -

      {{ post.title }}

      - -
      -
      - ` +new Vue({ + el: '#message-event-example', + data: { + messages: [] + }, + methods: { + handleMessage: function (payload) { + this.messages.push(payload.message) + } + } }) ``` @@ -688,10 +1138,7 @@ this.$emit('update:foo', newValue) Le modificateur `.sync` peut aussi être utilisé avec `v-bind` quand il utilise un objet pour affecter plusieurs propriétés en une seule fois : ```html - + ``` Cela a pour effet d'ajouter des écouteurs de mise à jour `v-on` sur `foo` et `bar`. @@ -705,13 +1152,17 @@ Les évènements personnalisés peuvent aussi être utilisés pour créer des ch ``` est juste du sucre syntaxique pour : +======= +It should be noted that **this limitation does _not_ apply if you are using string templates from one of the following sources**: -``` html - -``` +- String templates (e.g. `template: '...'`) +- [Single-file (`.vue`) components](single-file-components.html) +- [` {% endraw %} L'implémentation ci-dessus est plutôt naïve cependant. Par exemple, les utilisateurs peuvent toujours saisir plusieurs points et même parfois des lettres (beurk) ! Donc pour ceux qui souhaiteraient voir un exemple non trivial, voici un filtre de devise plus robuste : -It's sometimes useful to emit a specific value with an event. For example, we may want the `` component to be in charge of how much to enlarge the text by. In those cases, we can use `$emit`'s 2nd parameter to provide this value: + ### Personnalisation de composant avec `v-model` @@ -923,7 +1377,7 @@ Vue.component('child-component', { someChildProperty: true } } -} +}) ``` De façon similaire, le contenu distribué sera compilé dans la portée parente. @@ -1131,10 +1585,14 @@ Si vous préférez, vous pouvez aussi les lier directement à des composants obj var Home = { template: '

      Bienvenue chez toi !

      ' } - -{% endraw %} -Fortunately, this task is made very simple by Vue's custom `` element: +var vm = new Vue({ + el: '#example', + data: { + currentView: Home + } +}) +``` ### `keep-alive` @@ -1238,15 +1696,9 @@ Quand vous utilisez une [inscription locale](components.html#Local-Registration) ``` js new Vue({ - el: '#dynamic-component-demo', - data: { - currentTab: 'Home', - tabs: ['Home', 'Posts', 'Archive'] - }, - computed: { - currentTabComponent: function () { - return 'tab-' + this.currentTab.toLowerCase() - } + // ... + components: { + 'my-component': () => import('./my-async-component') } }) ``` @@ -1314,28 +1766,26 @@ components: { camelCasedComponent: { /* ... */ }, PascalCasedComponent: { /* ... */ } } -.dynamic-component-demo-tab-button-active { - background: #e0e0e0; -} -.dynamic-component-demo-tab { - border: 1px solid #ccc; - padding: 10px; -} - -{% endraw %} +``` -The above is made possible by Vue's `` element with the `is` special attribute: +``` html + -```html - - + + + + + + ``` Cela signifie que la PascalCase est la _convention de déclaration_ la plus universelle et que la kebab-case est la _convention d'utilisation_ la plus universelle. Si votre composant ne passe pas de contenu via des éléments `slot` vous pouvez même utiliser la syntaxe d'autofermeture `/` après le nom : -See [this fiddle](https://jsfiddle.net/chrisvfritz/o3nycadu/) to experiment with the full code, or [this version](https://jsfiddle.net/chrisvfritz/b2qj69o1/) for an example binding to a component's options object, instead of its registered name. +``` html + +``` Encore une fois, cela fonctionne _seulement_ dans les templates sous forme de chaine de caractères. Les éléments autofermants ne sont pas du HTML valide et l'analyseur HTML natif de votre navigateur ne le comprendra pas. @@ -1343,7 +1793,9 @@ Encore une fois, cela fonctionne _seulement_ dans les templates sous forme de ch Les composants peuvent s'invoquer récursivement dans leur propre template. Cependant, ils peuvent uniquement le faire avec l'option `name` : -This will lead to issues when using components with elements that have such restrictions. For example: +``` js +name: 'unique-name-of-my-component' +``` Quand vous inscrivez un composant de manière globale en utilisant `Vue.component`, l'ID global est automatiquement défini en tant qu'option `name` du composant. @@ -1367,17 +1819,21 @@ Un composant comme celui ci-dessus conduira à une erreur « taille maximale de Imaginons que vous construisiez une arborescence de fichiers, comme Finder ou File Explorer. Vous pouvez avoir un composant `tree-folder` avec ce template : ``` html - - -
      +

      + {{ folder.name }} + +

      ``` Puis un composant `tree-folder-contents` avec ce template : ``` html - - -
      +
        +
      • + + {{ child.name }} +
      • +
      ``` En regardant attentivement, vous verrez que ces composants seront en fait l'ancêtre _et_ le descendant l'un de l'autre dans l'arbre de rendu — un paradoxe ! Quand vous inscrivez un composant de manière globale avec `Vue.component`, ce paradoxe est résolu pour vous automatiquement. Si c'est votre cas, vous pouvez arrêter de lire ici. @@ -1447,3 +1903,6 @@ Vue.component('terms-of-service', { ` }) ``` +======= +Once you feel comfortable with the knowledge you've just digested, we recommend coming back to read the full guide on [Dynamic & Async Components](components-dynamic-async.html), as well as the other pages in the Components In-Depth section of the sidebar. +>>>>>>> upstream/master From 3c6ae585ecf8c064d8279303bd7d78a6d655a2ae Mon Sep 17 00:00:00 2001 From: MachinisteWeb Date: Thu, 19 Apr 2018 14:04:48 +0200 Subject: [PATCH 2/9] Intro + Registration + Props translated Signed-off-by: MachinisteWeb --- src/v2/guide/components.md | 84 ++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/src/v2/guide/components.md b/src/v2/guide/components.md index 1cbb0747ff..c9de97819a 100644 --- a/src/v2/guide/components.md +++ b/src/v2/guide/components.md @@ -1,9 +1,5 @@ --- -<<<<<<< HEAD title: Composants -======= -title: Components Basics ->>>>>>> upstream/master type: guide order: 11 --- @@ -21,27 +17,27 @@ Tous les composants Vue sont également des instances de Vue. Ils acceptent le m Nous avons appris dans les sections précédentes que nous pouvions créer une nouvelle instance de Vue avec : ======= -## Base Example +## Exemple de base -Here's an example of a Vue component: +Voici un exemple de composant Vue : >>>>>>> upstream/master ``` js -// Define a new component called button-counter +// Définition d'un nouveau composant appelé `button-counter` Vue.component('button-counter', { data: function () { return { count: 0 } }, - template: '' + template: '' }) ``` <<<<<<< HEAD Pour inscrire un composant global, vous pouvez utiliser `Vue.component(tagName, options)`. Par exemple : ======= -Components are reusable Vue instances with a name: in this case, ``. We can use this component as a custom element inside a root Vue instance created with `new Vue`: +Les composants sont des instances de Vue réutilisable avec un nom : dans notre cas ``. Nous pouvons utiliser ce composant en tant qu'élément persommalisé à l'intérieure d'une instance de Vue racie créée avec `new Vue` : >>>>>>> upstream/master ```html @@ -81,7 +77,7 @@ Vue.component('button-counter', { count: 0 } }, - template: '' + template: '' >>>>>>> upstream/master }) new Vue({ el: '#components-demo' }) @@ -101,11 +97,11 @@ Ce qui donnera comme rendu :
      Un composant personnalisé !
      ======= -Since components are reusable Vue instances, they accept the same options as `new Vue`, such as `data`, `computed`, `watch`, `methods`, and lifecycle hooks. The only exceptions are a few root-specific options like `el`. +Puisque les composants sont des instances de Vue réutilisables, ils acceptent les mêmes option que `new Vue` comme `data`, `computed`, `watch`, `methods`, et les hooks du cycle de vie. Les seules exceptions sont quelques options spécifique à la racine comme `el`. -## Reusing Components +## Réutilisation de composants -Components can be reused as many times as you want: +Les composants peuvent être réutilisés autant de fois que souhaité : ```html
      @@ -143,11 +139,11 @@ new Vue({ el: '#components-demo2' }) {% endraw %} -Notice that when clicking on the buttons, each one maintains its own, separate `count`. That's because each time you use a component, a new **instance** of it is created. +Notez que lors du clique sur les boutons, chacun d'entre eux maintient sont propre conteur séparé des autres. C'est parceque chaque fois que vous utilisez un composant, une nouvelle **instance** est créée. -### `data` Must Be a Function +### `data` doit être une fonction -When we defined the `` component, you may have noticed that `data` wasn't directly provided an object, like this: +Quand vous définissez le composant ``, vous devez faire attention que `data` ne soit pas directement fourni en tant qu'objet, comme ceci : ```js data: { @@ -163,7 +159,7 @@ new Vue({ // ne sera disponible que dans le template parent 'my-component': Child ======= -Instead, **a component's `data` option must be a function**, so that each instance can maintain an independent copy of the returned data object: +À la place, **l'option `data` d'un composant doit être une fonction**, ainsi chaque instance peut maintenir sa propre copie indépendante d'objet de données : ```js data: function () { @@ -183,7 +179,7 @@ Quand vous utilisez le DOM en tant que template (par ex. : en utilisant l'option Ceci est problématique quand on utilise des composants personnalisés avec des éléments qui ont ces restrictions, par exemple : ======= -If Vue didn't have this rule, clicking on one button would affect the data of _all other instances_, like below: +Si Vue n'avait pas cette règle, cliquer sur un bouton affecterait les données de _toutes les autres instances_, comme ci-dessous : {% raw %}
      @@ -199,25 +195,25 @@ Vue.component('button-counter2', { data: function () { return buttonCounter2Data }, - template: '' + template: '' }) new Vue({ el: '#components-demo3' }) {% endraw %} -## Organizing Components +## Organisation des composants -It's common for an app to be organized into a tree of nested components: +Il est commun pour une application d'être organisée en un arbre de composants imbriqués : -![Component Tree](/images/components.png) +![Arbre de composant](/images/components.png) >>>>>>> upstream/master -For example, you might have components for a header, sidebar, and content area, each typically containing other components for navigation links, blog posts, etc. +Par exemple, vous pouvez avoir des composant pour l'en-tête, la barre latérale, la zone de contenu ; chacun contenant lui aussi d'autres composants pour la navigations, les liens, les billets de blog, etc. <<<<<<< HEAD Le composant personnalisé `` sera évalué comme du contenu invalide, ce qui causera des erreurs dans les éventuels rendus en sortie. Une solution de contournement est d'utiliser l'attribut spécial `is` : ======= -To use these components in templates, they must be registered so that Vue knows about them. There are two types of component registration: **global** and **local**. So far, we've only registered components globally, using `Vue.component`: +Pour utiliser ces composants dans des templates, ils doivent être enregistrés pour que Vue les connaissent. Il y a deux types d'enregistrement de composant : **globale** et **locale**. Jusqu'ici, nous avons uniquement enregistrés des composants globallement en utilisant `Vue.component` : >>>>>>> upstream/master ```js @@ -271,15 +267,15 @@ Vue.component('simple-counter', { } }) ======= -Globally registered components can be used in the template of any root Vue instance (`new Vue`) created afterwards -- and even inside all subcomponents of that Vue instance's component tree. +Les composants enregistrés globallement peuvent être utilisé dans le template de n'importe quelle instance racine de Vue (`new Vue`) créer après coup, ainsi que dans les sous-composants de l'arbre des composants de cette instance de Vue. -That's all you need to know about registration for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Component Registration](components-registration.html). +C'est tout ce que vous avez besoin de savoir à propos de l'enregistrement pour le moment, mais une fois que vous aurez fini de lire cette page et que vous vous sentirez à l'aise avec son contenu, nous vous recommandons de revenir plus tard pour lire le guide complet à propos de l'[Enregistrement de composant](components-registration.html). -## Passing Data to Child Components with Props +## Passer des données aux composants enfant avec les props -Earlier, we mentioned creating a component for blog posts. The problem is, that component won't be useful unless you can pass data to it, such as the title and content of the specific post we want to display. That's where props come in. +Plus tôt, nous avons mentionné la création d'un composant pour des billets de blog. Le problème est, que ce composant ne sera utile que s'il ont peu lui passer des données, comme le titre ou le contenu pour un billet spécifique à afficher. C'est ici que les props interviennent. -Props are custom attributes you can register on a component. When a value is passed to a prop attribute, it becomes a property on that component instance. To pass a title to our blog post component, we can include it in the list of props this component accepts, using a `props` option: +Les props sont des attributs personnalisables que vous pouvez enregistrer dans un composant. Quand une valeur est passé à un attribut prop, elle devient une propriété de l'instance du composant. Pour passer un titre à notre billet de blog, nous devont l'inclure dans une liste de props que ce composant accepte, en utilisant l'option `props` : ```js Vue.component('blog-post', { @@ -288,22 +284,22 @@ Vue.component('blog-post', { }) ``` -A component can have as many props as you'd like and by default, any value can be passed to any prop. In the template above, you'll see that we can access this value on the component instance, just like with `data`. +Un composant peut avoir autant de props que vous le souhaitez et par défaut, n'importe quelle valeur peut être passé à une prop. Dans le template ci-dessus, vous devriez voir cette valeur dans l'instance du composant, comme pour `data`. -Once a prop is registered, you can pass data to it as a custom attribute, like this: +Une fois une prop enregistrée, vous pouvez lui passer des données en tant qu'attribut personnalisé comme ceci : >>>>>>> upstream/master ```html - - - + + + ``` {% raw %}
      - - - + + +
      {% endraw %} -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION // créer une instance racine new Vue({ el: '#example' @@ -96,7 +96,7 @@ Ce qui donnera comme rendu : ``` html
      Un composant personnalisé !
      -======= +≠≠≠≠≠≠≠ Puisque les composants sont des instances de Vue réutilisables, ils acceptent les mêmes option que `new Vue` comme `data`, `computed`, `watch`, `methods`, et les hooks du cycle de vie. Les seules exceptions sont quelques options spécifique à la racine comme `el`. ## Réutilisation de composants @@ -108,7 +108,7 @@ Les composants peuvent être réutilisés autant de fois que souhaité : ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION
      ``` @@ -119,7 +119,7 @@ Les composants peuvent être réutilisés autant de fois que souhaité :
      {% endraw %} @@ -148,29 +148,29 @@ Quand vous définissez le composant ``, vous devez faire attenti ```js data: { count: 0 ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION } ``` -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION new Vue({ // ... components: { // ne sera disponible que dans le template parent 'my-component': Child -======= +≠≠≠≠≠≠≠ À la place, **l'option `data` d'un composant doit être une fonction**, ainsi chaque instance peut maintenir sa propre copie indépendante d'objet de données : ```js data: function () { return { count: 0 ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION } } ``` -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION La même encapsulation s’applique pour les autres fonctionnalités de Vue pouvant être inscrites, comme les directives. ### Limitations de l'analyse d'un template à partir du DOM @@ -178,7 +178,7 @@ La même encapsulation s’applique pour les autres fonctionnalités de Vue pouv Quand vous utilisez le DOM en tant que template (par ex. : en utilisant l'option `el` pour monter un élément avec du contenu existant), vous êtes sujet à plusieurs restrictions dépendantes de la façon dont fonctionne le HTML, car Vue peut uniquement récupérer le contenu du template **après** qu'il ait été analysé et normalisé. Des éléments tels que `
        `, `
          `, `` et ` ``` ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION does the same thing as: -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION 2. Définir une propriété calculée qui est calculée à partir de la valeur de la prop : -======= +≠≠≠≠≠≠≠ ```html ``` ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION When used on a component, `v-model` instead does this: -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION

          Notez que les objets et tableaux en JavaScript sont passés par référence, aussi si la prop est un tableau ou un objet, modifier l'objet ou le tableau lui-même à l'intérieur de l'enfant **va** affecter l'état du parent.

          ### Validation de prop @@ -751,7 +751,7 @@ Un attribut non-prop est un attribut qui est passé au composant, mais qui n'a p Bien que définir explicitement les props soit conseillé pour passer les informations à un composant enfant, les auteurs des bibliothèques de composant ne suivent pas forcément cette règle dans leurs composants. C'est pour cela que les composants peuvent accepter des attributs arbitraires, qui sont ajoutés à l'élément racine du composant. Par exemple, imaginez que nous utilisions un composant tiers `bs-date-input` avec un plugin Bootstrap qui nécessite un attribut `data-3d-date-picker` sur l'`input`. Nous pouvons ajouter cet attribut dans l'instance de notre composant : -======= +≠≠≠≠≠≠≠ ``` html >>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION ``` html @@ -797,13 +797,13 @@ Just like with HTML elements, it's often useful to be able to pass content to a ``` -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION Et l'attribut `data-3d-date-picker="true"` sera automatiquement ajouté à l'élément racine de `bs-date-input`. ## Remplacement et merge avec des attributs existants Imaginez que ceci est un template pour `bs-date-input`: -======= +≠≠≠≠≠≠≠ Which might render something like: {% raw %} @@ -833,7 +833,7 @@ new Vue({ el: '#slots-demo' }) {% endraw %} Fortunately, this task is made very simple by Vue's custom `` element: ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION ```js Vue.component('alert-box', { @@ -846,15 +846,15 @@ Vue.component('alert-box', { }) ``` -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION Pour ajouter un thème spécifique à notre plugin date picker, nous allons avoir besoin d'ajouter une classe, comme cela : -======= +≠≠≠≠≠≠≠ As you'll see above, we just add the slot where we want it to go -- and that's it. We're done! ->>>>>>> upstream/master +≥≥≥≥≥≥≥ CURRENT TRANSLATION That's all you need to know about slots for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Slots](components-slots.html). -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION Dans ce cas, deux valeurs différentes pour `class` sont définies : - `form-control`, qui est la classe du composant dans ce template @@ -880,7 +880,7 @@ De plus, un composant parent peut écouter des évènements émis depuis un comp

          Vous ne pouvez pas utiliser `$on` pour écouter les évènements émis par les enfants. Vous devez utiliser `v-on` directement dans le template, comme dans l'exemple ci-dessous.

          Voici un exemple : -======= +≠≠≠≠≠≠≠ ## Dynamic Components Sometimes, it's useful to dynamically switch between components, like in a tabbed interface: @@ -963,7 +963,7 @@ That's all you need to know about dynamic components for now, but once you've fi Some HTML elements, such as `
            `, `
              `, `
          ` and ``, and `
          @@ -979,7 +979,7 @@ The custom component `` will be hoisted out as invalid content, c
          ``` -<<<<<<< HEAD +≤≤≤≤≤≤≤≤ OLD TRANSLATION {% raw %}

          {{ total }}

          @@ -1148,17 +1148,17 @@ Les évènements personnalisés peuvent aussi être utilisés pour créer des ch ``` est juste du sucre syntaxique pour : -======= +≠≠≠≠≠≠≠ It should be noted that **this limitation does _not_ apply if you are using string templates from one of the following sources**: - String templates (e.g. `template: '...'`) - [Single-file (`.vue`) components](single-file-components.html) - [` {% endraw %} -≤≤≤≤≤≤≤≤ OLD TRANSLATION -// créer une instance racine -new Vue({ - el: '#example' -}) -``` - -Ce qui donnera comme rendu : - -``` html -
          -
          Un composant personnalisé !
          -≠≠≠≠≠≠≠ Puisque les composants sont des instances de Vue réutilisables, ils acceptent les mêmes option que `new Vue` comme `data`, `computed`, `watch`, `methods`, et les hooks du cycle de vie. Les seules exceptions sont quelques options spécifique à la racine comme `el`. ## Réutilisation de composants @@ -108,7 +60,6 @@ Les composants peuvent être réutilisés autant de fois que souhaité : -≥≥≥≥≥≥≥ CURRENT TRANSLATION
          ``` @@ -119,22 +70,6 @@ Les composants peuvent être réutilisés autant de fois que souhaité :
          -{% endraw %} - -### Inscription locale - -Vous n'êtes pas obligé d'inscrire chaque composant de manière globale. Vous pouvez rendre un composant disponible dans la portée d'un(e) autre composant/instance en l'inscrivant avec l'option `components` lors de l'instanciation : - -``` js -var Child = { - template: '
          Un composant personnalisé !
          ' -≠≠≠≠≠≠≠ new Vue({ el: '#components-demo2' }) {% endraw %} @@ -148,37 +83,19 @@ Quand vous définissez le composant ``, vous devez faire attenti ```js data: { count: 0 -≥≥≥≥≥≥≥ CURRENT TRANSLATION } ``` -≤≤≤≤≤≤≤≤ OLD TRANSLATION -new Vue({ - // ... - components: { - // ne sera disponible que dans le template parent - 'my-component': Child -≠≠≠≠≠≠≠ À la place, **l'option `data` d'un composant doit être une fonction**, ainsi chaque instance peut maintenir sa propre copie indépendante d'objet de données : ```js data: function () { return { count: 0 -≥≥≥≥≥≥≥ CURRENT TRANSLATION } } ``` -≤≤≤≤≤≤≤≤ OLD TRANSLATION -La même encapsulation s’applique pour les autres fonctionnalités de Vue pouvant être inscrites, comme les directives. - -### Limitations de l'analyse d'un template à partir du DOM - -Quand vous utilisez le DOM en tant que template (par ex. : en utilisant l'option `el` pour monter un élément avec du contenu existant), vous êtes sujet à plusieurs restrictions dépendantes de la façon dont fonctionne le HTML, car Vue peut uniquement récupérer le contenu du template **après** qu'il ait été analysé et normalisé. Des éléments tels que `
            `, `
              `, `` et ` ``` -≥≥≥≥≥≥≥ CURRENT TRANSLATION -does the same thing as: +réalise la même chose que : -≤≤≤≤≤≤≤≤ OLD TRANSLATION -2. Définir une propriété calculée qui est calculée à partir de la valeur de la prop : -≠≠≠≠≠≠≠ ```html ``` -≥≥≥≥≥≥≥ CURRENT TRANSLATION - -When used on a component, `v-model` instead does this: - -≤≤≤≤≤≤≤≤ OLD TRANSLATION -

              Notez que les objets et tableaux en JavaScript sont passés par référence, aussi si la prop est un tableau ou un objet, modifier l'objet ou le tableau lui-même à l'intérieur de l'enfant **va** affecter l'état du parent.

              - -### Validation de prop - -Il est possible pour un composant de spécifier les conditions à remplir pour les props qu'il reçoit. Si une condition n'est pas satisfaite, Vue émettra des alertes. C'est particulièrement utile quand vous créez un composant qui a pour vocation d'être utilisé par d'autres. - -Au lieu de définir les props en tant que tableau de chaine de caractères, vous pouvez utiliser un objet avec des conditions de validation : - -``` js -Vue.component('example', { - props: { - // vérification basique du type (`null` signifie l'acceptation de n'importe quel type) - propA: Number, - // plusieurs types possibles - propB: [String, Number], - // une chaine de caractères est obligatoire - propC: { - type: String, - required: true - }, - // un nombre avec une valeur par défaut - propD: { - type: Number, - default: 100 - }, - // les objets et tableaux par défaut doivent être retournés - // par une fabrique de fonctions - propE: { - type: Object, - default: function () { - return { message: 'hello' } - } - }, - // fonction de validation personnalisée - propF: { - validator: function (value) { - return value > 10 - } - } - } -}) -``` -Le `type` peut être l'un des constructeurs natifs suivants : +Quand il est utiliser sur un composant, `v-model` fait plutôt cela : -- String -- Number -- Boolean -- Function -- Object -- Array -- Symbol - -De plus, `type` peut également être une fonction constructeur personnalisée et ainsi l'assertion sera faite avec une vérification `instanceof`. - -Quand une validation de prop échoue, Vue produira un avertissement dans la console (si vous utilisez le *build* de développement). Notez que cette props est validée __avant__ que l'instance du composant soit créée, donc à l'intérieur des fonctions `default` ou `validator`, les propriétés d'instance comme `data`, `computed`, ou `methods` ne seront pas disponibles. - -## Attribut non-prop - -Un attribut non-prop est un attribut qui est passé au composant, mais qui n'a pas de prop correspondante définie. - -Bien que définir explicitement les props soit conseillé pour passer les informations à un composant enfant, les auteurs des bibliothèques de composant ne suivent pas forcément cette règle dans leurs composants. C'est pour cela que les composants peuvent accepter des attributs arbitraires, qui sont ajoutés à l'élément racine du composant. - -Par exemple, imaginez que nous utilisions un composant tiers `bs-date-input` avec un plugin Bootstrap qui nécessite un attribut `data-3d-date-picker` sur l'`input`. Nous pouvons ajouter cet attribut dans l'instance de notre composant : -≠≠≠≠≠≠≠ ``` html ``` -For this to actually work though, the `` inside the component must: +Pour que cela puisse fonctionner, la balise `` à l'intérieur du composant doit : -- Bind the `value` attribute to a `value` prop -- On `input`, emit its own custom `input` event with the new value +- Lier l'attribut `value` à la prop `value` +- Et sur l'`input`, émettre son propre événement personnalisé `input` avec la nouvelle valeur -Here's that in action: +Voici un exemple en action : ```js Vue.component('custom-input', { @@ -778,7 +424,7 @@ Vue.component('custom-input', { }) ``` -Now `v-model` should work perfectly with this component: +Maintenant `v-model` fonctionnera parfaitement avec le composant : ```html @@ -786,37 +432,31 @@ Now `v-model` should work perfectly with this component: That's all you need to know about custom component events for now, but once you've finished reading this page and feel comfortable with its content, we recommend coming back later to read the full guide on [Custom Events](components-custom-events.html). -## Content Distribution with Slots +C'est tout ce que vous avez besoin de savoir à propos des événements pour le moment, mais une fois que vous aurez fini de lire cette page et que vous vous sentirez à l'aise avec son contenu, nous vous recommandons de revenir plus tard pour lire le guide complet à propos des [événements personnalisés](components-custom-events.html). -Just like with HTML elements, it's often useful to be able to pass content to a component, like this: -≥≥≥≥≥≥≥ CURRENT TRANSLATION +## Distribution de contenu avec les slots + +Exactement comme les éléments HTML, il est souvent utile de passer du contenu à un composant comme ceci : ``` html - Something bad happened. + Quelque chose c'est mal passé. ``` -≤≤≤≤≤≤≤≤ OLD TRANSLATION -Et l'attribut `data-3d-date-picker="true"` sera automatiquement ajouté à l'élément racine de `bs-date-input`. - -## Remplacement et merge avec des attributs existants - -Imaginez que ceci est un template pour `bs-date-input`: -≠≠≠≠≠≠≠ -Which might render something like: +Qui pourrait faire le rendu de quelque chose comme : {% raw %}
              - Something bad happened. + Quelque chose c'est mal passé.
              -{% endraw %} - -Dans cet exemple, il est important de noter que le composant enfant est toujours complètement découplé de ce qui se passe en dehors de celui-ci. Tout ce qu'il fait, c'est rapporter des informations sur sa propre activité, juste au cas où le composant parent écouterait. - -Voici comment utiliser des données complémentaires : - -``` html -
              -

              {{ msg }}

              - -
              -``` - -``` js -Vue.component('button-message', { - template: `
              - - -
              `, - data: function () { - return { - message: 'message test' - } - }, - methods: { - handleSendMessage: function () { - this.$emit('message', { message: this.message }) - } - } -}) - -new Vue({ - el: '#message-event-example', - data: { - messages: [] - }, - methods: { - handleMessage: function (payload) { - this.messages.push(payload.message) - } - } -}) -``` - -{% raw %} -
              -

              {{ msg }}

              - -
              - -{% endraw %} - -Dans le second exemple, il est important de noter que le composant enfant est toujours complètement découplé de ce qu'il peut se passer à l'extérieur. Tout ce qu'il fait c'est reporter l'information à propos de sa propre activité en incluant les données utiles dans le déclencheur d'évènement, au cas où le composant parant en aurait besoin. - -### Lier des évènements natifs aux composants - -Il y a des fois où vous souhaitez écouter un évènement natif sur l'élément racine d'un composant. Dans ce cas, vous devez utiliser le modificateur `.native` sur `v-on`. Par exemple : - -``` html - -``` - -### Modificateur `.sync` - -> 2.3.0+ - -Dans certains cas, nous pourrions avoir besoin d'une « liaison bidirectionnelle » pour une prop. En fait, dans Vue 1.x, c'est exactement ce que le modificateur `.sync` permettait. Quand un composant enfant mute une prop qui a `.sync`, la valeur est remontée au parent. C'est pratique, cependant cela peut conduire à des soucis de maintenance sur le long terme car cela brise l'hypothèse du flux de donnée unidirectionnelle : le code qui mute dans des props enfants affecte l'état du parent. - -C'est pour cela que nous avions retiré le modificateur `.sync` dans la version 2.0. Cependant, nous trouvons tout de même qu'il existe des cas où celle-ci est très utile, notamment pour les composants réutilisables. Ce dont nous avions besoin était **de rendre le code d'un enfant qui affecte l'état d'un parent plus cohérent et explicite.** - -Dans la 2.3.0+ nous réintroduisons donc le modificateur `.sync` pour les props, mais cette fois, ce n'est qu'un sucre syntaxique pour étendre automatiquement un écouteur `v-on` additionnel : - -Ce qui suit - -``` html - -``` - -est le raccourci de : - -``` html - -``` - -Pour un composant enfant qui met à jour la valeur de `foo`, il faut explicitement émettre un évènement au lieu de muter la prop : - -``` js -this.$emit('update:foo', newValue) -``` - -Le modificateur `.sync` peut aussi être utilisé avec `v-bind` quand il utilise un objet pour affecter plusieurs propriétés en une seule fois : - -```html - -``` - -Cela a pour effet d'ajouter des écouteurs de mise à jour `v-on` sur `foo` et `bar`. - -### Composants de champ de formulaire utilisant les évènements personnalisés - -Les évènements personnalisés peuvent aussi être utilisés pour créer des champs personnalisés qui fonctionnent avec `v-model`. Rappelez-vous : - -``` html - -``` - -est juste du sucre syntaxique pour : -≠≠≠≠≠≠≠ It should be noted that **this limitation does _not_ apply if you are using string templates from one of the following sources**: - String templates (e.g. `template: '...'`) - [Single-file (`.vue`) components](single-file-components.html) - [` -{% endraw %} - -L'implémentation ci-dessus est plutôt naïve cependant. Par exemple, les utilisateurs peuvent toujours saisir plusieurs points et même parfois des lettres (beurk) ! Donc pour ceux qui souhaiteraient voir un exemple non trivial, voici un filtre de devise plus robuste : - - - -### Personnalisation de composant avec `v-model` - -> Nouveau dans la 2.2.0+ - -Par défaut, `v-model` sur un composant utilise `value` en tant que prop et `input` en tant qu'évènement, mais plusieurs types de champ comme les cases à cocher et les boutons radio pourraient utiliser `value` pour un usage différent. Utiliser l'option `model` permet d'éviter les conflits dans ce genre de situations : - -``` js -Vue.component('my-checkbox', { - model: { - prop: 'checked', - event: 'change' - }, - props: { - checked: Boolean, - // ceci permet d'utiliser la prop `value` pour un usage différent - value: String - }, - // ... -}) -``` - -``` html - -``` - -La partie ci-dessus sera équivalente à : - -``` html - - -``` - -

              Notez que vous devez encore déclarer la prop `checked` explicitement.

              - -### Communication non parent-enfant - -Parfois deux composants peuvent avoir besoin de communiquer entre eux mais ne sont pas parent et enfant l'un de l'autre. Dans les scénarios simples, vous pouvez utiliser une instance de Vue vide comme canal d'évènements central. - -``` js -var bus = new Vue() -``` -``` js -// dans la méthode du composant A -bus.$emit('id-selected', 1) -``` -``` js -// dans le hook de création de B -bus.$on('id-selected', function (id) { - // ... -}) -``` - -Dans des cas plus complexes, vous pouvez envisager l'utilisation d'un [*pattern* de management d'état](state-management.html). - -## Distribution de contenu avec des slots - -Quand on utilise des composants, il est souvent souhaitable de les composer comme ceci : - -``` html - - - - -``` - -Il y a deux choses à noter ici : - -1. Le composant `` ne sait pas quel contenu il va recevoir. Ceci est défini par le composant qui utilise ``. - -2. Le composant `` a vraisemblablement son propre template. - -Pour faire fonctionner la composition, nous avons besoin d'un moyen pour entremêler le « contenu » du parent et le template de son propre composant. C'est un processus appelé **distribution de contenu** (ou « transclusion » si vous êtes familier avec Angular). Vue.js implémente une API de distribution de contenu modélisée à partir du [brouillon de spécification sur les Web Components](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md), en utilisant l'élément spécial `` pour servir de points de distribution pour le contenu original. - -### Portée de compilation - -Avant de rentrer plus profondément dans l'API, clarifions dans quelle portée le contenu va être compilé. Imaginez un template comme celui-ci : - -``` html - - {{ message }} - -``` - -`message` devrait-il être lié aux données du parent ou aux données de l'enfant ? La réponse est : au parent. Une règle simple pour la portée du composant est : - -> Tout ce qui se trouve dans le template parent est compilé dans la portée du parent ; tout ce qui se trouve dans le template enfant est compilé dans la portée de l'enfant. - -Une erreur répandue est d'essayer de lier une directive à une propriété/méthode enfant dans le template du parent : - -``` html - - -``` - -En admettant que `someChildProperty` est une propriété du composant enfant, l'exemple ci-dessus ne fonctionnerait pas. Le template parent n'est pas au courant de l'état du composant enfant. - -Si vous avez besoin de lier des directives enfants sur un composant du nœud racine, vous devriez faire cela sur le template du composant enfant : - -``` js -Vue.component('child-component', { - // ceci fonctionne, car nous sommes dans la bonne portée - template: '
              Enfant
              ', - data: function () { - return { - someChildProperty: true - } - } -}) -``` - -De façon similaire, le contenu distribué sera compilé dans la portée parente. - -### Slot unique - -Le contenu parent sera **évincé** si le template du composant enfant contient au moins une balise ``. Quand il n'y a qu'un seul slot sans attribut, tout le fragment de contenu sera inséré à sa position dans le DOM, remplaçant le slot lui-même. - -Tout ce qui était contenu à la base dans les balises `` est considéré comme **du contenu par défaut**. Le contenu par défaut est compilé dans la portée enfant et ne sera affiché que si l'élément l'incluant est vide et qu'il n'y a pas de contenu à insérer. - -Supposons que nous ayons un composant appelé `my-component` avec le template suivant : - -``` html -
              -

              Je suis le titre de l'enfant

              - - Ceci ne sera affiché que s'il n'y a pas de contenu - à distribuer. - -
              -``` - -Et un parent qui utilise le composant : - -``` html -
              -

              Je suis le titre du parent

              - -

              Ceci est le contenu original

              -

              Ceci est encore du contenu original

              -
              -
              -``` - -Le résultat du rendu sera : - -``` html -
              -

              Je suis le titre du parent

              -
              -

              Je suis le titre de l'enfant

              -

              Ceci est le contenu original

              -

              Ceci est encore du contenu original

              -
              -
              -``` - -### Slots nommés - -Les éléments `` ont un attribut spécial, `name`, qui peut être utilisé pour personnaliser la façon dont le contenu doit être distribué. Vous pouvez avoir de multiples slots avec des noms différents. Un slot nommé ira avec n'importe quel élément possédant l'attribut `slot` correspondant dans le fragment de contenu. - -Il peut encore y avoir un slot non nommé, c'est le **slot par défaut** qui va servir de fourretout pour tout le contenu ne concordant avec aucun nom. S'il n'y a pas de slot par défaut, le contenu ne concordant pas est évincé. - -Par exemple, avec un composant `app-layout` avec le template suivant : - -``` html -
              -
              - -
              -
              - -
              -
              - -
              -
              -``` - -Le balisage du parent : - -``` html - -

              Voici un titre de page

              - -

              Un paragraphe pour le contenu principal.

              -

              Et un autre.

              - -

              Ici plusieurs informations de contact

              -
              -``` - -Le résultat du rendu sera : - -``` html -
              -
              -

              Voici un titre de page

              -
              -
              -

              Un paragraphe pour le contenu principal.

              -

              Et un autre.

              -
              -
              -

              Ici plusieurs informations de contact

              -
              -
              -``` - -L'API de distribution de contenu est un mécanisme vraiment utile lors de la conception de composants qui sont censés être composés ensemble. - -### Slots avec portée - -> Nouveau dans la 2.1.0+ - -Un slot avec portée est un type de slot spécial qui fonctionne comme un template réutilisable (auquel on peut passer des données) au lieu d'éléments déjà rendus. - -Dans un composant enfant, passez simplement les données via le slot de la même manière que vous passeriez des props dans un composant : - -``` html -
              - -
              -``` - -Dans le parent, un élément `