VueJS
/vju:/
Emmanuel DEMEY et Aurélien LOYER
https://www.sli.do/ #8423
Emmanuel DEMEY
@EmmanuelDemey
Zenika Lille
Aurélien LOYER
@AurelienLoyer
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'})
}
}
})
PW #1
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>
PW #2
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');
}
})
}
})
PW #3
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>
PW #4
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;
});
}
});
PW #5
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('/');
}
}
}
PW #6
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);
PW #7
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
PW #8
Emmanuel DEMEY
@EmmanuelDemey
Zenika Lille
Aurélien LOYER
@AurelienLoyer
Zenika Lille
Devoxx - VueJSœ
By Emmanuel Demey
Devoxx - VueJSœ
- 4,713