Eric Le Codeur

Suivez-moi
cover image

Apprendre Vue.js 3 - Jour 1 : concepts de base

Javascript VueJS

Série d'article sur Vue.js 3

Bonjour, cici est le premier article d'une série d'article qui couvrira le monde de Vue 3. Cet article ce veut un résumé de mes notes et du coup un excellent aide-mémoire (cheat sheet)

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 outils.

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 future développement

Extensions VSCode 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
  • settings.json :
emmet.includeLanguages: {
    'vue' : 'html',
	'vue-html': 'html'
}

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.

Voici ce qu'il faut faire pour utiliser Vue seulement dans une partie de votre 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 votre fichier application Vue (app.js)
  • Créer une div avec id="app" qui servira de conteneur au rendu de votre application Vue.

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>
	</boby>
</html>

(app.js)

// fonction qui permet d'initialiser Vue.js
Vue.createApp({
	data() {
		return {
			title: "Hello Word Vue"
		}
	}
}).mount('#app') 
// mount spécifie que l'application Vue s'affichera dans la div avec id="app"

Variables Reactive

La fonction data() sert à créer des variables réactives qui seront utilisé dans votre application Vue. Chaque fois qu'une variable réactive est modifié, si elle est affiché ou utilisé 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() }}

Les directives Vue.js

Les directives Vue.js sont des attributs html qui peuvent être inséré dans votre page afin de modifier le rendu de votre application Vue.

Voici la liste des directives disponible:

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"

<img v-bind:src="image_url" />

// ou syntaxe raccourci
<img :src="image_url" />

v-once

Avec la directive v-once Vue va interpolé l'expression seulement une fois. L'expression sera donc ignoré pour tous les autres rafraichissement

<div v-once>
   {{ title }}
</div>

v-html

Permet d'afficher une expression avec des tags HTML.

<div v-html="title">
</div>

v-model

Permet de lier la valeur d'un champs de saisie avec une variable. Si vous modifié 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>

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ément

<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

Ref

Permet à votre 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 possibile 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. Vue va regrouper ces deux attributs lors du rendu.

Il est également possible d'utiliser un object 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éfinit 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 'template'

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érieur à zéro
</template>

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: suivit 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 le appuie d'une touche (ex. enter)

<button v-on:keydown.enter="name = 'Mike'">Afficher message</button>

// ou syntaxe raccourci
<button @click="name = 'Mike'">Afficher message</button>

Autre valeurs possibles pour v-on:keydown, keyup, keypress

Autre valeur 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.

Les méthodes

Vue js permet de créer des méthodes afin d'y placer un block de code réutilisable dans votre applications. Voici la syntaxe pour créer un 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érieure 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'object 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'object event à notre méthode

Les méthodes "computed"

Contrairement aux autres méthodes qui vont se ré-exécuté à chaque rendu de votre application, les méthodes "computed" vont être ré-exécuté seulement si les variables quelle contiennent sont modifié.

computed: {
    recalculerTotal(items, taxes) {
        return  this.calculerTotal(items, taxes)
    }
}

Les méthodes "computed" peuvent ensuite être appelé 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 quelle 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

Les "Components"

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 et 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'
        }
    },
    methodes: {
        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é 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 ou vous avez placé votre tag component dans votre page html

L'objet "props" définit quel data est attendu 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>

Créer un application entière avec Vue CLI

L'outils pour créer un projet Vue.js est Vue CLI. Vous devrez l'installé

npm install -g @vue/cli

Vue create

Permet de créer un projet Vue.js avec plein de truc déjà pré-configuré pour vous.

vue create my-app-name

npm run serve

Une fois l'application créer 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é 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 'template' de chacun de vos components

Vite

Il est également possible de créer un projet avec Vite. C'est un outils 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é-configuration 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éfinit 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 saisie dans la section template. Il n'est pas saisie 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éfinit/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é 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éfinit dans le component enfant, donc devra utiliser les variables ou le css définit 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 syntax v-slot:title p eut é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 balise ici sont optionnelles) mais il est possible d'ajouter un second slot avec un nom

Slot Props

Les slot peuvent avoir des props

<template>
  <slot name="title" satus="info"></slot>
</template>

Les Props peuvent ensuite être utilisé

<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>

Conclusion

Merci d'avoir lu cet article. Si vous avez aimez ou si vous avez des commentaires n'hésitez pas à les enter ici bas.

Commentaires