Les observateurs permettent de réagir aux changements de données. La directive v-model simplifie la liaison de formulaires. Les composants encapsulent des mroceaux d'interface réutilisables.
Utilisation des observateurs avec watch
Un observateur exécute une fonction lorsqu'une propriété réactive spécifique change.
<template>
<div>
<h3>Observateur de données</h3>
<button @click="mettreAJour">Changer la valeur</button>
<p>Message actuel : {{ texte }}</p>
</div>
</template>
<script>
export default {
data() {
return {
texte: 'Bonjour'
}
},
methods: {
mettreAJour() {
this.texte = 'Monde'
}
},
watch: {
texte(nouveau, ancien) {
console.log('Changement détecté :', ancien, '->', nouveau)
if (nouveau !== ancien) {
alert('La valeur a changé !')
}
}
}
}
</script>
Le nom de la fonction dans l'observateur doit correspondre exactement à la propriété à observer.
Liaison de formulaires avec v-model
v-model crée une liaison bidirectionnelle entre la saisie utilisateur et une donnée réactive.
<template>
<div>
<h3>Formulaire de contact</h3>
<input type="text" v-model="nomUtilisateur">
<p>Nom saisi : {{ nomUtilisateur }}</p>
<input type="checkbox" id="accepte" v-model="estAccepte">
<label for="accepte">{{ estAccepte ? 'Accepté' : 'Refusé' }}</label>
</div>
</template>
<script>
export default {
data() {
return {
nomUtilisateur: '',
estAccepte: false
}
}
}
</script>
Modificateurs de v-model
.lazy : la synchronisation se produit sur l'événement change plutôt que input.
<input v-model.lazy="recherche">
.number : tente de convertir la saisie en nombre JavaScript.
<input type="text" v-model.number="age">
.trim : supprime les espaces blancs en début et fin de chaîne.
<input v-model.trim="commentaire">
Références aux éléments du template
La directive ref attribue une référence à un élément DOM, accessible via this.$refs.
<template>
<div>
<div ref="cadre" class="cadre">Conteneur</div>
<button @click="acceder">Manipuler l'élément</button>
</div>
</template>
<script>
export default {
methods: {
acceder() {
console.log(this.$refs.cadre)
this.$refs.cadre.innerHTML = 'Modifié'
}
}
}
</script>
Architecture des composants Vue
Un composant Vue combine trois sections : un template pour le HTML, un script pour la logique et un style pour le CSS.
Enregistrement local (3 étapes) : importer, déclarer dans l'option components, utiliser dans le temlpate.
<template>
<div>
<MonBouton />
</div>
</template>
<script>
import MonBouton from './MonBouton.vue'
export default {
components: {
MonBouton
}
}
</script>
La portée des styles est limitée au composant avec <style scoped>.
Exemple d'imbrication de composants
Voici une structure typique avec un en-tête, une barre latérale et un contenu principal.
// EnTete.vue
<template>
<header class="en-tete">En-tête</header>
</template>
<style scoped>
.en-tete { height: 80px; background: #eee; }
</style>
// BarreLaterale.vue
<template>
<aside class="barre">
<ElementMenu />
<ElementMenu />
</aside>
</template>
<script>
import ElementMenu from './ElementMenu.vue'
export default {
components: { ElementMenu }
}
</script>
// ContenuPrincipal.vue
<template>
<main class="contenu">
<ArticlePublication />
</main>
</template>
<script>
import ArticlePublication from './ArticlePublication.vue'
export default {
components: { ArticlePublication }
}
</script>
// App.vue
<template>
<div id="app">
<EnTete />
<BarreLaterale />
<ContenuPrincipal />
</div>
</template>
<script>
import EnTete from './EnTete.vue'
import BarreLaterale from './BarreLaterale.vue'
import ContenuPrincipal from './ContenuPrincipal.vue'
export default {
components: {
EnTete,
BarreLaterale,
ContenuPrincipal
}
}
</script>
Enregistrement global des composants
Dans Vue 2
On utilise la méthode Vue.component() dans le fichier d'entrée.
import Vue from 'vue'
import CarteArticle from './CarteArticle.vue'
Vue.component('CarteArticle', CarteArticle)
new Vue({
render: h => h(App)
}).$mount('#app')
Dans Vue 3
La méthode app.component() est utilisée après la création de l'instance d'application.
import { createApp } from 'vue'
import App from './App.vue'
import CarteArticle from './CarteArticle.vue'
const application = createApp(App)
application.component('CarteArticle', CarteArticle)
application.mount('#app')