Académique Documents
Professionnel Documents
Culture Documents
Dans cet atelier, on va effectuer des opérations CRUD à l'aide de l'API Web dans VueJS. Les services
qu’on va consommer provenant d’un fichier JSON. En effet, on va apprendre comment créer et
consommer un RESTful. Pour gérer les données dans un serveur, on utilisera GET, POST, PUT et Delete
à travers HttpClient API. De plus, on va intégrer le Framework Bootstrap aux interfaces créées.
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.
Pour installer le projet Vue, nous devons avoir Vue CLI installé sur notre système de développement.
Exécutez la commande suivante pour installer Vue CLI :
npm install -g @vue/cli
Une fois le serveur hébergé et l'application démarrée, vous pouvez accéder à http://localhost:8080/.
La réponse doit être quelque chose de similaire à la sortie, comme ci-dessous.
2. Les composants d’un projet Vue
Presque tous les Framework front-end nous permettent de créer des composants que nous pouvons
réutiliser à plusieurs endroits sur le même site Web ou sur des sites Web différents. Certains exemples
incluent une barre de recherche, un formulaire de connexion, un composant d'affichage du produit,
etc. Dans Vue, les fichiers avec l'extension ".vue" sont appelés composants de fichier unique. Ces
composants de fichier unique sont composés de HTML, JavaScript et CSS.
<template>
<!-- HTML Template -->
</template>
<script>
export default {}
</script>
<style>
</style>
Passons en revue la structure des dossiers de notre projet Vue nouvellement créé :
*src/assets *— stocke les fichiers multimédias comme les images, les logos, etc.
*src/components *— stocke tous les composants réutilisables de notre projet. Ces composants ne
sont pas uniques à un itinéraire spécifique.
main.js **— c'est le point de départ de notre projet. Ici, nous importerons notre composant racine
**App.vue, notre fichier de routeur index.js et la méthode createApp.
La structure des dossiers n'est pas obligatoire telle qu’elle est, nous pouvons la personnaliser selon nos
besoins.
Bootstrap est une collection d'outils utiles à la création du design de sites et d'applications web.
npm install bootstrap
b. Axios
Pour les projets qui doivent s'interfacer avec une API REST, Axios est un client HTTP léger basé sur le
service $http et similaire à l'API Fetch.
Axios est basé sur des promesses et nous pouvons donc profiter de async et await plus lisible. Nous
pouvons également intercepter et annuler des demandes, et il existe une protection côté client
intégrée contre la falsification des demandes intersites.
npm install axios
c. Router
Le terme « Applications monopages » (SPA) indique qu'une seule page est chargée. Cette dernière est
ensuite mise à jour dynamiquement en fonction des besoins. Bien que cela soit puissant, il y a tout de
même un défaut principal : les utilisateurs ont besoin d'URL différentes pour distinguer les différentes
pages les unes des autres. Sinon, à chaque fois qu'un utilisateur essaie de revenir en arrière, il
obtiendra toujours la même page !
Pour résoudre ce problème, tous les grands Frameworks disposent d'une solution de routage. La
solution recommandée par Vue est la bibliothèque officielle vue-router.
Pour ajouter Vue Router à notre application, nous utiliserons Vue CLI :
vue add router
Une fois l'installation terminée, vous devriez observer que la CLI a modifié un certain nombre de
fichiers afin de s'assurer que tout fonctionne correctement. Si vous ouvrez votre fichier main.js, vous
verrez que Vue CLI a automatiquement configuré la propriété Router en la rattachant à votre instance
de Vue. De plus, un nouveau fichier est apparu, essentiel à la compréhension du routage :
router/index.js.
Le JavaScript Object Notation (JSON) est un format standard utilisé pour représenter des données
structurées de façon semblable aux objets Javascript. Il est habituellement utilisé pour structurer et
transmettre des données sur des sites web (échanger des données entre un serveur et un client).
json-server nous permet d’imiter une API et de fournir un accès dynamique aux données. Cela veut dire
qu’on peut lire, ajouter, mettre à jour et supprimer des données (GET, POST, PUT / PATCH, DELETE).
Vous pouvez installer json-server en global ou bien dans votre projet en utilisant la commande :
npm install -g json-server
6. Dans le nouveau projet Vue déjà généré, créer un répertoire intitulé backend dans lequel un
fichier ayant le nom database.json.
Ce fichier aura les données fake JSON dont la structure est la suivante :
{
"livres": [
{
"id": 1,
"isbn": "9882348560755",
"titre": "HAVE FUN LEAR ENGLISH YEAR 4 BASIC EDUCATION",
"maisonedition": "Eyrolles",
"annedition": "2021",
"auteur": "CNP",
"prix": 2,
"qtestock": 10,
"categorie": "LISTES SCOLAIRES MINISTERE CNP",
"image": "6192202608000_1_m.jpg"
},
{
"id": 2,
"isbn": "9782401064218",
"titre": "annabac sujets & corrigés",
"maisonedition": "Eyrolles",
"annedition": "2020",
"auteur": "CNP",
"prix": 48,
"qtestock": 15,
"categorie": "LISTES SCOLAIRES MINISTERE CNP",
"image": "9782401064218_1_75.jpg"
}
]
}
Sachant que le numéro de port par défaut s’il n’est pas explicitement déclaré est 3000.
8. Dans le dossier « src/assets » du projet Vue, créer un répertoire intitulé « images ». Puis y
télécharger les différentes images de produits qu’on va afficher dans notre site.
Vue CLI crée plusieurs dossiers et fichiers. Le point de départ est public/index.html et "src/main.js".
Mais 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
Le fichier main.js sert à configurer notre projet. Il précise les composants à utiliser (import App from
'./App.vue'), initialiser des variables globales (Vue.config.productionTip = false) et précise où le rendu
doit être effectué ($mount('#app'))).
createApp(App).use(router).mount('#app')
Rendez-vous dans le répertoire src/components, ici nous devons créer les composants suivants. Ces
composants géreront les données dans notre application Vue.Js.
CreateComponent.vue
EditComponent.vue
ListComponent.vue
<script>
export default {
data() {
return {
}
}
}
</script>
</div>
Il existe deux composants principaux que Vue Router utilise et que vous devrez apprivoiser pour vos
applications :
Ces deux composants constituent la base de l'utilisation de Vue Router dans nos composants. Ils
facilitent la navigation dans une application Vue.
L'option d'historique lors de la création de l'instance de routeur nous permet de choisir parmi
différents modes d'historique.
Vue dispose d'un système de fichiers en cascade qui déterminera les variables d'environnement pour
votre application. Le fichier principal étant un .env
BASE_URL - cela correspond à l'option publicPath dans vue.config.js et est le chemin de base sur lequel
votre application est déployée.
</template>
b. Accédez au fichier src/App.vue, nous définissons ici la directive router-view et nous appelons
le composant NavBar.
<template>
<div>
<NavBar />
<!-- Router view -->
<div class="container mt-5">
<router-view></router-view>
</div>
</div>
</template>
<script>
import NavBar from './views/NavBar.vue'
export default {
name: 'App',
components: {
NavBar
}
}
</script>
Le composant <router-view> est le composant principal responsable du rendu du composant
correspondant pour le chemin fourni.
On a besoin de données venant d’un serveur notamment grâce à l’utilisation d’un service REST. Nous
allons consommer les données JSON. Pour cela nous allons mettre en place les requêtes axios avec les
différentes méthodes GET, POST, PUT et DELETE.
Nous allons créer une classe de services dans src/services/LivreService.js ayant le contenu suivant :
class ProductService {
getAll() {
return Axios.get("/livres")
}
add(data) {
return Axios.post("/livres", data);
}
getOne(id) {
return Axios.get(`/livres/${id}`)
}
edit(id,data) {
return Axios.put(`/livres/${id}`,data);
}
del(id) {
return Axios.delete(`/livres/${id}`)
}
}
export default new ProductService();
14. Afficher la liste des données et supprimer les données dans Vue
Maintenant, nous allons afficher les données sous forme d’un tableau à l'aide des composants
Bootstrap Table, et nous allons faire appel à la requête axios.get() pour restituer les données du
serveur à partir de la classe ProductService.
<template>
<div class="row">
<div class="col-md-12">
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th></th>
<th>Titre</th>
<th>Edition</th>
<th>Auteur</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="liv in Livres" :key="liv.id">
<td><span v-if="liv.image.indexOf('.')>-1"><img
:src="require(`../assets/images/${liv.image}`)" :alt="liv.titre"
width="70"></span></td>
<td>{{ liv.titre }}</td>
<td>{{ liv.maisonedition }}</td>
<td>{{ liv.auteur }}</td>
<td>
<router-link :to="{name: 'Modification', params: {
id: liv.id }}" class="btn btn-success">Edit
</router-link>
<button @click.prevent="deleteLivre(liv.id)"
class="btn btn-danger">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
<style>
.btn-success {
margin-right: 10px;
}
</style>
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 {{ titre }}
La directive v-if permet d'effectuer le rendu ou pas du bloc si l'expression associée à cette directive est
vraie. Par ailleurs comme tout bloc de condition, v-if peut s'utiliser avec v-else-if (où une autre
expression peut être évaluée) v-else pour le bloc par défaut si aucune expression n'est satisfaite.
Lorsque le contenu de l’image ne contient pas un point (indiquant qu’il y a une extension) ce n’est pas
la peine de faire l’affichage de l’image. On pourrait enrichir ce test en ajoutant des validatins sur les
extensions des images.
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" />
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.
<button v-on:click="deleteLivre(liv.id)">Delete</button>
ou syntaxe raccourci
<button @click="deleteLivre(liv.id)">Delete</button>
La méthode appelée (deleteLivre ) est développée dans la partie methods dans le script.
created est appelé de manière synchrone après la création de l'instance. A ce stade, l'instance a fini de
traiter les options, ce qui signifie que les éléments suivants ont été configurés : observation des
données, propriétés calculées, méthodes, rappels watch/event. Cependant, la phase de montage n'a
pas encore commencé et la propriété $el ne sera pas encore disponible.
Une autre alternative est mounted qui est appelé après que l'instance vient d'être montée mais ce
hook n'est pas appelé lors du rendu côté serveur.
ProductService est appelée pour faire appel à la méthode getAll ayant l’axios de get.
Résultat obtenu :
La méthode de post Axios prend l'API REST et envoie la requête POST au serveur. Il crée les données
des livres que nous ajoutons dans JSON database.
<template>
<div class="row justify-content-center">
<div class="col-md-6">
<h3 class="text-center">Create Student</h3>
<form @submit.prevent="handleSubmitForm">
<div class="form-group">
<label>ISBN</label>
<input type="text" class="form-control" v-
model="livre.isbn" required>
</div>
<div class="form-group">
<label>Titre</label>
<input type="text" class="form-control" v-
model="livre.titre" required>
</div>
<div class="form-group">
<label>Edition</label>
<input type="text" class="form-control" v-
model="livre.maisonedition" >
</div>
<div class="form-group">
<label>Année</label>
<input type="number" class="form-control" v-
model="livre.annedition" >
</div>
<div class="form-group">
<label>Auteur</label>
<input type="text" class="form-control" v-
model="livre.auteur" >
</div>
<div class="form-group">
<label>Prix</label>
<input type="number" class="form-control" v-
model="livre.prix" >
</div>
<div class="form-group">
<label>Quantité</label>
<input type="number" class="form-control" v-
model="livre.qtestock" >
</div>
<div class="form-group">
<label>Catégorie</label>
<input type="text" class="form-control" v-
model="livre.categorie" >
</div>
<div class="form-group">
<label>Image</label>
<input type="file" class="form-
control" @change="onFileChange">
</div>
<div class="form-group">
<button class="btn btn-danger btn-block">Ajouter</button>
</div>
</form>
</div>
</div>
</template>
<script>
import ProductService from "../services/LivreService";
export default {
data() {
return {
livre: {
isbn: "",
titre: "",
maisonedition: "",
annedition: "",
auteur: "",
prix: "",
qtestock: "",
categorie: "",
image: ""
}
}
},
methods: {
handleSubmitForm() {
ProductService.add(this.livre).then(() => {
this.$router.push('/')
this.livre = {
isbn: "",
titre: "",
maisonedition: "",
annedition: "",
auteur: "",
prix: "",
qtestock: "",
categorie: "",
image: ""
}
}).catch(error => {
console.log(error)
});
},
onFileChange(e) {
this.livre.image = e.target.files[0].name;
}
}
}
</script>
<style scoped>
img {
width: 30%;
margin: auto;
display: block;
margin-bottom: 10px;
}
</style>
v-model permet de lier la valeur d'un champs de saisie avec une variable. Si vous avez modifié l'un ou
l'autre Vue mettra à jour automatiquement l'autre. Du coup, la variable et le champ de saisie auront
toujours la même valeur. Il s’agit du databiding.
Résultat obtenu :
<template>
<div class="row justify-content-center">
<div class="col-md-6">
<h3 class="text-center">Create Student</h3>
<form @submit.prevent="handleSubmitForm">
<div class="form-group">
<label>ISBN</label>
<input type="text" class="form-control" v-
model="livre.isbn" required>
</div>
<div class="form-group">
<label>Titre</label>
<input type="text" class="form-control" v-
model="livre.titre" required>
</div>
<div class="form-group">
<label>Edition</label>
<input type="text" class="form-control" v-
model="livre.maisonedition" >
</div>
<div class="form-group">
<label>Année</label>
<input type="number" class="form-control" v-
model="livre.annedition" >
</div>
<div class="form-group">
<label>Auteur</label>
<input type="text" class="form-control" v-
model="livre.auteur" >
</div>
<div class="form-group">
<label>Prix</label>
<input type="number" class="form-control" v-
model="livre.prix" >
</div>
<div class="form-group">
<label>Quantité</label>
<input type="number" class="form-control" v-
model="livre.qtestock" >
</div>
<div class="form-group">
<label>Catégorie</label>
<input type="text" class="form-control" v-
model="livre.categorie" >
</div>
<div class="form-group">
<label>Image</label>
<input type="file" class="form-
control" @change="onFileChange">
</div>
<div class="form-group">
<button class="btn btn-danger btn-block">Modifier</button>
</div>
</form>
</div>
</div>
</template>
<script>
import ProductService from "../services/LivreService";
export default {
data() {
return {
livre: {}
}
},
created() {
ProductService.getOne(this.$route.params.id).then((res) => {
this.livre = res.data;
})
},
methods: {
handleSubmitForm() {
ProductService.edit(this.$route.params.id, this.livre).then(()
=> {
this.$router.push('/')
this.livre = {
isbn: "",
titre: "",
maisonedition: "",
annedition: "",
auteur: "",
prix: "",
qtestock: "",
categorie: "",
image: ""
}
}).catch(error => {
console.log(error)
});
},
onFileChange(e) {
this.livre.image = e.target.files[0].name;
}
}
}
</script>
<style scoped>
img {
width: 30%;
margin: auto;
display: block;
margin-bottom: 10px;
}
</style>
Ici, nous devons faire face à deux choses, et nous devons rendre les données lorsque l'utilisateur
atterrit sur le composant des détails de l'étudiant et faire la demande de publication pour mettre à
jour les informations sur le serveur.
Pour obtenir l'identifiant actuel à partir de l'URL existante, utilisez this.$route.params.id vue API.
En utilisant la même API, nous pouvons obtenir l'identifiant de l'URL et mettre à jour les valeurs de la
base de données en utilisant l'API.
$route / this.$route est un object global qui contient des informations sur la route actuelle:
- name
- fullPath
- path
- query
- params
Résultat obtenu :