Remarque
Ce tutoriel est plus un récapitulatif des possibilités de Vue js. Pour un cours plus complet vous pouvez aller à cette adresse : guide Vue.js 3
Extensions VisualStudioCode pour être productif avec Vue
Quel que soit le navigateur utilisé, il est impératif durant la phase de développement, d'afficher la console web.
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 utiliser 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
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).
3. Installez-le en utilisant npm.
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 pour la création "d'application entière".
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.
Support du cours "Le jeu de moutons"
Le but du jeu est de réussir à cliquer sur le loup "qui se balade" dans la grille.
Créer une instance de Vue.js
Il existe 2 solutions pour utiliser vue.js :
1. Télécharger vue et l'ajouter à notre projet.
2. Utiliser CDN. La librairie sera accessible à distance et héberger sur un serveur distant. Cette solution est plus pratique mais nécessite une connexion internet fiable.
Dans ce cours nous allons utiliser la méthode CDN.
Découverte de vue.js :
Fichier html (view1.html) :
<html>
<head>
<meta charset="utf-8">
<title>Cours Vue.js</title>
</head>
<body>
<div id="app">{{ msg }}</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel1.js"></script>
</body>
</html>
Création du fichier javascript (viewModel1.js) :
var app = Vue.createApp({
data() {
return {
msg: "Hello world !"
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div ayant l'id "app"
Etape 1 : Lier une valeur du modèle à une valeur d'attribut de la vue
Objectif : Créer la grille (5*5) permettant d'afficher les moutons et un loup placé aléatoirement.
ou
ou
Principe à découvrir : v-bind.
Fichier html ("view2.html") :
<html>
<head>
<meta charset="utf-8">
<title>Cours Vue.js - 2</title>
<style>
.plateau {
display: grid;
grid-template-columns: 100px 100px 100px 100px 100px;
}
</style>
</head>
<body>
<div id="app">
<h1>{{ titre }}</h1>
<div class="plateau">
<div class="cellule"><img v-bind:src=cases[0] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[1] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[2] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[3] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[4] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[5] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[6] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[7] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[8] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[9] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[10] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[11] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[12] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[13] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[14] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[15] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[16] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[17] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[18] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[19] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[20] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[21] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[22] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[23] height="100" width="100"></div>
<div class="cellule"><img v-bind:src=cases[24] height="100" width="100"></div>
</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel2.js"></script>
</body>
</html>
Fichier javascript ("viewModel2.js") :
var app = Vue.createApp({
data() {
return {
titre: "Attraper le loup !",
cases: []
}
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = "./images/mouton.png";
}
this.cases[this.getRandomInt(0,24)] = "./images/loup.png";
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Explications :
Dans le html:
La directive v-bind:, placé dans le document html, permet ici de relier l'attribut src de l'image avec la valeur du modèle, en l'occurrence avec un élément du tableau cases.
Dans le modèle :
Dans methods, on créé nos propres fonctions. Ici getrandomInt(param1, param2) permet de retourner un nombre aléatoire situé entre 0 et 24.
beforeMount()permet de placer des instructions javascript qui seront exécutées avant le montage de l'application Vue.
Il est impératif d'utiliser this quand on utilise une donnée ou méthode du modèle, dans le modèle lui même.
Etape 2 : Afficher du html du modèle dans la vue
Objectif : Toujours le même affichage mais en simplifiant le fichier html.
Principe à découvrir : v-html
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Attraper le loup !",
cases: [],
caseMouton: "<img src='./images/mouton.png' height='100' width='100'>",
caseLoup: "<img src='./images/loup.png' height='100' width='100'>"
}
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = this.caseMouton;
}
this.cases[this.getRandomInt(0,24)] = this.caseLoup;
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
<head>
.
.
.
</head>
<body>
<div id="app">
<h1>{{ titre }}</h1>
<div class="plateau">
<div class='cellule' v-html='cases[0]'></div>
.
.
.
<div class='cellule' v-html='cases[24]'></div>
…
Etape 3 : Faire bouger le loup toutes les secondes
Objectif : Déplacer le loup toutes les secondes dans la grille.
puis
puis
Principe à découvrir : la fonction setInterval.
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Attraper le loup !",
cases: [],
caseMouton: "<img src='./images/mouton.png' height='100' width='100'>",
caseLoup: "<img src='./images/loup.png' height='100' width='100'>",
numCaseLoup : 0
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = this.caseMouton;
}
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
setInterval(this.deplaceLoup, 1000);
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
deplaceLoup() {
this.cases[this.numCaseLoup] = this.caseMouton;
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Explications :
Aucune modification à effectuer dans le fichier html.
Dans le modèle :
· Dans data(), ajout d'une valeur numCaseLoup. Celle-ci contiendra le numéro de la case contenant le loup.
· Création de la méthode "deplaceLoup()" qui permet de mettre un mouton dans la case -contenant le loup et de placer un loup aléatoirement dans une autre case de la grille.
· Dans beforeMount, on place la fonction setInterval. Celle-ci lance la fonction deplaceLoup() toutes les secondes. Et entraine donc le déplacement du loup à intervalle d'une seconde.
Etape 4 : Compter le nombre de clics sur la grille
Objectif : Compter le nombre de fois que l'utilisateur clique sur la grille pour essayer d'attraper le loup.
Principe à découvrir : Gestion des évènements avec Vue js.
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Le loup est a la case : ",
cases: [],
caseMouton: "<img src='./images/mouton.png' height='100' width='100'>",
caseLoup: "<img src='./images/loup.png' height='100' width='100'>",
numCaseLoup : 0,
nbEssai : 0
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = this.caseMouton;
}
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
setInterval(this.deplaceLoup, 1000);
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
deplaceLoup() {
this.cases[this.numCaseLoup] = this.caseMouton;
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
},
attraper() {
this.nbEssai++;
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
<head>
.
.
.
</head>
<body>
<div id="app">
<h1>{{ titre }}{{ numCaseLoup + 1 }}</h1>
<div class="plateau">
<div class='cellule' v-html='cases[0]' @click="attraper"></div>
<div class='cellule' v-html='cases[1]' @click="attraper"></div>
.
.
.
<div class='cellule' v-html='cases[24]' @click="attraper"></div>
</div>
<span>Vous avez essayé : {{ nbEssai }} fois !</span>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel5.js"></script>
</body>
</html>
Explications :
Dans le fichier html :
· On modifie le titre pour afficher la position du loup.
· Ajout d'un évènement (ici le clic => @click ou v-on:click) sur les div des cellules. Au clic on lance la fonction attraper.
· Ajout d'un span pour afficher le nombre de clics effectués.
Dans le modèle :
· Modification de la valeur titre dans data().
· Ajout d'une valeur nbEssai dans data().
· Création de la méthode attraper. Celle-ci va compter le nombre de clics.
Etape 5 : Arrêter le jeu et mettre une image "OK" quand le loup est attrapé
Objectif : Détecter quand l'utilisateur clique sur le loup et mettre l'image OK.
Principe à découvrir : Passer des valeurs en arguments d'une méthode avec les évènements.
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Le loup est a la case : ",
cases: [],
caseMouton: "<img src='./images/mouton.png' height='100' width='100'>",
caseLoup: "<img src='./images/loup.png' height='100' width='100'>",
caseAttrape: "<img src='./images/ok.png' height='100' width='100'>",
numCaseLoup : 0,
nbEssai : 0,
interval : '',
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = this.caseMouton;
}
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
this.interval = setInterval(this.deplaceLoup, 1000);
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
deplaceLoup() {
this.cases[this.numCaseLoup] = this.caseMouton;
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
},
attraper(numCaseClique) {
this.nbEssai++;
if (numCaseClique == this.numCaseLoup)
{
this.cases[this.numCaseLoup] = this.caseAttrape;
clearInterval(this.interval);
}
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
.
.
.
<h1>{{ titre }}{{ numCaseLoup + 1 }}</h1>
<div class="plateau">
<div class='cellule' v-html='cases[0]' @click="attraper(0)"></div>
<div class='cellule' v-html='cases[1]' @click="attraper(1)"></div>
.
.
.
<div class='cellule' v-html='cases[24]' @click="attraper(24)"></div>
</div>
<span>Vous avez essayé : {{ nbEssai }} fois !</span>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel6.js"></script>
</body>
</html>
Explications :
Dans le fichier html :
· On ajoute en paramètre effectif de la méthode attraper le numéro de la case.
Dans le modèle :
· Ajout d'une valeur caseAttrape dans data(). Celle-ci va contenir le code html de l'affichage de l'image OK.png.
· Ajout d'une valeur interval dans data().
· On affecte à la valeur interval le setInterval(…). Le setInterval sera toujours lancé mais aussi affecté à cette valeur interval.
· On modifie la méthode attraper en lui ajoutant un paramètre (numéro de la case sur laquelle on a cliqué) et en ajoutant le test permettant de contrôler si le numéro de la case loup correspond au numéro de la case cliquée. Si c'est le cas, on remplace l'image du loup par l'image ok dans cette case et on arrête l'interval (=> le loup ne bouge plus)..
Etape 6 : Afficher un message conditionnel
Objectif : Si l'utilisateur clique sur un mouton, afficher le message "Le loup court toujours !" et si l'utilisateur clique sur le loup, afficher le message "Bien joué vous avez attrapé le loup !".
Principe à découvrir : La directive v-if et v-else.
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Le loup est a la case : ",
cases: [],
caseMouton: "<img src='./images/mouton.png' height='100' width='100'>",
caseLoup: "<img src='./images/loup.png' height='100' width='100'>",
caseAttrape: "<img src='./images/ok.png' height='100' width='100'>",
numCaseLoup : 0,
nbEssai : 0,
interval : '',
attrape : false,
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = this.caseMouton;
}
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
this.interval = setInterval(this.deplaceLoup, 1000);
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
deplaceLoup() {
this.cases[this.numCaseLoup] = this.caseMouton;
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
},
attraper(numCaseClique) {
this.nbEssai++;
if (numCaseClique == this.numCaseLoup)
{
this.cases[this.numCaseLoup] = this.caseAttrape;
this.attrape = true;
clearInterval(this.interval);
}
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
.
.
.
<body>
<div id="app">
<h1>{{ titre }}{{ numCaseLoup + 1 }}</h1>
<div class="plateau">
.
.
.
</div>
<span>Vous avez essayé : {{ nbEssai }} fois !</span>
<br>
<span v-if="attrape">Bien joué vous avez attrapé le loup !</span>
<span v-else>Le loup court toujours !</span>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel7.js"></script>
</body>
</html>
Explications :
Dans le fichier html :
·
On ajoute 2 span. Le 1er affiche "Bien joué…" si attrape
= true (v-if="attrape").
Le second affiche "Le loup court toujours !" dans le cas
contraire.
Dans le modèle :
· Ajout d'une valeur attrape dans data(). Celle-ci est initialisée à false.
· Dans la méthode attraper on affecte la valeur true à attrape si la case cliquée est la bonne.
Etape 7 : Améliorer le code html pour afficher la grille en une seule ligne
Objectif : Afficher la grille en une ligne au lieu des 25 actuellement (<div class='cellule' v-html='cases[0]'></div>. . .<div class='cellule' v-html='cases[24]'></div>).
Principe à découvrir : La directive v-for.
Pas de modification du modèle.
Modification du fichier html ("view2.html") pour devenir :
<html>
.
.
.
<div class="plateau">
<div class='cellule' v-for="(currentCase, i) in cases" v-html='currentCase' @click="attraper(i)"></div>
</div>
<span>Vous avez essayé : {{ nbEssai }} fois !</span>
<br>
<span v-if="attrape">Bien joué vous avez attrapé le loup !</span>
<span v-else>Le loup court toujours !</span>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel8.js"></script>
</body>
</html>
Explications :
Dans le fichier html :
· La directive "v-for" permet de parcourir chaque élément du tableau cases. Chaque élément est récupéré dans currentCase et i récupère l'ordre de passage (0 pour le 1er tour de boucle, 1 pour le 2ème, … , 24 pour le 25ème).
Pas de modification dans le modèle.
Etape 8 : Ajouter un bouton Démarrer et pouvoir régler la vitesse de déplacement du loup
Objectif
: Permettre à l'utilisateur de démarrer et arrêter le jeu à l'aide
d'un bouton.
Régler la vitesse de déplacement du loup à l'aide d'un
"slider".
Principe à découvrir : La directive v-model ("lien bidirectionnel").
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Le loup est a la case : ",
cases: [],
caseMouton: "<img src='./images/mouton.png' height='100' width='100'>",
caseLoup: "<img src='./images/loup.png' height='100' width='100'>",
caseAttrape: "<img src='./images/ok.png' height='100' width='100'>",
numCaseLoup : 0,
nbEssai : 0,
interval : '',
attrape : false,
demarre : false,
vitesse : 1000,
}
},
beforeMount(){
for (var i=0; i<25; i++)
{
this.cases[i] = this.caseMouton;
}
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
/* Ligne supprimée
this.interval = setInterval(this.deplaceLoup, 1000);
*/
},
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
deplaceLoup() {
this.cases[this.numCaseLoup] = this.caseMouton;
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
},
attraper(numCaseClique) {
this.nbEssai++;
if (numCaseClique == this.numCaseLoup)
{
this.cases[this.numCaseLoup] = this.caseAttrape;
this.attrape = true;
clearInterval(this.interval);
}
},
demarrer() {
if (this.demarre)
{
clearInterval(this.interval);
this.demarre = false;
}
else
{
this.interval = setInterval(this.deplaceLoup, this.vitesse);
this.demarre = true;
}
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
…
<body>
<div id="app">
<h1>{{ titre }}{{ numCaseLoup + 1 }}</h1>
<br>
<input type="button" :value="demarre ? 'Arreter' : 'Demarrer'" @click="demarrer" />
<br>
<br>
<input type="text" v-model="vitesse" />
<input type="range" min="100" max="2000" v-model="vitesse"/>
<div class="plateau">
<div class='cellule' v-for="(currentCase, i) in cases" v-html='currentCase' @click="attraper(i)"></div>
</div>
…
</html>
Explications :
Dans le fichier html :
·
On ajoute d'abord un bouton qui prendra la valeur "Arreter" ou
"Demarrer" suivant la valeur de l'élément demarre du
modèle.
L'expression javascript "demarre ? 'Arreter' : 'Demarrer'" signifie
si demarre est à vrai alors le bouton prendra la valeur
'Arreter' sinon la valeur 'Demarrer'.
On ajoute également l'évènement click sur ce bouton (@click). Le
clic lancera la fonction demarrer du modèle.
· On ajoute ensuite un champ texte que l'on relie, de façon bidirectionnelle, à la propriété vitesse du modèle. => si vitesse évolue dans le modèle cela se répercute dans le html et inversement.
· On ajoute enfin un "slider", c’est-à-dire un input de type range. Celui-ci sera également relié de façon bidirectionnelle à la propriété vitesse du modèle.
Dans le modèle :
· Dans data() on ajout une valeur demarre que l'on initialise à false et une valeur vitesse que l'on initialise à 1000.
· On supprime la ligne "this.interval = setInterval(this.deplaceLoup, 1000);".de beforeMount.
· On ajoute la méthode demarrer qui va arrêter le déplacement du loup si la valeur demarre est à true et lancer le déplacement si la valeur demarre est à false.
Etape 9 : Mettre des "styles dynamiques"
Objectif : Encadrer le nombre d'essais effectués, en rouge lorsque l'utilisateur essaye de cliquer sur le loup et en vert quand il a réussi.
Principe à découvrir : Les styles dynamiques .
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
return {
titre: "Le loup est a la case : ",
.
.
.
vitesse : 1000,
essai : false,
}
},
.
.
.
methods: {
getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
deplaceLoup() {
this.cases[this.numCaseLoup] = this.caseMouton;
this.numCaseLoup = this.getRandomInt(0,24);
this.cases[this.numCaseLoup] = this.caseLoup;
},
attraper(numCaseClique) {
this.nbEssai++;
this.essai = true;
if (numCaseClique == this.numCaseLoup)
{
this.cases[this.numCaseLoup] = this.caseAttrape;
this.attrape = true;
clearInterval(this.interval);
}
},
.
.
.
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
<head>
<meta charset="utf-8">
<title>Cours Vue.js - 2</title>
<style>
.plateau {
display: grid;
grid-template-columns: 100px 100px 100px 100px 100px;
}
.red {
border: 3px solid red;
}
.green {
border: 3px solid green;
}
</style>
</head>
<body>
<div id="app">
<h1>{{ titre }}{{ numCaseLoup + 1 }}</h1>
<br>
<input type="button" :value="demarre ? 'Arreter' : 'Demarrer'" @click="demarrer" />
<br>
<br>
<input type="text" v-model="vitesse" />
<input type="range" min="100" max="2000" v-model="vitesse"/>
<div class="plateau">
<div class='cellule' v-for="(currentCase, i) in cases" v-html='currentCase' @click="attraper(i)"></div>
</div>
<span :class="{red: essai, green: attrape}" >Vous avez essayé : {{ nbEssai }} fois !</span>
<br>
<span v-if="attrape">Bien joué vous avez attrapé le loup !</span>
<span v-else>Le loup court toujours !</span>
</div>
…
</html>
Explications :
Dans le fichier html :
· On ajoute 2 styles. .red pour définir un encadré rouge et green pour un encadré vert.
· Dans le span dans lequel on affiche le message "Vous avez essayé…" on ajoute un :class permettant de définir un style red si essai est à true ou green si attrape est à true. Si les 2 sont à true alors l'encadré vert "écrase" l'encadré rouge.
Dans le modèle :
· On ajoute une valeur essai dans data(). Celle-ci est initialisée à false.
· Dans la méthode attraper on ajoute l'instruction "this.essai = true".
Etape 10 : Mettre des "styles dynamiques" avec un objet et sans CSS
Objectif : Afficher le texte "Vitesse : " en : rouge si celle-ci est inférieure ou égale à 500, orange si celle-ci est comprise entre 501 et 1000 et verte si celle-ci est supérieure à 1000.
Principe à découvrir : Les styles dynamiques avec un objet et les propriétés calculées.
Modification du fichier javascript ("viewModel2.js") pour devenir :
var app = Vue.createApp({
data() {
.
.
.
}
},
beforeMount(){
.
.
.
},
methods: {
.
.
.
},
computed: {
colorieVitesse() {
if (this.vitesse > 1000)
{
return {color: 'green'};
}
else
{
if (this.vitesse > 500)
{
return {color: 'orange'};
}
else
{
return {color: 'red'};
}
}
}
}
});
app.mount('#app');
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"
Modification du fichier html ("view2.html") pour devenir :
<html>
<head>
.
.
.
</head>
<body>
<div id="app">
<h1>{{ titre }}{{ numCaseLoup + 1 }}</h1>
<br>
<input type="button" :value="demarre ? 'Arreter' : 'Demarrer'" @click="demarrer" />
<br>
<br>
<span :style="colorieVitesse" >Vitesse : </span>
<input type="text" v-model="vitesse" />
<input type="range" min="100" max="2000" v-model="vitesse"/>
<div class="plateau">
<div class='cellule' v-for="(currentCase, i) in cases" v-html='currentCase' @click="attraper(i)"></div>
</div>
<span :class="{red: essai, green: attrape}" >Vous avez essayé : {{ nbEssai }} fois !</span>
<br>
<span v-if="attrape">Bien joué vous avez attrapé le loup !</span>
<span v-else>Le loup court toujours !</span>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="./viewModel11.js"></script>
</body>
</html>
Explications :
Dans le fichier html :
· On ajoute un span dans lequel on affiche le message "Vitesse : " on applique le style de la propriété calculée colorieVitesse.
Dans le modèle :
· On ajoute une propriété calculée colorieVitesse(), dans computed:. Dans celle-ci on place les instructions conditionnelles afin de retourner l'objet {color: 'green'} ou {color: 'orange'} ou {color: 'red'} suivant la valeur de this.vitesse.
Il existe encore beaucoup de directives et de fonctionnalités à découvrir avec Vue js mais celle-ci seront abordées en fin d'année.
Cependant, avec les directives étudiées dans ce cours, vous pourrez déjà concevoir une partie front de votre application web performante et réactive.