Apprendre
Vue.js 3 - : concepts de base
Remarque
Ce tutoriel est plus un récapitulatif des possibilités de Vue js.
Pour un cours plus complet vous pouvez aller à cette adresse
:
https://v3.vuejs.org/guide/introduction.html
Qu’est-ce que Vue.js ?
Vue.js est un framework progressif pour JavaScript utilisé pour
créer des interfaces Web et des applications d'une page (SPA).
Vue.js peut également être utilisé pour le développement
d'applications de bureau et mobiles avec les frameworks Ionic et
Electron.
Pourquoi
Vue.js
Avant d’utiliser un framework il est important de comprendre dans
quel contexte il s’avère le bon outil.
Voici donc la liste des différentes raisons qui pourraient
justifier l’utilisation d’un framework comme Vue.js
- Organisation
de votre code
- Efficacité/rapidité
de développement
- Réutilisabilité
du code
- Maintenance
et développement évolutif
Extensions
VisualStudioCode pour être productif avec Vue
- Vetur
:
Outils d'aide à coder comme la coloration syntaxique,
le formating, intelliSense, Emmet, etc.
- Vue
VsCode Snippets : Raccourci clavier pour ajouter des snippets dans
votre code
Comment
Utiliser/installer Vue.js
Vue est un framework dit progressif. Vous pouvez l’utiliser juste
dans une petite partie de votre page web ou si vous préférez vous
pouvez construire une application entière avec Vue.js.
Il y a 4 possibilités "d'installer" vue js dans vos
applications :
1.
Importez-le en tant que package
CDN sur
la page (ce sera la solution choisie ici).
-
Téléchargez
les fichiers JavaScript et hébergez-les
vous-même.
-
Installez-le
en utilisant npm.
-
Vue fournit une CLI
officielle (ouvre
une nouvelle fenêtre)
pour un échafaudage rapide d'applications monopages
ambitieuses.
La CLI suppose une connaissance préalable de Node.js et des outils
de génération associés. Nous allons donc utiliser vue js avec
un lien CDN dans un 1er temps. Nous utiliserons l'outil
CLI dans un 2nd temps.
Voici ce que l'on fera pour utiliser Vue seulement dans une partie
de notre page web :
·
Ajouter un tag 'script' qui contient un lien vers la librairie
Vue.js
- Ajouter
un autre tag 'script' qui contient un lien vers notre fichier
application Vue (app.js)
- Créer
une div avec id="app" qui servira de conteneur au rendu de notre
application Vue.
Remarque :
Quel que soit le navigateur utilisé, il est impératif durant la
phase de développement, d'afficher la console web.
A.
UTILISATION VUE
JS SANS OUTIL DE DEVELOPPEMENT
Voici un exemple d'une page utilisant Vue.js
(index.html)
<html>
<head>
<title>Ma page
Vue.js</title>
</head>
<body>
<div
id="app">
{{ title }}
</div>
<script
src="https://unpkg.com/vue@next"></script>
<script
src="./app.js"></script>
</body>
</html>
(app.js)
// fonction qui permet d'initialiser Vue.js
const vm = Vue.createApp({ // le const vm =
est facultatif mais plus pratique
data() {
return {
title: "Hello Word Vue"
}
}
}).mount('#app')
// mount spécifie que l'application Vue s'affichera dans la div
avec id="app"
Ou
const vm = {
data() {
return {
title: "Hello Word Vue"
}
}
}
Vue.createApp(vm).mount('#app')
A-1.
Variables Reactive
La fonction data() sert à créer des variables réactives qui seront
utilisées dans votre application Vue. Chaque fois qu'une variable
réactive est modifiée, si elle est affichée ou utilisée dans votre
page, Vue la mettra à jour immédiatement.
Pour afficher une variable réactive ou une expression dans votre
page vous devez utiliser les doubles crochets Vue remplacera le
contenu de l'expression par sa valeur
// variable
{{ title }}
// expression
{{ title.toUpperCase() }}
A-2. Les directives Vue.js
Les directives Vue.js sont des attributs html qui peuvent être
insérés dans votre page afin de modifier le rendu de votre
application Vue.
Voici la liste des directives disponibles:
v-bind
Permet d'assigner une expression à un attribut. Vue va remplacer
l'expression par sa valeur
(ex: image_url : "http://www.exemple.com/car.jpg"
dans app.js)
<img v-bind:src="image_url" />
// ou syntaxe raccourci
<img :src="image_url" />
v-once
Avec la directive v-once Vue va interpoler l'expression seulement
une fois. L'expression sera donc ignorée pour tous les autres
rafraichissements.
<div v-once>
{{ title }}
</div>
v-html
Permet d'afficher une expression avec des tags HTML.
ex: title: "
Hello World
"
<div v-html="title">
</div>
Illustration TD1_base et TD2_base.
v-model
Permet de lier la valeur d'un champ de saisie avec une variable. Si
vous modifiez l'un ou l'autre Vue mettra a jour automatiquement
l'autre. Du coup, la variable et le champ de saisie auront toujours
la même valeur.
<input v-model="name" type="text" />
<div>
Nom : {{ name }}
</div>
Illustration TD3_v-model.
v-if, v-else-if et v-else
Rend un élément visible ou non visible selon la valeur vrai ou faux
de l'expression. Lorsque non visible l'élément n'est pas rendu dans
le html
<div v-if="montant > 100">
Livraison gratuite!
<div>
<div v-else-if="montant > 50">
Livraison 9.95$
</div>
<div v-else>
Livraison 19.95$
</div>
v-show
Rend un élément visible ou non visible selon la valeur vrai ou faux
de l'expression. Par contre, l'élément reste toujours présent dans
le rendu. Lorsque non visible l'élément est rendu avec l'attribut
CSS: display: none;
<div v-show="isError">
{{ errorMessage }}
</div>
v-for
Permet d'afficher une liste d'éléments
<ul>
<li v-for="item in items"
:key="item.id">
{{ item.name
}}
</li>
</ul>
À noter le mot clé "key" est nécessaire pour permettre à Vue
d'identifier uniquement l'élément
Illustration TD4_directive_v-for.
Ref
Permet à l'application Vue d'identifier un élément html et
d'effectuer des actions sur cet élément.
Identification avec la directif ref
<input type="text" ref="name">
Manipulation à partir de votre code Vue en utilisant le mot clé
spécial: $refs
methods: {
handleClick() {
console.log(this.$refs.name)
this.$refs.name.classList.add('active')
this.$refs.name.focus()
}
}
v-bind sur l'attribut "class" et les "style"
Il est possible de faire un v-bind sur l'attribut class et
style
<div class="text-2xl" :class="isAdmin ? 'text-red-500' :
'text-gray-500'">
Hello World
</div>
À noter que l'attribut class est utilisé deux fois (une fois pour
le css, une fois par Vue).
Vue va regrouper ces deux attributs lors du rendu.
Il est également possible d'utiliser un objet pour envoyer du
contenu dans notre attribut "class"
<div :class="{ 'text-red-500': isAdmin, 'text-gray-500':
!isAdmin }">
Hello World
</div>
À noter la syntaxe de l'object { attribut : expression } si
l'expression retourne vrai alors l'attribut sera ajouter à la
class
Une syntaxe similaire s'applique à l'attribut style
<div :style="{'margin-top': '10px', 'padding':
'5px'}">
Hello World
</div>
Enfin les attributs class et style peuvent être définis par une
variable de type objet créé ailleurs dans votre
application
titleClass: {
'text-red-400': this.isAdmin,
'text-gray-500': !this.isAdmin
}
<div :class="titleClass">
Hello World
</div>
L'élément
Cet élément permet d'utiliser des directives de Vue sans créer un
élément html.
<template v-show="quantity === 0">
La quantité doit être supérieure à
zéro
</template>
A-3. Les Évènements
Vue permet de gérer les évènements javascript comme click, input,
change, etc. Pour ce faire vous devez utiliser la directive v-on:
suivi du nom de l'évènement.
v-on:click
Permet d'exécuter du code sur le click d'un élément
<button v-on:click="name = 'Mike'">Afficher
message</button>
// ou syntaxe raccourci
<button @click="name = 'Mike'">Afficher
message</button>
v-on:keydown
Permet d'exécuter du code sur l'appui d'une touche (ex.
enter)
<button v-on:keydown.enter="name = 'Mike'">Afficher
message</button>
// ou syntaxe raccourci
<button @keydown.enter="name = 'Mike'">Afficher
message</button>
Autres valeurs possibles pour v-on : keydown, keyup,
keypress
Autres valeurs possibles pour .enter : tab, esc, up, down, left,
right, delete
v-on:submit
Permet d'exécuter du code lors de la soumission d'un
formulaire
<form v-on:submit.prevent="name = 'Mike'">
<input v-model="name" type="text"
/>
<button
type="submit">Sauvegarde</button>
</form>
À noter, la présence de ".prevent" après la directive v-on:submit.
Cette instruction va prévenir la soumission du formulaire au
serveur.
A-4. Les méthodes
Vue js permet de créer des méthodes afin d'y placer un bloc de code
réutilisable dans votre application. Voici la syntaxe pour créer
une méthode:
Vue.createApp({
data() {
return {
name: "Mike Taylor",
}
},
methods: {
resetName() {
this.name = ''
}
}
}).mount('#app')
À noter le mot clé 'this' placé en avant de la variable name. Ce
mot clé est obligatoire pour permettre de référencer une variable à
l'intérieur de notre instance de Vue.
Pour appeler une méthode vous pouvez le faire simplement en
utilisant son nom.
<input v-model="name" type="text" />
<button @click="resetName"
type="text">Effacer</button>
Une méthode peut également contenir des paramètres
methods: {
resetName(newName) {
this.name =
newName
}
}
<input v-model="name" type="text" />
<button @click="resetName('John')"
type="text">Effacer</button>
Une méthode peut également envoyer l'objet event
methods: {
resetName(newName, e) {
this.name =
newName
console.log(e.target.textContent)
}
}
<input v-model="name" type="text" />
<button @click="resetName('John', $event)"
type="text">Effacer</button>
À noter le paramètre spécial $event va envoyer l'objet event à
notre méthode
Illustration TD5_methode&evenement.
Les
méthodes "computed"
Contrairement aux autres méthodes qui vont se ré-exécutées à chaque
rendu de votre application, les méthodes "computed" vont être
ré-exécutées seulement si les variables qu'elles contiennent sont
modifiées.
computed: {
recalculerTotal(items, taxes) {
return
this.calculerTotal(items, taxes)
}
}
Les méthodes "computed" peuvent ensuite être appelées dans notre
page.
<button
@click="recalculerTotal">Re-Calculer</button>
À noter qu'aucun paramètre ni parenthèse n'est utilisé
Les
méthodes "watch"
Ces méthodes vont "regarder" une variable et dès qu'elle change
exécutera le code de la méthode.
watch: {
title(newTitle, oldTitle) {
console.log(`Le titre
${oldTitle} à changé pour ${newTitle}`)
}
}
Les
méthodes "Lifecycle Hook"
Chaque instance de vue traverse une série d’étapes d’initialisation
au moment de sa création - par exemple, elle doit mettre en place
l’observation des données, compiler le template, monter l’instance
sur le DOM et mettre à jour le DOM quand les données
changent.
En cours de route, elle va aussi invoquer
des hooks de cycle de vie, qui nous donnent
l’opportunité d’exécuter une logique personnalisée à chaque
étape.
Par exemple, le hook "created" est appelé une fois l’instance
créée
created() {
console.log('Mon instance est
created')
}
Il existe plusieurs autres méthodes hook. En voici
quelques-unes:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
A-5. Les
"Components" (composants)
Vue.js est un framework qui permet et encourage l'organisation de
votre application en plusieurs "components"et sous
"components"
Chaque élément distinct de votre page devra avoir son propre
component. Par exemple la barre de navigation pourrait être contenu
dans un component NavBar réutilisé sur plusieurs pages
Voici la syntaxe pour créer des "components" et utiliser Vue
seulement dans une petite partie de votre page.
const app = Vue.createApp({
data() {
return {
messsage: 'Un message'
}
},
methods: {
deleteUser(userID)
{
console.log(`User ${userID} deleted`)
}
}
})
app.component('nav-bar', {
template: `
<div>
{{ title }}
...navigation bar code...
</div>
`,
props: {
title: {
type: String,
required: true,
default: 'Mon application'
}
},
methods: {
sendDelete()
{
const userId = 10
this.$emit('delete', userId)
}
}
})
app.mount('#app')
Les components crées peuvent ensuite être utilisés comme des tags
HTML dans votre page
<div>
<nav-bar title="Mon application"
v-on:delete="deleteUser($event)" />
</div>
L'élément "template" contient le HTML qui sera rendu à l'endroit où
vous avez placé votre tag component dans votre page html
L'objet "props" définit quelle data est attendue lors du rendu du
component
props: {
title: {
type: String,
required:
true,
default: 'Mon
application'
}
},
Props peut également être utilisé avec une syntaxe
raccourci
props: ['title'],
Vous pouvez par la suite assigner une valeur à ces props lors de
l'utilisation du component
<div>
<nav-bar title="Mon application"
/>
</div>
Enfin, le mot-clé $emit permet d'émettre un événement. Cet
évènement pourra ensuite être capté par votre application avec un
v-on:nom-event
methods: {
sendDelete() {
const userId =
10
this.$emit('delete',
userId)
}
}
<div>
<nav-bar title="Mon app"
v-on:delete="deleteUser" />
</div>
Illustration TD6_composant.
B. CREER
UNE APPLICATION VUE JS AVEC L'OUTIL DE DEVELOPPEMENT VUE
CLI
L'outil pour créer un projet Vue.js est Vue CLI. Vous devrez
l'installer
npm install -g
@vue/cli
ou avec yarn (c'est ce que nous
utiliserons)
Vue
create
Permet de créer un projet Vue.js avec plein d'éléments déjà
préconfigurés pour vous.
vue create my-app-name
npm
run serve
Une fois l'application créée vous pouvez vous positionner dans le
dossier et lancer le serveur de développement.
cd my-app-name
npm run serve
Vue
add
Il est possible d'ajouter des plugin/librairie à votre projet Vue
en utilisant le raccourci vue add. Voici 3 exemples:
vue add vue-router
vue add vuex
vue add tailwind
Point
de départ
Vue CLI va créer plusieurs dossiers et fichiers. Le point de départ
est public/index.html et "src/main.js"
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
Le component qui sert de point d'entrée est donc App.vue
Avec une application Vue, aucun code HTML ne sera écrit dans le
fichier index.html. Votre code HTML sera écrit dans la section de
chacun de vos components
Vite
Il est également possible de créer un projet avec Vite. C'est un
outil plus récent et plus efficace
npm init @vitejs/app my-app-name --template vue
Cette commande va créer exactement un projet Vue.js avec les mêmes
pré-configurations que le Vue-CLI
Avec un projet Vite, la commande pour lancer le serveur
est
npm install
npm run dev
Les
Single-File Component
Chaque component Vue est défini dans son propre fichier .vue avec
la syntaxe suivante
<template>
<img alt="Vue logo" src="./assets/logo.png"
/>
<HelloWorld msg="Hello Vue 3 + Vite"
/>
{{ message }}
</template>
<script>
import HelloWorld from
'./components/HelloWorld.vue'
export default {
components: {
HelloWorld
},
data() {
return {
message: 'Hello World'
}
},
}
</script>
<style scope >
#app {
font-family: Avenir, Helvetica,
Arial, sans-serif;
text-align: center;
color: #2c3e50;
}
</style>
À noter qu'avec l'utilisation des single-file-component, le
code HTML du component est saisi dans la section template. Il n'est
pas saisi dans la div #app de votre index.html
Comme démontré dans le dernier exemple, Il est possible d'utiliser
un autre component à l'intérieur de votre component
actuel.
<template>
<HelloWorld msg="Hello Vue 3 + Vite"
/>
</template>
Pour cela il faut utiliser import:
import HelloWorld from './components/HelloWorld.vue'
Emplacement
des fichiers components
Les Single-File-Component sont sauvegardés dans un dossier
src/components ou src/pages selon si le component agit à titre de
page (ex. About.vue) ou à titre de component ré-utilisable (ex.
NavBar.vue)
Les
Slots
Les slots permettent d'ajouter du contenu à un component
<custom-button>
Je peux ajouter du contenu...
Titre: {{ title }}
</custom-button>
À noter que le rendu de 'title' se fera dans le component parent.
Le même principe s'appliquera pour le css. Donc le contenu de la
slot doit être défini/accessible dans le component
parent
À l'interne le custom-button ressemble à quelque chose comme
ceci:
<template>
<slot></slot>
</template>
La balise slot va être remplacée par le contenu de
'custom-button'
Il est possible de définir une valeur par défaut pour la
slot
<template>
<slot>Si rien n'est spécifier je vais
m'afficher</slot>
</template>
À noter que la valeur par défaut est défini dans le component
enfant, donc devra utiliser les variables ou le css défini dans le
component enfant.
Les slots multiples
Permet d'ajouter du contenu associé seulement à un slot en
particulier
<custom-button>
Je peux ajouter du contenu...
<template #title>
{{ title }}
</template>
</custom-button>
'#title' indentifie la template au slot title. La syntaxe
v-slot:title peut également être utilisé.
À l'interne le custom-button ressemble à quelque chose comme ceci
:
<template>
<slot></slot>
<slot name="title"></slot>
</template>
À noter que le slot principal est toujours disponible
(les balises ici sont optionnelles) mais il est possible d'ajouter
un second slot avec un nom
Slot
Props
Les slots peuvent avoir des props
<template>
<slot name="title"
satus="info"></slot>
</template>
Les Props peuvent ensuite être utilisés
<custom-button>
Je peux ajouter du contenu...
<template #title="titleProps">
{{ title }}
{{ titleProps.status }}
</template>
</custom-button>
Il est possible de définir des Props pour les slot principal en
utilisant '#defaut'
<template>
<slot
type="ajout"></slot>
<slot name="title"
status="info"></slot>
</template>
<custom-button>
<template #default="defaultProps">
Je peux ajouter du
contenu...
{{ defaultProps.type }}
</template>
<template #title="titleProps">
{{ title }}
{{ titleProps.status }}
</template>
</custom-button>
À noter que si il n'y a pas de named slot. Il est possible
d'utiliser les Props du default avec cette syntaxe
<custom-button #default="defaultProps">
Je peux ajouter du
contenu...
{{ defaultProps.type }}
</custom-button>