Préambule
- Les démonstrations de ce TD se basent sur les sources disponibles [ ici ].
- Attention, seul le répertoire src est dans l'archive. Il faut donc créer un projet avec vue-cli et remplacer son répertoire src.
1°/ Que sont les props ?
- Dans le premier TP, on utilise un store pinia afin de créer un dépot central de données, que se partagent tous les composants.
- Cependant, toutes les données applicatives n'ont pas besoin d'être totalement partagées. Dans bien des cas, il y a juste besoin qu'un composant père donne des valeurs à un composant fils.
- Par exemple, on imagine aisément un composant faisant office de barre de navigation dont les items lui seraient fournis par son père.
- Ce passage de valeurs se fait grâce au principe des props, sous entendu les propriétés du composant fils, dont le père peut fixer la valeur.
- Les props restent malgré tout des variables locales à un composant, comme celle de data. Elles ne sont donc pas accessibles directement à l'extérieur du composant.
2°/ définir des props
- Pour définir des variables de type props d'un composant, il suffit d'appeler dans la partie script la fonction defineProps(), dont le paramètre est :
- soit un tableau contenant uniquement le nom des variables,
- soit un objet dont les champs sont les noms des variables et leur valeur un type JS (String, Number, Boolean, Array, Object, Function, ...)
- La deuxième syntaxe est à privilégier car elle permet d'avoir des message d'alerte dans la console lorsque le composant parent donne une valeur du mauvais type à une props.
Exemple avec 2 props nommées title et show :
<script setup>
...
const props = defineProps({
title: String,
show: Boolean
})
...
</script>
Remarques :
- Il n'y a pas besoin d'importer defineProps().
- On n'est pas obligé de récupérer la valeur de retour de cette fonction. Cela n'est utile que lorsque l'on a besoin d'accéder aux props dans le partie script.
- Si on récupère la valeur de retour, on la met dans une variable généralement nommée props. Cependant, on peut la nommer autrement, pourvu que l'on utilise ensuite ce nom dans le script.
3°/ Manipuler les props
- On ne manipule pas tout à fait les props comme les variables locales définies avec ref ou reactive. Cela dépend du contexte :
- dans le template : on utilise directement le nom de la props
- dans le script, on utilise le nom de la props, précédé du nom de la variable qui stocke la valeur de retour de defineProps().
Exemple (dans CompoFils.vue) :
<template>
{{ title }}
</template>
<script setup>
const props = defineProps({ title: String, happy: boolean})
console.log(props.title); console.log(props.happy)
...
</script>
- Pour fixer leur valeur dans le composant parent, cela se passe lorsque l'on utilise la balise permettant de créer le composant fils. On donne simplement une valeur à un attribut portant le nom de la props.
- Du point de vue du parent, la props est donc un attribut du fils.
- Pour fixer la valeur de l'attribut représentant la props, cela fonctionne comme avec les autres attributs.
- On peut :
- soit donner une valeur statique, comme on le ferait en HTML. Par exemple : oneprop="hello",
- soit donner une valeur venant d'une variable du composant père, grâce à v-bind. Par exemple : v-bind:oneprop="myvar"
Exemple (dans CompoParent.vue) :
<template>
<CompoFils title="bonjour" :happy="state">
</template>
<script setup>
import {ref} from 'vue'
import CompoFils from '@/components/CompoFils.vue'
const state = ref(false)
...
</script>
ATTENTION !
- Modifier la valeur d'une props dans le composant qui la déclare est normalement interdit, bien que cela soit possible. Dans ce cas, on a un message d'alerte dans la console.
- De plus, sauf exception, si une props est modifiée, cette modification ne sera pas répercutée dans le composant parent.
Démonstration :
- lancer l'application : npm run dev et accéder à l'URL
- Montrer le code de TD3Demo.vue. On observe que le composant a 3 props : title, show et initVal.
- Montrer le code de App.vue. On observe que les 3 attributs de la balise <TD3Demo> correspondent aux 3 props.
- Pour title, on fixe sa valeur "en dur" : pas besoin d'utiliser un v-bind. En revanche, pour les 2 autres, on veut pouvoir changer dynamiquement la valeur passée à TD3Demo. On est donc obligé d'utiliser v-bind.
- Si on tape quelque chose dans le champ de saisie, cela modifie la valeur de la variable value, initialisée grâce à la props initVal. On remarque que cela ne crée pas de lien spécial entre ces 2 variables puisque changer value ne change pas initVal.
- Cliquer sur le bouton "Toggle ...". Cela change la valeur de showMsg dans App. Comme cette variable est reliée à la props show de TD3Demo, un changement de showMsg implique le même changement pour show.
- Cliquer sur le bouton "Reset...". Un warning s'affiche signalant l'échec de la modification.
- NB : les @click sont des directives vuejs pour gérer les événements click (comme onclick en JS classique). Les principes de gestion de événements sont décrits dans le TD 4