VueJS

/vju:/

Emmanuel DEMEY

@EmmanuelDemey

Zenika Lille

 

Aurélien LOYER

@AurelienLoyer

Zenika Lille

Nathan DAMIE

@NathanDM

Zenika Lille

VueJS - Plan

 

  • Les Composants
  • Les Directives
  • Les Filtres
  • HTTP
  • Routeur
  • Formulaire
  • VueX

VueJS

 

- Librairie pour créer des composants

- Permet de créer une application "rapidement"

- Pas la prétention de concurrencer Angular et ReactJS

- Principaux éléments : Vues, Directives, Composants et Bindings

- Utilisation du Shadow DOM


npm install -g vue-cli

vue init webpack my-project

cd my-project

npm install

npm run dev

npm run build

VueJS - Interpolation

<div id="zenika">
  {{ message }}
</div>
let app = new Vue({
  el: '#zenika',
  data() {
    return {
        message: 'Hello Zenika!'
    }
  }
})

VueJS - Bindings

<div id="zenika" v-bind:class="css">
  {{ message }}
</div>
let app = new Vue({
  el: '#zenika',
  data() {
    return {
      message: 'Hello Zenika!',
      css: 'rouge-zenika'
    }
  } 
})

VueJS - Bindings

<div id="zenika" :class="css">
  {{ message }}
</div>
let app = new Vue({
  el: '#zenika',
  data() {
    return {
      message: 'Hello Zenika!',
      css: 'rouge-zenika'
    }
  } 
})

VueJS - Events Handlers

<ul id="zenika">
   <button v-on:click="add">Add Antoine</button>
</ul>
let app = new Vue({
  el: '#zenika',
  data: { consultants: [ ... ] },
  methods: {
    add(){
        this.consultants.push({name: 'Antoine'})
    }
  }
})

VueJS - Events Handlers

<ul id="zenika">
   <button @click="add">Add Antoine</button>
</ul>
let app = new Vue({
  el: '#zenika',
  data: { consultants: [ ... ] },
  methods: {
    add(){
        this.consultants.push({name: 'Antoine'})
    }
  }
})

Toute notre app dans la même Vue ? 

Les Composants

VueJS - Global Components

<div id="zenika">   
    <ul>
       <li ...> ... </li>   
    </ul>
    <c-form></c-form>
</div>
Vue.component('c-form', {
   template: '<input /><button>Add</button>',
   data(){
    return {
        ...
    }
   }
})

let app = new Vue({
  el: '#zenika'
});

VueJS - Global Components

VueJS - Global Components

<div id="zenika">
    <ul>
       <li ...> ... </li>
    </ul>
    <c-form :value="'Arnaud'"></c-form>
</div>
Vue.component('c-form', {
   template: `
        {{ value }}
        <button>Add</button>'
   `,
   props: ['value']
})

let app = new Vue({ ... });

VueJS - Global Components

<div id="zenika">
    <ul>
       <li ...> ... </li>
    </ul>
    <c-form :value="'Arnaud'"></c-form>
</div>
Vue.component('c-form', {
   template: `
        {{ value }}
        <button>Add</button>'
   `,
   props: {
        value: {
            type: String, 
            required: false,
            default: 'Manu'
        }
   }
})

VueJS - Global Components

Vue.component('c-form', {
   template: `
        {{ value }}
        <button @click="click">Add</button>'
   `,
   props: ['value'],
   methods: { 
      click(){
          this.$emit('newconsultant', this.value)
      }
   }
});

VueJS - Global Components

<div id="zenika">
    <ul>
       <li ...> ... </li>
    </ul>
    <c-form :value="'Arnaud'"
            @newconsultant="add"></c-form>
</div>
let app = new Vue({ 
    ...,
    methods: {
        add(consultant){
            this.consultants.push(consultant)
        }
    } 
});

VueJS - local component

let cForm =  {
   template: `...`,
   props: ['value'],
   methods: { 
      click: ...
   }
})

let app = new Vue({ 
    ...,
    components: {
      'c-form': cForm  
    } 
});

VueJS - Fichiers .vue

- Import via des modules ECMAScript 2015

     - meilleur découpage, testable facilement

- Tout le code au même endroit

- Intégration WebPack (hot reloading, préprocesseurs CSS, ...)

- CSS scopé

 

VueJS - Fichiers .vue

<template>
    <c-form></c-form>
</template>

<script>
    import Form from './Form.vue'

    export default {
       props: ['value'],
       components: {
        'c-form': Form
       }
    }
</script> 
   
<style lang="css" scoped>...</style>

Les Directives

VueJS - Directives

<ul id="zenika">
    <li v-for="c in consultants" 
        v-if="c.name != 'Aurélien'">
      {{ c.name }}
   </li>
</ul>
let app = new Vue({
  el: '#zenika',
  data: {
    consultants: [ 
        {name: 'Manu'}, 
        {name: 'Aurélien'}
    ]
  }
})

v-for, v-if, v-else
v-model, v-once, v-bind, v-show, v-cloak, ...

VueJS - Directives

<div id="zenika">
  <input type="text" v-required>  
</div>
Vue.directive('required', {
  inserted(el) {
    el.addEventListener('blur', () => {
    	if(!el.value) {
      	el.classList.add('has-error');
      } else {
      	el.classList.remove('has-error');
      }
    })
  }
})

Les Filtres

  • Manipulation de la donnée avant affichage
  • Fonction de transformation locale ou globale
  • Utilisation du | l'exécuter

 

Filtre global

Vue.filter('reverse', value => {
  return value.split('').reverse().join('')
});

let app = new Vue({ 
    ...
});
<ul id="zenika">
      {{ c.name | reverse }}
</ul>

Filtre Local

let app = new Vue({ 
    ...,
    filters: {
        uppercase(value){
            return value.toUpperCase();
        }
    }
});
<ul id="zenika">

    {{ c.name | uppercase }}

</ul>

Computed Values

let app = new Vue({ 
    ...,
    computed: {
        sortedUsers(){
            return this.data.sort( ... );
        }
    }
});
<ul id="zenika">
   <ul>
         <li v-for="user in sortedUsers">
            {{name}}
        </li>
   </ul>
</ul>

HTTP

  • Utilisation du module Axios
  • Module permettant d'exécuter des requêtes HTTP
  • Utilisation des Promise
  • Support des Intercepteurs
  • Possibilité de définir une configuration globale

axios - $http

import Vue from 'vue';
import axios from 'axios';

Vue.prototype.$http = axios;

axios - $http

import Vue from 'vue';
import axios from 'axios';

Vue.prototype.$http = axios;

axios.defaults.baseURL = '/api';
axios.defaults.headers
    .common['Authorization'] = 'token';

axios - $http

import Vue from 'vue';
import axios from 'axios';

Vue.prototype.$http = axios;

axios.defaults.baseURL = '/api';
axios.defaults.headers
    .common['Authorization'] = 'token';

axios.interceptors.request.use(config => {
    //Mise à jour de la requête
    return config;
});
axios.interceptors.response.use(response => {
    //Mise à jour de la réponse
    return response;
});

axios - $http

this.$http.get(url, [options])

this.$http.head(url, [options])

this.$http.delete(url, [options])

this.$http.jsonp(url, [options])

this.$http.post(url, [body], [options])

this.$http.put(url, [body], [options])

this.$http.patch(url, [body], [options])

axios - $http

let conferences = [];

this.$http.post('/devoxx', {day: 1})
    .then(response => {

        //response.status;

        conferences = response.data;

    }, response => {

        // error callback

    });

axios - $http

let app = new Vue({ 
    datas: {
        conferences: []
    },
    created(){
        this.$http.get('/devoxx')
            .then(response => {
                this.conferences = response.data;
            });
    } 
});

Le Routeur

  • Configuration orientée composant
  • Utilisation des composants router-link et router-view
  • Récupération des informations courantes via l'objet $route
  • Redirection programmatique via l'objet $router
  • Support du lazy loading, des guards, des vues nommées et vues imbriquées

VueJS - Routeur

const Conferences = { template: '<div>Conférences Page</div>' }
const Conference = { template: '<div>Conférence Page</div>' }
const Inscription = { template: '<div>Inscription Page</div>' }

const routes = [
  { path: '/conferences', component: Conferences },
  { path: '/conference/:id', component: Conference },
  { path: '/inscription', component: Inscription }
]

const router = new VueRouter({
  routes 
})

const app = new Vue({
  el: '#app',
  router
})

VueJS - Routeur

<nav>
    <ul>
        <li>
          <router-link to="/conferences">Conférences</router-link>
        </li>
        <li>
          <router-link to="/inscription">Inscription</router-link>
        </li>
    </ul>
</nav>

<router-view></router-view>    

VueJS - Routeur

//Conference.vue

export default {
  data () {
    return {
      conference: null
    }
  },
  created () {
    this.getConference()
  },
  watch: {
    '$route': 'getConference'
  },
  methods: {
    getConference () {
      this.$http.get(`/conference/${this.$route.params.id}`)
        .then(data => this.conference = data.body);
    },
    goHome () {
        this.$router.push('/');    
    }
  }
}

Les Formulaires

Devinez le nom de la directive pour interagir avec un <input / > ?

  • Utilisation de la directive v-model
  • Support tous les inputs HTML
  • Possibilité de définir des Modifiers
  • Pas de système de validation des données
  • Persistance de la donnée lors du submit du formulaire

VueJS - Models

<form @submit="add">
   <input v-model="consultant" />
   <button type="submit">Add</button>
</form>
let app = new Vue({
  el: '#zenapp',
  data: { consultant: '', consultants: [ ... ] },
  methods: {
    add(){
        this.consultants.push({
            name: this.consultant
        });
        this.consultant = '';
    }
  }
})

VueJS - Models

<form @sumit="add">
   <input v-model.trim="consultant" /><!--.number-->
   <button type="submit">Add</button>
</form>
let app = new Vue({
  el: '#zenapp',
  data: { consultant: '', consultants: [ ... ] },
  methods: {
    add(){
        this.consultants.push({
            name: this.consultant
        });
        this.consultant = '';
    }
  }
})

VueJS - Validateurs

<form @sumit="add">
   <input v-model="password" name="password" 
            v-validate="'required'"/> 
   
   <span v-show="errors.has('password')" class="error">
        {{ errors.first('password') }}
   </span>
  
   <button type="submit">Add</button>
</form>
import Vue from 'vue';
import VeeValidate from 'vee-validate';

Vue.use(VeeValidate);

Vuex

  • Centralisation de l'état de votre application et des mutations dans un store
  • Toutes mises à jours d'une donnée passera par un commit
  • Création d'un mapping entre une variable locale et une variable du store
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    agenda:[]
  },
  mutations: {
    addConference(state, conference) {
      state.agenda.push(conference);
    }
  }
});

new Vue({
  el: '#app',
  store,
});

VueX

<template>
    <div>
        Vous avez choisi {{ conferences.length}} 
        conferences

        <button @click="add">Ajoutez cette conference</button>
    </div>
</template>

<script>
module.exports {
   computed: {
      conferences() {
        return this.$store.state.agenda;
      }
   },
   methods: { 
      add(){
          this.$store.commit('addConference', 'VueJS');
      }
   }
}
</script>

VueX

Emmanuel DEMEY

@EmmanuelDemey

Zenika Lille

 

Aurélien LOYER

@AurelienLoyer

Zenika Lille

VueJS

By Nathan Damie

VueJS

  • 950