Vue.js
/vju:/
@AurelienLoyer
Aurélien LOYER
@AurelienLoyer
CTO Zenika Montréal
Vue.js - Plan
- Les Composants
- Les Directives
- Les Filtres
- HTTP
- Routeur
- Formulaire
- VueX
Vue.js
- 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
// OR
yarn global add @vue/cli
// vue init webpack my-project
vue create my-project
cd my-project
npm install
npm run serve
npm run build
Vue.js - Interpolation
<div id="zenika">
{{ message }}
</div>
let app = new Vue({
el: '#zenika',
data() {
return {
message: 'Hello Zenika!'
}
}
})
Vue.js - Bindings
<div id="zenika" v-bind:class="css">
{{ message }}
</div>
let app = new Vue({
el: '#zenika',
data() {
return {
message: 'Hello Zenika!',
css: 'rouge-zenika'
}
}
})
Vue.js - Bindings
<div id="zenika" :class="css">
{{ message }}
</div>
let app = new Vue({
el: '#zenika',
data() {
return {
message: 'Hello Zenika!',
css: 'rouge-zenika'
}
}
})
Vue.js - Events Handlers
<ul id="zenika">
<button v-on:click="add">Add Aurélien</button>
</ul>
let app = new Vue({
el: '#zenika',
data: { consultants: [ ... ] },
methods: {
add(){
this.consultants.push({name: 'Aurélien'})
}
}
})
Vue.js - Events Handlers
<ul id="zenika">
<button @click="add('Aurélien')">Add Aurélien</button>
</ul>
let app = new Vue({
el: '#zenika',
data: { consultants: [ ... ] },
methods: {
add(name){
this.consultants.push({name})
}
}
})
PW #1
Toute notre app dans la même Vue ?
Les Composants
Vue.js - 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'
});
Vue.js - Global Components
Vue.js - 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({ ... });
Vue.js - 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'
}
}
})
Vue.js - Global Components
Vue.component('c-form', {
template: `
{{ value }}
<button @click="click">Add</button>'
`,
props: ['value'],
methods: {
click(){
this.$emit('newconsultant', this.value)
}
}
});
Vue.js - 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)
}
}
});
Vue.js - local component
let cForm = {
template: `...`,
props: ['value'],
methods: {
click: ...
}
})
let app = new Vue({
...,
components: {
'c-form': cForm
}
});
Vue.js - Cycle de vie
.vue
Vue.js - 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é
Vue.js - 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
Vue.js - 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, ...
Vue.js - 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
-
Fin de vue-resource ...
- 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 - <script>
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
VueX
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
VueX
PW #8
MERCI !
🙏
@AurelienLoyer
@T3kstiil3
Handson - VueJS
By Aurelien Loyer
Handson - VueJS
Depuis le temps que vous allez à des conférences, vous avez sûrement participé à des codelabs React et/ou Angular. Vous êtes même devenu peut-être un expert sur l'une de ces technos. C'est pour cela que nous avons décidé de ne pas choisir l'un de ces deux projets. Pendant ce codelab, nous avons choisi une toute autre librairie que nous sommes en train de tester pour des projets perso : VueJS. A travers ces 3 heures, nous allons aborder tous les concepts vous permettant de créer une application riche : composants, directives, mixins, routers, ... A la fin de ce codelab, vous allez pouvoir vous rendre compte que VueJS gagne le combat des frameworks/librairies JavaScript par sa simplicité et sa facilité de mise en oeuvre, tout en réutilisant certains concepts de ses deux concurrents.
- 3,360