Tutoriel pour apprendre à utiliser le framework Vue.js version 2

Plus loin


précédentsommairesuivant

III. Vue-resource (1/2)

Dans le tutoriel précédent, on a vu l'essentiel de Vue.js, mais cette bibliothèque bénéficie de nombreuses ressources additionnelles. Vous en trouvez l'ensemble sur cette page avec en plus la référence des tutoriels et autres. Dans ce chapitre je vous propose de découvrir le plugin vue-resource qui simplifie la mise en place de requêtes Ajax.

Pour l'occasion on va utiliser Laravel pour d'une part fournir l'application et d'autre part présenter une API. Comme sujet je ne vais pas faire dans l'originalité puisque je vais me contenter de gérer la table par défaut des utilisateurs.

Pour vous faciliter la vie et si vous n'avez pas le courage de suivre tout le processus vous pouvez télécharger ici le code complet. Il suffit de l'installer…

III-A. Installation de l'intendance

III-A-1. Laravel

On va donc avoir besoin d'une installation fraîche de Laravel. Comme je n'aime pas me compliquer la vie, j'ai adopté Laragon et pour installer un Laravel c'est tout simple :

Image non disponible

Il suffit d'indiquer un nom et c'est parti !

Image non disponible

Laragon ouvre la console, crée une base de données du même nom et lance l'installation, il n'y a plus qu'à attendre ! En bonus on bénéficie automatiquement d'un hôte virtuel vuejs.dev.

On va ensuite le franciser avec ce plugin en copiant le dossier du français :

Image non disponible

Et en mettant à jour la configuration (app/config/app.php) :

 
Sélectionnez
'locale' => 'fr',

Ça va nous servir pour les messages de la validation.

III-A-2. La base de données

Comme on va avoir besoin d'une base de données sans grande complexité on va utiliser sqlite.

Dans le fichier .env changez cette ligne :

 
Sélectionnez
DB_CONNECTION=sqlite

Et supprimez cette ligne :

 
Sélectionnez
DB_DATABASE=homestead

Ensuite, dans la console créez le fichier :

 
Sélectionnez
touch database/database.sqlite

Vous devriez trouver le fichier ici :

Image non disponible

Pour les migrations, supprimez celle-ci que nous n'utiliserons pas :

Image non disponible

On ne conserve donc que celle de la table users.

Vous pouvez lancer la migration :

 
Sélectionnez
php artisan migrate

On va aussi avoir besoin de remplir un peu cette table. Laravel offre des factories bien pratiques et celui des utilisateurs est déjà présent par défaut. On va donc l'utiliser pour créer dix utilisateurs, on va modifier ce fichier :

Image non disponible

Avec ce code :

 
Sélectionnez
1.
2.
3.
4.
public function run()
{
    factory(App\User::class, 10)->create();;
}

Vous pouvez alors lancer la population :

 
Sélectionnez
php artisan db:seed

Si tout se passe bien, vous devriez avoir dix utilisateurs :

Image non disponible

Pour info j'utilise une extension de Firefox pour cette visualisation et d'une manière générale pour gérer simplement les bases sqlite.

III-A-3. Route et contrôleur

Il ne reste plus maintenant qu'à créer un contrôleur et les routes pour charger l'application et présenter l'API :

 
Sélectionnez
php artisan make:controller UserController
Image non disponible

Changez ainsi le code :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
use App\User;
use Illuminate\Validation\Rule;
 
class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return User::select('id', 'name', 'email')->get();
    }
 
    /**
     * Send app.
     *
     * @return \Illuminate\Http\Response
     */
    public function app()
    {
        return view('users');
    }
 
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
        ]);
 
        $input = array_merge($request->all(), ['password' => bcrypt('secret')]);
         
        User::create($input);
         
        return response()->json();       
    }
 
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'name' => 'required|max:255',
            'email' => ['required', 'email', 'max:255',
             Rule::unique('users')->ignore($id)],
        ]);
 
        User::find($id)->update($request->all());
 
        return response()->json(); 
    }
 
    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        User::find($id)->delete();
 
        return response()->json();
    }
}

Et ajoutez ces routes dans routes/web.php :

 
Sélectionnez
1.
2.
3.
4.
5.
Route::get('app', 'UserController@app');
 
Route::resource('users', 'UserController', ['except' => [
    'create', 'show', 'edit'
]]);

Vous pouvez supprimer la route présente dans le fichier routes/web.php.

Je place les routes dans le fichier web parce qu'on va avoir besoin de la session.

Vous devriez avoir ces routes :

Image non disponible

En détaillant :

  • app : on va charger ici l'application ;
  • users (GET) : on charge tous les utilisateurs ;
  • users (POST) : on crée un utilisateur ;
  • users/{user} (PUT) : on modifie un utilisateur ;
  • users/{user} (DELETE) : on supprime un utilisateur.

Je ne détaille pas le code du contrôleur qui est classique et ce n'est pas le sujet de ce chapitre.

On ne va mettre en place aucune authentification pour simplifier.

III-A-4. npm

Par défaut on a ce fichier package.json :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
{
  "private": true,
  "scripts": {
    "prod": "gulp --production",
    "dev": "gulp watch"
  },
  "devDependencies": {
    "bootstrap-sass": "^3.3.7",
    "gulp": "^3.9.1",
    "jquery": "^3.1.0",
    "laravel-elixir": "^6.0.0-9",
    "laravel-elixir-vue-2": "^0.2.0",
    "laravel-elixir-webpack-official": "^1.0.2",
    "lodash": "^4.16.2",
    "vue": "^2.0.1",
    "vue-resource": "^1.0.3"
  }
}

Comme on y trouve que des choses qui vont nous servir (en particulier il y a déjà vue-resource) on installe ça :

 
Sélectionnez
npm install

Si tout se passe bien, vous obtenez toutes les dépendances dans ce dossier :

Image non disponible

Comme on va utiliser Sweet Alert on va installer aussi le plugin prévu pour Vue.js :

 
Sélectionnez
npm i vue-sweetalert --save-dev

III-B. L'application

Maintenant qu'on a mis en place toute l'intendance, on va coder l'application.

On va commencer par supprimer le composant prévu par défaut :

Image non disponible

Et on va modifier ainsi le fichier resources/assets/je/app.js :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
require('./bootstrap');
 
// Sweetalert
import VueSweetAlert from 'vue-sweetalert';
Vue.use(VueSweetAlert);
 
Vue.component('app', require('./components/App.vue'));
 
const app = new Vue({
    el: '#app'
});

J'ai ajouté Sweetalert et changé le nom du composant.

D'autre part on va enlever la compilation de sass dans gulpfile.js :

 
Sélectionnez
elixir(mix => {
    mix.webpack('app.js');
});

On va créer une vue resources/views/users.blade.php :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<!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">
    <title>Test vue.js</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
  </head>
  <body>
    <div class="container">
        <br>
        <div id="app">
          <app></app>
        </div>
    </div>
    <script>
      window.Laravel = {!! json_encode(['csrfToken' => csrf_token()]) !!};
    </script>
    <script src="/js/app.js"></script>
  </body>
</html>

Pour changer un peu, je vais utiliser Semantic-ui que je trouve très élégant.

Le reste est classique mis à part la ligne pour le token qui est nécessaire pour l'intercepteur.

Il ne nous manque plus que le composant ! On l'appelle simplement :

Image non disponible

Avec ce code :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
<template>
  <div class="ui raised container segment">
    <div class="ui positive message" v-show="success">
      <i class="close icon" @click="closeSuccess()"></i>
      <div class="header">
        Serveur mis à jour avec succès !
      </div>
    </div>
    <div class="ui negative message" v-show="danger">
      <i class="close icon" @click="closeDanger()"></i>
      <div class="header">
        Echec de la communication avec le serveur !
      </div>
    </div>
    <div class="ui negative message" v-show="validation.name || validation.email">
      <i class="close icon" @click="closeValidation()"></i>
      <div class="header">
        Il y a des erreurs dans la validation des données saisies :
      </div> 
      <ul class="list">
        <li>{{ validation.name }}</li>
        <li>{{ validation.email }}</li>
      </ul>         
    </div>
    <table class="ui celled table">
      <caption><h1>Liste des utilisateurs</h1></caption>
      <thead>
        <tr>
         <th>Nom</th>
         <th>Email</th>
         <th></th>
         <th></th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(user, index) in users">
          <td>{{ user.name }}</td>
          <td>{{ user.email }}</td>
          <td>
            <button class="fluid ui orange button" :class="{ disabled: edition }" data-tooltip="Modifier cet utilisateur" data-position="top center" @click="edit(index)">
              <i class="edit icon"></i>
            </button>
          </td>
          <td>
            <button class="fluid ui red button" :class="{ disabled: edition }" data-tooltip="Supprimer cet utilisateur" data-position="top center" @click="del(index)">
              <i class="remove user icon"></i>
            </button>
          </td>  
        </tr>  
        <tr class="ui form">
          <td>
            <div class="ui field" :class="{ error: validation.name }">
              <input type="text"v-model="user.name" placeholder="Nom">
            </div>
          </td>
          <td>
            <div class="ui field" :class="{ error: validation.email }">
              <input type="email" class="form-control" v-model="user.email" placeholder="Email">
            </div>
          </td>
          <td colspan="2" v-if="!edition">
            <button class="fluid ui blue button" data-tooltip="Ajouter un utilisateur" data-position="top center" @click="add()">
              <i class="add user icon"></i>
            </button>
          </td>
          <td v-if="edition">
            <button class="fluid ui blue button" data-tooltip="Mettre à jour cet utilisateur" data-position="top center" @click="update()">
              <i class="add user icon"></i>
            </button>
          </td>
          <td v-if="edition">
            <button class="fluid ui violet button" data-tooltip="Annuler la modification" data-position="top center" @click="undo()">
              <i class="undo icon"></i>
            </button>
          </td>
        </tr>
      </tbody>       
    </table>
  </div>  
</template>
 
<script>
export default {
  name: 'application',
  resource: null,
  data () {
    return {
      users: [],
      user: { name: '', email: ''},
      userSave: {},
      success: false,
      danger: false,
      edition: false,
      validation: { name: '', email: ''}
    }
  },
  mounted: function() {
    this.resource = this.$resource('/users{/id}')
    this.resource.get().then((response) => {
      this.users = response.body
    }, (response) => {
      this.danger = true
    })
  },
  methods: {
    add: function() {
        this.resetMessages()
        this.resource.save(this.user).then((response) => {
        this.success = true
        this.users.push(this.user)
        this.user = { name: '', email: '' }
      }, (response) => {
        this.setValidation(response)
      });
    },
    update: function() {
        this.resetMessages()
        this.resource.update({id: this.user.id}, this.user).then((response) => {
        this.success = true
        this.edition = false
        this.users.push(this.user)
        this.user = { name: '', email: '' }
      }, (response) => {
        this.setValidation(response)
      });
    },
    del: function(index) {
      let that = this
      this.resetMessages()
      this.$swal({
        title: 'Vous êtes sûr de vous ?',
        text: "Il n'y aura aucun retour en arrière possible !",
        type: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Oui supprimer !',
        cancelButtonText: 'Non, surtout pas !',
      }).then(function() {
        that.resource.delete({id: that.users[index].id}).then((response) => {
          that.success = true
          that.users.splice(index, 1)
        }, (response) => {
          that.danger = true 
        });        
      }).done()
    },
    edit: function(index) {
      this.resetMessages()
      this.user = this.users[index]
      this.userSave = JSON.parse(JSON.stringify(this.user))
      this.users.splice(index, 1)
      this.edition = true
    },
    undo: function() {
      this.users.push(this.userSave)
      this.user = { name: '', email: '' }
      this.edition = false
    },
    resetMessages: function() {
      this.success = false
      this.danger = false
      this.closeValidation()
    },
    setValidation: function(response) {
      this.validation.name = response.body.name ? response.body.name[0] : ''
      this.validation.email = response.body.email ? response.body.email[0] : ''
    },
    closeSuccess: function() {
      this.success = false
    },
    closeDanger: function() {
      this.danger = false
    },
    closeValidation: function() {
      this.validation = { name: '', email: ''}
    }
  }
}
</script>

On va détailler un peu tout ça, mais on va déjà voir si ça fonctionne…

Image non disponible

On va ouvrir avec Chrome (on a vu dans un précédent chapitre qu'on bénéficie d'un outil de développement spécial pour Vue.js) avec l'URL vuejs.dev/app :

Image non disponible

On obtient bien notre application avec les dix utilisateurs.

III-B-1. Les données du composant

Regardons le data du composant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
data () {
  return {
    users: [],
    user: { name: '', email: ''},
    userSave: {},
    success: false,
    danger: false,
    edition: false,
    validation: { name: '', email: ''}
  }
},

On a :

  • users : tableau de tous les utilisateurs, au départ vide ;
  • user : objet pour la liaison de données avec le formulaire ;
  • userSave : objet pour mémoriser les données de l'utilisateur en cas de modification (si on annule) ;
  • succes, danger, edition : des commutateurs pour l'état de l'application ;
  • validation : tableau pour les messages issus de la validation de Laravel.

III-C. Le chargement de l'application

Lorsque l'application se charge, elle passe par un certain nombre de stades avec des événements associés. On va utiliser l'événement mounted pour être sûr que le composant est prêt à afficher des informations :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
mounted: function() {
  this.resource = this.$resource('/users{/id}')  (1)
  this.resource.get().then((response) => {   (2)
    this.users = response.body
  }, (response) => {
    this.danger = true
  })
},

On commence par créer et mémoriser la ressource (1). On va ainsi disposer de ces actions :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
get: {method: 'GET'},
save: {method: 'POST'},
query: {method: 'GET'},
update: {method: 'PUT'},
remove: {method: 'DELETE'},
delete: {method: 'DELETE'}

Ensuite on envoie une requête get (2). Si ça aboutit, on remplit le tableau users et les données s'affichent automatiquement :

 
Sélectionnez
1.
2.
3.
4.
5.
<tr v-for="(user, index) in users">
  <td>{{ user.name }}</td>
  <td>{{ user.email }}</td>
  ...
</tr>

Au niveau de Laravel on a une simple requête Eloquent :

 
Sélectionnez
1.
2.
3.
4.
public function index()
{
    return User::select('id', 'name', 'email')->get();
}

Si ça n'aboutit pas, on met à true la propriété danger et avec une directive v-show on affiche un message :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
<div class="ui negative message" v-show="danger">
  <i class="close icon" @click="closeDanger()"></i>
  <div class="header">
    Echec de la communication avec le serveur !
  </div>
</div>
Image non disponible

III-D. Supprimer un utilisateur

On dispose de boutons pour supprimer un utilisateur :

Image non disponible

Avec ce code :

 
Sélectionnez
<button class="fluid ui red button" :class="{ disabled: edition }" data-tooltip="Supprimer cet utilisateur" data-position="top center" @click="del(index)">
  <i class="remove user icon"></i>
</button>

On voit qu'on intercepte le clic avec la méthode del en transmettant l'index :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
del: function(index) {
  let that = this
  this.resetMessages()
  this.$swal({
    title: 'Vous êtes sûr de vous ?',
    text: "Il n'y aura aucun retour en arrière possible !",
    type: 'warning',
    showCancelButton: true,
    confirmButtonColor: '#3085d6',
    cancelButtonColor: '#d33',
    confirmButtonText: 'Oui supprimer !',
    cancelButtonText: 'Non, surtout pas !',
  }).then(function() {
    that.resource.delete({id: that.users[index].id}).then((response) => {
      that.success = true
      that.users.splice(index, 1)
    }, (response) => {
      that.danger = true
    });        
  }).done()
},

Pour faire plus joli, j'ai prévu l'utilisation de Sweetalert pour avoir une fenêtre de confirmation élégante :

Image non disponible

Cette fois on utilise l'action delete de la ressource :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
that.resource.delete({id: that.users[index].id}).then((response) => {
  that.success = true
  that.users.splice(index, 1)
}, (response) => {
  that.danger = true
});

En cas de succès, on met à true la propriété success pour faire apparaître un message :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
<div class="ui positive message" v-show="success">
  <i class="close icon" @click="closeSuccess()"></i>
  <div class="header">
    Serveur mis à jour avec succès !
  </div>
</div>
Image non disponible

On supprime les informations du tableau des utilisateurs et il disparaît de la liste.

En cas d'échec c'est la même chose qu'on a vue ci-dessus.

III-E. Ajouter un utilisateur

Pour ajouter un utilisateur, on dispose d'un formulaire au bas de la liste :

Image non disponible

Le code est un peu chargé parce que le même formulaire sert pour la modification :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<tr class="ui form">
  <td>
    <div class="ui field" :class="{ error: validation.name }">
      <input type="text" v-model="user.name" placeholder="Nom">
    </div>
  </td>
  <td>
    <div class="ui field" :class="{ error: validation.email }">
      <input type="email" class="form-control" v-model="user.email" placeholder="Email">
    </div>
  </td>
  <td colspan="2" v-if="!edition">
    <button class="fluid ui blue button" data-tooltip="Ajouter un utilisateur" data-position="top center" @click="add()">
      <i class="add user icon"></i>
    </button>
  </td>
  <td v-if="edition">
    ...
  </td>
</tr>

On passe d'une situation à l'autre avec une directive v-if et la propriété edition.

On crée la liaison des données avec des directives v-model.

On prévoit une classe error en cas d'erreur de validation qui nous est donnée par l'objet validation.

Le bouton active la méthode add :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
add: function() {
    this.resetMessages()   (1)
    this.resource.save(this.user).then((response) => {    (2)
    this.success = true   (3)
    this.users.push(this.user)   (4)
    this.user = { name: '', email: '' }   (5)
  }, (response) => {
    this.setValidation(response)   (6)
  });
},

On commence par supprimer les messages éventuels d'erreur de validation (1).

On utilise l'action save de la ressource (2).

En cas de réussite, on affiche le message de réussite (3), on ajoute l'utilisateur dans le tableau (4), on efface les données saisies dans les contrôles du formulaire (5).

En cas de souci de validation, on appelle la méthode setValidation (6) :

 
Sélectionnez
1.
2.
3.
4.
setValidation: function(response) {
  this.validation.name = response.body.name ? response.body.name[0] : ''
  this.validation.email = response.body.email ? response.body.email[0] : ''
},

On informe l'objet validation avec les messages de validation reçus. Ce qui va avoir pour effet de mettre en rouge le contrôle correspondant :

 
Sélectionnez
<div class="ui field" :class="{ error: validation.name }">
Image non disponible

Et d'afficher un message en haut de la liste avec les textes des erreurs :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<div class="ui negative message" v-show="validation.name || validation.email">
  <i class="close icon" @click="closeValidation()"></i>
  <div class="header">
    Il y a des erreurs dans la validation des données saisies :
  </div> 
  <ul class="list">
    <li>{{ validation.name }}</li>
    <li>{{ validation.email }}</li>
  </ul>         
</div>
Image non disponible

Au niveau de Laravel on a prévu ces règles :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public function store(Request $request)
{
    $this->validate($request, [
        'name' => 'required|max:255',
        'email' => 'required|email|max:255|unique:users',
    ]);
 
    $input = array_merge($request->all(), ['password' => bcrypt('secret')]);
     
    User::create($input);
     
    return response()->json();       
}

On voit aussi qu'on affecte automatiquement un mot de passe pour faire plaisir à la base.

III-F. Modifier un utilisateur

La modification d'un utilisateur ressemble beaucoup à l'ajout avec quelques contraintes supplémentaires. En effet il faut transférer les données dans le formulaire, empêcher de faire une autre action, prévoir un bouton d'annulation.

On dispose d'un bouton de modification pour chaque utilisateur :

 
Sélectionnez
<button class="fluid ui orange button" :class="{ disabled: edition }" data-tooltip="Modifier cet utilisateur" data-position="top center" @click="edit(index)">
  <i class="edit icon"></i>
</button>
Image non disponible

On appelle la méthode edit :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
edit: function(index) {
  this.resetMessages()   (1)
  this.user = this.users[index]   (2)
  this.userSave = JSON.parse(JSON.stringify(this.user))   (3)
  this.users.splice(index, 1)   (4)
  this.edition = true   (5)
},

On supprime les messages de validation éventuels (1).

On transfère les données dans le formulaire (2).

On clone les données pour le cas de l'annulation (3).

On supprime les données de la liste (4).

On passe en mode édition en informant la propriété edition (5).

On a donc les informations dans le formulaire, deux boutons et les autres boutons tous inhibés :

Image non disponible

L'inhibition des boutons se fait en ajoutant la classe disabled avec la propriété edition :

 
Sélectionnez
:class="{ disabled: edition }"

Si on utilise le bouton d'annulation, on appelle la méthode undo :

 
Sélectionnez
1.
2.
3.
4.
5.
undo: function() {
  this.users.push(this.userSave)   (1)
  this.user = { name: '', email: '' }   (2)
  this.edition = false   (3)
},

On rétablit l'utilisateur dans le tableau (1).

On efface les données du formulaire (2).

On enlève le mode édition (3).

Si on utilise le bouton d'envoi on active la méthode update :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
update: function() {
    this.resetMessages()
    this.resource.update({id: this.user.id}, this.user).then((response) => {
    this.success = true
    this.edition = false
    this.users.push(this.user)
    this.user = { name: '', email: '' }
  }, (response) => {
    this.setValidation(response)
  });
},

Là c'est comme dans le cas de l'ajout à part qu'on utilise l'action update de la ressource.

On a la même validation.

Au niveau de Laravel on a ce code classique :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public function update(Request $request, $id)
{
    $this->validate($request, [
        'name' => 'required|max:255',
        'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($id)],
    ]);
 
    User::find($id)->update($request->all());
 
    return response()->json(); 
}

III-G. En conclusion

Mon application d'exemple n'est pas très réaliste avec mon API accessible par tout le monde, mais elle montre comment mettre en œuvre les plugins vue-resource et vue-sweetalert. D'autre part s'il y a beaucoup d'utilisateurs il serait judicieux de faire une pagination. Alors dans le prochain chapitre je montrerai comment ajouter facilement la pagination et on en profitera aussi pour créer un composant pour les messages puisqu'on en a trois différents dans notre application.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2017 Vue.js. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.