
Comment débuter votre aventure avec Vue.js ?
Les technologies front-end sont un domaine de l'industrie du développement logiciel qui connaît une croissance presque exponentielle. De plus en plus souvent, lors du démarrage de nouveaux projets, les développeurs décident d'abandonner le JavaScript pur et jQuery pour les remplacer par des frameworks modernes afin de construire la couche client des applications. Puis, ils sont confrontés à un dilemme – lequel utiliser ? Généralement, trois sont pris en compte : Vue, React et Angular. Dans cet article, nous présenterons les bases du premier d'entre eux de la manière la plus simple et conviviale possible.
Qu'est-ce que Vue.js ?
Vue.js, tout comme React.js et Angular, appartient à la famille des frameworks JavaScript les plus populaires utilisés pour construire des interfaces utilisateur (UI). Il permet aux développeurs de créer à la fois des composants simples, ainsi que des applications monopages avancées et évolutives en utilisant des outils et des bibliothèques supplémentaires.
Instance Vue et modèles
Au tout début de nos réflexions, nous devons nous habituer à la manière de lier le modèle avec la couche logique de JavaScript. Pour cela, nous discuterons de la création d'une instance Vue() et de ses propriétés de base. Tout d'abord, cependant, pour pouvoir l'utiliser dans notre document, nous devons inclure le code d'une bibliothèque disponible, par exemple, à partir d'un CDN.
HTML
<body>
<div id="app">
<p>{{ message }}</p>
<p>{{ capitalize() }}</p>
<p>{{ reversedMessage }}</p>
</div>
</body>
JavaScript
const app = new Vue({
el: '#app',
data: {
message: 'Hello world',
},
methods: {
capitalize () {
return this.message.toUpperCase()
}
},
computed: {
reversedMessage () {
return this.message.split('').reverse().join('')
}
}
})
L'action principale que nous devons effectuer dès le début est de lier l'objet Vue avec un élément DOM spécifique dans notre document. L'instance Vue doit connaître la portée dans laquelle elle doit fonctionner et cela doit être clairement défini. Nous le faisons en fournissant le nom du sélecteur de propriété el de l'objet, que nous passons en argument du constructeur Vue(). Grâce à cela, chaque enfant de l'élément défini sera observé et traité comme un arbre DOM virtuel.
La propriété data contient des champs que nous allons utiliser pour stocker des données, les méthodes conservent les définitions des méthodes disponibles dans la portée de l'instance. Les méthodes calculées sont des valeurs calculées dynamiquement. Nous les définissons comme des méthodes, mais lorsqu'elles sont utilisées, nous les utilisons comme un champ régulier (Vue les calcule automatiquement). C'est extrêmement utile, par exemple, dans les situations où vous souhaitez modifier une valeur quelconque, mais qu'utiliser une méthode classique n'est pas la meilleure solution (par exemple à cause d'un grand nombre de dépendances).
Un autre point important concerne la référence à l'une des propriétés ci-dessus, qui se fait à l'aide de cette référence. Cela est possible grâce au fait que Vue connecte toutes les propriétés avec l'instance principale de l'objet, ce qui permet un accès direct à celles-ci.
Il vaut également la peine de noter l'utilisation des champs et des méthodes dans le modèle. Tout ce qui est censé être affiché dans le document est placé dans des accolades doubles {{ }}. La seule chose à garder à l'esprit est qu'une telle syntaxe ne peut être utilisée que dans les éléments #app imbriqués.
Directives
Les directives sont des attributs spéciaux utilisés dans les modèles. Elles sont précédées du préfixe v-, par exemple : v-if, v-else, v-for, v-model, v-bind. Il est bon de se rappeler que beaucoup d'entre elles ont des alias qui peuvent être utilisés de manière interchangeable.
v-if
Permet le rendu conditionnel de l'élément DOM auquel la directive est assignée.
HTML
<div id="app">
<p v-if="isVisible">
Un paragraphe
</p>
<button @click="toggle">
Basculez-moi !
</button>
Javascript
const app = new Vue({
el: '#app',
data: {
isVisible: true,
},
methods: {
toggle () {
this.isVisible = !this.isVisible
}
},
})
v-on
Permet de lier des auditeurs d'événements à des éléments DOM sélectionnés.
Alias
v-on:click=”someMethod” -> @click=”someMethod”
HTML
<div id="app">
<p v-if="isVisible">Un paragraphe</p>
<button @click="toggle">Basculez-moi !</button>
</div>
HTML version 2
<div id="app">
<p v-if="isVisible">Un paragraphe</p>
<button v-on:click="isVisible = !isVisible">
Basculez-moi !
</button>
JavaScript
const app = new Vue({
el: '#app',
data: {
isVisible: true,
},
methods: {
toggle () {
this.isVisible = !this.isVisible
}
},
})
v-for
Permet d'exécuter une boucle sur l'élément DOM associé.
HTML
<div id="app">
<p v-for="person in people">
{{ person.name }} a {{ person.age }} ans.
</p>
JavaScript
const app = new Vue({
el: '#app',
data: {
people: [
{ name: 'John', age: 10 },
{ name: 'Mark', age: 20 },
{ name: 'Jeff', age: 30 },
]
},
})
Le résultat
v-bind
Permet de lier aux attributs des éléments DOM.
Alias
v-bind:title=”someTitle” -> :title=”someTitle”
HTML version 1
<div id="app">
<p v-bind:class="className">Un paragraphe</p>
<button @click="toggle">Changer la couleur</button>
HTML version 2
<div id="app">
<p :class="className">Un paragraphe</p>
<button @click="toggle">Changer la couleur</button>
Javascript
const app = new Vue({
el: '#app',
data: {
className: 'red',
},
methods: {
toggle () {
this.className = this.className === 'red'
? 'blue'
: 'red'
}
}
})
v-model
Permet de lier des éléments DOM tels que <input> aux champs de l'objet data.
HTML
<div id="app">
<input type="text" v-model="inputValue" name="exampleInput">
<p>{{ inputValue }}</p>
JavaScript
const app = new Vue({
el: '#app',
data: {
inputValue: ''
}
})
Composants
Les composants sont des instances Vue, vous permettant de réutiliser à plusieurs reprises des fragments de code de manière universelle. Cela vous permet d'éviter les répétitions, et donc de respecter le principe DRY (Don't Repeat Yourself). Grâce à cela, l'application est propre et le code est lisible, et si besoin est, vous n'avez pas à corriger des bogues à de nombreux endroits.
HTML
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
JavaScript
Vue.component('button-counter', {
data () {
return {
count: 0
}
},
template: `
<button v-on:click="count++">
Vous m'avez cliqué {{ count }} fois.
</button>
`
})
Le résultat
Le composant est défini à l'aide de Vue.component. Le premier argument de la méthode est le nom de l'élément DOM à utiliser dans les modèles. Le deuxième paramètre est un objet qui, dans ce cas, a deux propriétés. La plus importante d'entre elles est le modèle, qui sera remplacé dans l'arbre DOM réel chaque fois que le composant est utilisé. La deuxième propriété de l'objet est la méthode data (méthode, pas l'objet !) qui retourne un objet avec les données qui seront disponibles pour un seul composant.
Les composants peuvent être imbriqués les uns dans les autres, ce qui vous permet de construire des structures de modèles plus avancées et complexes. L'exemple ci-dessous montre deux exemples simples : parent et enfant. Des balises spéciales <slot></slot> ont été utilisées, qui servent de substitut. Tout ce qui a été placé dans l'élément parent est rendu à leur place.
HTML
<div id="app">
<parent>
<child></child>
<child></child>
<child></child>
</parent>
JavaScript
Vue.component('parent', {
template: '<div><slot></slot></div>',
})
Vue.component('child', {
template: `<p>Je suis un enfant !</p>`
})
const app = new Vue({
el: '#app',
})
Le résultat
Événements
Nous avons traité de la gestion des événements lorsque nous avons parlé de la directive v-on. Nous allons l'utiliser pour ajouter un écouteur d'événements, qui écoutera la survenue d'un événement défini, et après l'avoir déclenché, il effectuera une action spécifique (par exemple, il invoquera une méthode). Allons un peu plus loin et réfléchissons à ce que la communication entre composants ressemble dans le contexte des événements. Ici, vous pouvez imaginer une situation simple dans laquelle nous avons un arbre DOM composé d'un élément parent et d'un enfant imbriqué. La question est : comment informer le parent qu'un événement a été déclenché à partir du niveau d'un élément imbriqué ? Analysons l'exemple ci-dessous.
HTML
<div id="app">
<div>
<example @execute="onExecute"></example>
</div>
JavaScript
Vue.component('example', {
template: `
<button @click="execute">
Exécutez !
</button>
`,
methods: {
execute () {
this.$emit('execute')
}
}
})
const app = new Vue({
el: '#app',
methods: {
onExecute () {
alert('Faire des choses incroyables...')
}
}
})
Tout d'abord, notons le composant exemple dont le modèle contient un bouton standard. La méthode execute, qui effectue une action clé, est invoquée lorsqu'on clique dessus. Pour l'objet composant, la méthode $emit est invoquée, ce qui émet un événement qui peut ensuite être intercepté par le composant de couche supérieure. Le premier argument de la méthode est le nom de l'événement parent @execute. Dans le second (qui est absent dans cet exemple), vous pouvez ajouter les données que vous souhaitez passer à la méthode invoquée par l'événement parent.
Cependant, la méthode ci-dessus n'est pas entièrement efficace lorsque vous traitez un grand nombre de composants imbriqués, car, pour informer le premier d'entre eux, vous devez utiliser cette procédure avec chaque enfant. Il est facile d'imaginer l'impact négatif de cette approche sur la maintenance de l'application. L'une des solutions à ce problème est la création d'une nouvelle instance Vue, la liaison à l'objet global window, puis (basé sur le mécanisme de liaison de toutes les propriétés de l'objet par Vue) l'utilisation de méthodes telles que $emit (pour émettre l'événement) et $on (pour écouter l'événement et effectuer l'action en réponse). De cette façon, peu importe comment les composants sont imbriqués, les événements peuvent être gérés dans l'ensemble de l'application.
HTML
<div id="app">
<div>
<example></example>
</div>
JavaScript
window.Event = new Vue()
Vue.component('example', {
template: '<button @click="execute">Exécutez !</button>',
methods: {
execute () {
Event.$emit('execute')
}
}
})
const app = new Vue({
el: '#app',
created () {
Event.$on('execute', () => alert('Faire des choses incroyables...'))
}
})
Cycle de vie
Vue, tout comme React ou Angular, possède un cycle de vie des composants et des événements auxquels vous pouvez réagir. Il existe plusieurs méthodes qui valent la peine d'être notées, car elles sont extrêmement utiles dans de nombreuses situations courantes. Un des exemples peut être le chargement de données à partir d'une API externe, utilisant des requêtes AJAX dès qu'un composant est créé par Vue. Les événements d'objet les plus fréquemment utilisés sont : created, mounted, updated.
Utilisation dans des applications de taille moyenne et grande
Après avoir présenté les mécanismes de base, nous pouvons parler de questions liées aux méthodologies réelles de construction d'applications dans Vue. À cette fin, nous allons construire une application simple avec l'aide de vue-cli – une application console basée sur node.js, grâce à laquelle nous pourrons gérer notre application depuis le terminal. Pour installer vue-cli, vous devez avoir node.js et npm/yarn, puis exécuter une des commandes :
Utilisez les commandes suivantes pour créer une application :
npm install -g @vue/cli
ou
yarn global add @vue/cli
Pour créer l'application, utilisez :
vue create [nom-du-projet]
Cette commande créera un projet avec l'arbre suivant de répertoires et de fichiers :
├── babel.config.js
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ └── index.html
├── README.md
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── HelloWorld.vue
└── main.js
Aux fins de cet article, nous allons nous concentrer uniquement sur quatre fichiers, qui auront un impact visible sur notre application (le reste d'entre eux sont principalement des fichiers de configuration, dont nous ne parlerons pas ici). Ils ont été légèrement modifiés afin de permettre de présenter une approche appropriée. Ils sont :
- public/index.html
- src/main.js
- src/App.vue
- src/components/HelloWorld.vue
public/index.html
Par défaut, chaque application Web commence par un fichier index.* – rien n'a été changé à cet égard. La seule chose dont nous devons prendre note est de définir notre élément DOM principal, que nous allons utiliser pour lier notre instance Vue principale.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>mon-projet-génial</title>
</head>
<body>
<noscript>
<strong>Nous sommes désolés mais mon-projet-génial ne fonctionne pas correctement sans JavaScript activé. Veuillez l'activer pour continuer.</strong>
</noscript>
<div id="app"></div>
<!-- les fichiers construits seront automatiquement injectés -->
</body>
</html>
src/main.js
Un point de départ dans le contexte de la logique JavaScript. Trois choses de base se produisent ici et qui valent la peine d'être examinées.
- Une instance Vue est créée.
- Le rendu du composant de plus haut niveau est déplacé vers App.vue.
- L'instance Vue est liée à l'élément #app dans le fichier index.html.
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
src/App.vue
Pour comprendre comment fonctionne le code de ce fichier, nous devons discuter de la structure des composants à fichier unique. Selon ce concept, comme le nom l'indique, chaque composant doit se trouver dans un fichier séparé et avoir l'extension *.vue. Jetons un œil à l'exemple ci-dessous.
<template>
<div id="app-container">
<hello-world message="Bienvenue dans votre application Vue.js"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
<style>
#app-container {
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Nous pouvons distinguer trois éléments principaux du contenu du fichier.
template
Modèle de composant. Ici, nous mettons le code, qui jusqu'à présent était dans la propriété du modèle.
script
Logique du composant. Comme vous pouvez le voir, nous n'utilisons pas Vue.component ici (c'est la définition d'un composant global). Vous devez garder à l'esprit que vous ne pouvez pas vous y référer sans l'importer au préalable. De plus, le nom du composant importé doit être placé dans le champ components de l'objet exporté afin que le framework convertisse correctement le modèle en syntaxe HTML réelle.
style
Styles liés au composant. Ici, vous pouvez utiliser le CSS pur ou utiliser un des préprocesseurs connus : Sass, Less ou Stylus. Lors de la construction d'une application, un tel code sera compilé en CSS compatible avec les navigateurs.
src/HelloWorld.vue
Le deuxième composant à fichier unique dans notre application. Regardez de plus près la façon dont les propriétés sont transmises. App.vue contient son propre attribut message, qui est ensuite ajouté à la table props dans le sous-composant. L'attribut de portée dans la balise <style> vaut également la peine d'être examiné de plus près. Il s'assure que le style ne s'appliquera qu'à ce composant. En se référant à l'exemple ci-dessus, cela signifie que les paragraphes seront rouges uniquement dans le composant HelloWorld.
<template>
<div class="hello">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: ['message']
}
</script>
<style scoped>
p {
color: red;
}
</style>
La prochaine étape du développement de l'application est la même. Vous pouvez créer des structures de composants complexes afin d'atteindre le résultat désiré sous la forme d'une application complète et fonctionnelle. Il existe une large gamme de bibliothèques et d'extensions dédiées à Vue. Vous pouvez enrichir votre application avec le routage (Vue-Router), Vuex (équivalent Redux), des composants prêts à l'emploi de frameworks CSS (par exemple Bootstrap, Foundation), ainsi que des bibliothèques (Lodash, Axios) et bien d'autres. Les possibilités sont presque infinies.
Et ensuite ?
Dans cet article, nous avons présenté les bases mêmes de la création d'applications simples avec Vue.js. Nous avons appris les mécanismes fondamentaux implémentés dans le framework. Nous savons déjà comment fonctionne une instance Vue, ce que sont les directives et comment construire des composants réutilisables. Nous savons également comment aborder le développement d'applications en utilisant npm et vue-cli.
Cependant, les connaissances présentées ici sont vraiment basiques, c'est pourquoi il vaut la peine de se familiariser avec des techniques plus avancées (voir « Sources recommandées »). Cela peut apporter un certain nombre d'avantages : une bonne connaissance de l'un des frameworks JavaScript modernes accélère la création d'une couche cliente, le code est mieux organisé et moins sujet aux erreurs, ce qui se traduit par des applications front-end attrayantes et complexes.
Sources Recommandées
Un trésor de connaissances sur Vue.js :
https://github.com/vuejs/awesome-vue
Une série de tutoriels gratuits qui complète parfaitement cet article :
https://laracasts.com/series/learn-vue-2-step-by-step
Cours payant sur Udemy :
https://www.udemy.com/vuejs-2-the-complete-guide