IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

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

Plus loin


précédentsommairesuivant

II. Avec Laravel

Comme ce tutoriel est essentiellement consacré à Laravel il me faut évoquer l'utilisation de Vue.js 2 avec Laravel 5.3 puisque cette version a été enrichie de tout ce qu'il faut pour sceller ce mariage. J'en ai un peu parlé dans mon tutoriel sur les nouveautés de la version 5.3 je vais y revenir de façon plus précise maintenant en poursuivant l'exemple du panier dans le contexte de Laravel.

II-A. État des lieux

Dans l'article référencé ci-dessus, j'avais présenté l'infrastructure en place lorsqu'on installe Laravel 5.3 :

Image non disponible

On a déjà :

  • un composant vue.js 2 : Exemple.vue ;
  • une application de base : app.js ;
  • un fichier d'initialisation : bootstrap.js.

Avec Laravel on n'utilise pas directement Webpack - on pourrait si on le voulait -, mais plutôt Elixir qui est lui-même une sur couche qui simplifie l'utilisation de Gulp.

Si on regarde le fichier de configuration de Gulp (gulpfile.js) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
const elixir = require('laravel-elixir');
 
require('laravel-elixir-vue-2');
 
/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Sass
 | file for our application, as well as publishing vendor resources.
 |
 */
 
elixir(mix => {
    mix.sass('app.scss')
       .webpack('app.js');
});

On voit qu'on lance une tâche Webpack en référençant le fichier app.js qui est l'entrée de l'application. C'est donc Elixir qui se charge de tout de façon invisible (on n'a pas de fichier webpack.config.js, mais on peut en créer un au besoin).

Concernant npm 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-11",
    "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"
  }
}

On voit qu'on charge vue ainsi que le plugin vue-resource dont je parlerai dans un autre chapitre.

On dispose aussi de deux scripts :

  • dev : pour le développement avec une observation des modifications (watch) ;
  • prod : pour la production en compressant les fichiers.

II-B. Installation

La première chose à faire est évidemment d'utiliser npm pour charger toutes les dépendances :

 
Sélectionnez
npm install

Ce qui crée le dossier node_modules avec tous les fichiers :

Image non disponible

On sait qu'on aura besoin du système de template pug pour le panier, alors on l'ajoute :

 
Sélectionnez
npm install pug

On a ainsi tout ce qu'il faut au niveau des dépendances !

En faisant mes essais, je me suis rendu compte que la transformation du code ES6 en ES5 avec Elixir n'était pas assurée par Babel, mais par Bublé. Cela a certaines conséquences parce que ce n'est pas l'ensemble de ES6 qui est pris en charge, ce qui est justifié dans la documentation :

 
Sélectionnez
Bublé limits itself to ES features that can be compiled to compact, performant ES5

Vous disposez d'ailleurs d'une page avec les fonctionnalités non supportées. En particulier on y trouve le for…of que j'ai utilisé précédemmentOn s'organise ! pour justement tester la transformation effectuée par Babel. C'est d'ailleurs comme ça que je m'en suis rendu compte, parce que je tombais sur une erreur et que j'ai dû un peu fouiller parce que rien n'est indiqué dans la documentation de Laravel…

On peut tout de même changer les options de fonctionnement de Bublé, mais pas d'une façon qui m'a semblé suffisamment claire et adaptable à la situation. On peut évidemment utiliser Babel, mais le loader est codé en dur dans Elixir…

Pour le présent chapitre, j'ai pris la configuration par défaut et enlevé le for…of du code, ce qui était le plus simple !

II-C. Le panier

Maintenant pour mettre en place le panier c'est tout simple. On crée une route pour le tester :

 
Sélectionnez
Route::get('test', function () {
    return view('test');
});

La vue test.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.
<!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://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/united/bootstrap.min.css">
  </head>
  <body>
    <div class="container">
        <br>
        <div id="app">
          <app></app>          
        </div>
    </div>
    <script src="/js/app.js"></script>
  </body>
</html>

On a :

  • un identifiant app pour servir de référence à Vue.js ;
  • une balise app pour notre application ;
  • le chargement du fichier JavaScript de l'application /js/app.js.

Dans app.js on change le composant :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
require('./bootstrap');
 
Vue.component('app', require('./components/App.vue'));
 
const app = new Vue({
    el: '#app'
});

On met en place nos trois composants et on supprime Exemple.vue :

Image non disponible

Pour rappel voici le code de App.vue :

 
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.
<template>
  <div id="app">
    <panier :panier="panier"></panier> 
  </div>
</template>
 
<script>
import Panier from './Panier.vue'
 
export default {
  name: 'application',
  data () {
    return {
      panier: [
        { article: "Cahier", quantite: 2, prix: '5.30' },
        { article: "Crayon", quantite: 4, prix: '1.10' },
        { article: "Gomme", quantite: 1, prix: '3.25' }
      ]
    }
  },
  components: {
    Panier
  }
}
</script>

Le code de Panier.vue :

 
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.
<template>
<div class="panel panel-primary">
  <div class="panel-heading">Panier</div>        
  <table class="table table-bordered table-striped">
    <thead>
      <tr>
       <th class="col-sm-4">Article</th>
       <th class="col-sm-2">Quantité</th>
       <th class="col-sm-2">Prix</th>
       <th class="col-sm-2">Total</th>
       <th class="col-sm-1"></th>
       <th class="col-sm-1"></th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) in panier">
        <td>{{ item.article }}</td>
        <td>{{ item.quantite }}</td> 
        <td>{{ item.prix }}</td>
        <td>{{ (item.quantite * item.prix).toFixed(2) }}</td>
        <td><button class="btn btn-info btn-block" @click="modifier(index)"><i class="fa fa-edit fa-lg"></i></button></td>
        <td><button class="btn btn-danger btn-block" @click="supprimer(index)"><i class="fa fa-trash-o fa-lg"></i></button></td>
      </tr> 
      <tr>
        <td colspan="3"></td>
        <td><strong>{{ total }}</strong></td>
        <td colspan="2"></td>
      </tr> 
      <editeur :article="article" @add="ajouter"></editeur>
    </tbody>       
  </table>
</div>
</template>
 
<script>
import Editeur from './Editeur.vue'
 
export default {
  props: ['panier'],
  data: function () {
    return {
      article: { article: '', quantite: 0, prix: 0 }
    }
  },
  computed: {
    total: function () {
      let total = 0;
      this.panier.forEach(function(el) {
          total += el.prix * el.quantite;
      });
      return total.toFixed(2)
    }
  },
  methods: {
    modifier: function(index) {
      this.article = this.panier[index]
      this.panier.splice(index, 1)
    },
    supprimer: function(index) {
      this.panier.splice(index, 1)
    },
    ajouter: function(input) {
      this.panier.push(input)
      this.article = { article: '', quantite: 0, prix: 0 }
    }
  },
  components: {
    Editeur
  }
}
</script>

C'est là que j'ai supprimé le for…of.

Et Editeur.vue :

 
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.
<template lang="pug">
tr(class="bleu")
  td
    input(type="text" class="form-control" v-model="input.article" ref="modif" placeholder="Article")
  td
    input(type="text" class="form-control" v-model="input.quantite" placeholder="Quantité")
  td
    input(type="text" class="form-control" v-model="input.prix" placeholder="Prix")
  td(colspan="3")
    button(class="btn btn-primary btn-block" @click="ajouter()") "Ajouter"
</template>
 
<script>
export default {
  props: ['article'],
  computed: {
    input: function() {
      return this.article;
    }
  },
  methods: {
    ajouter: function() {
      this.$emit('add', this.input);
    }
  }  
}
</script>
 
<style lang="sass">
$fond: lightblue;
.bleu {
  background-color: $fond !important;
}
</style>

II-D. On lance Gulp

Il ne reste plus qu'à voir si ça fonctionne :

Image non disponible

Apparemment tout se passe bien en mode développement. On retrouve bien le panier :

Image non disponible

Et on est en mode watch pour que tous les changements soient pris en compte.

Et voilà ce que ça donne en mode production :

Image non disponible

Cette fois le fichier /js/app.js est minifié et le panier fonctionne encore !

On voit donc que la mise en œuvre de Vue.js2 avec Laravel 5.3 est assez facile.

Reste toutefois à voir s'il est aussi facile de modifier la configuration selon les besoins. Je n'en ai pas l'expérience parce que je n'ai eu aucun projet qui justifie ce genre de mise en œuvre.


précédentsommairesuivant

Copyright © 2017 Vue.js. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.