Vue.js
Data-reactive web components
Bonjour, je m'appelle Eduardo et aujourd'hui je vais vous parler de
vuejs. Un framework MVVM que j'ai découvert il y a quelques mois, que
j'utilise depuis et lequel me plait de plus en plus.
Un autre MV* ?!
j'ai dit que c'était un framework MVVM. C'est vrai qu'il y en a
plein. C'est comme si tout le monde avait vu Angular, s'était dit
"C'est stylé de faire des applis comme ça, mais j'aimerais X" ou je
n'aime pas Y". Et du coup tout le monde a eu envie de faire son
propre Framework. Certains l'on fait, d'autres se sont dit qu'ils
avaient pas le temps (la classique). Et du coup plus de 20 frameworks
existent aujourd'hui. Tels que Angular, React, Aurelia, Angular2,
Mithril et aussi Vuejs.
Pourquoi Vue ?
- Equilibre Performance – Usabilité
- Orienté Components
- Communauté très active !
Et si je parle de Vuejs aujourd'hui c'est parce que ce framework
établi un Equilibre entre performance et Usabilité. Je dirait meme
qu'il arrive a trouver le compromis que React et Angular manquent.
C'est orienté composants ou components en anglais. j'en reparlerai
plus tard
Issues crées tous les jours (un peu moins les we) et tout le monde qui répond
chat Gitter pour discuter ou demander de l'aide
Documentation solide
tout ça pour componser un manque de questions sur stack overflow
Hello World
<div id="hello-world">
<input v-model="value" type="text"/>
<p>{{value}}</p>
</div>
new Vue({
el: '#hello-world',
data: {
value: 'Hello World'
}
});
{{value}}
On va directement passer à un hello world. Je vais à chaque fois
on créé un vm pour lier div et data, une directive pour input
Le Vocabulaire
Il y qq nouveaux mots. On va donc en parler
Anvant de rentrer un peu plus dans les details de vue on va parler des
principaux termes utilisés. Il y en a pas beaucoup :D
Les Directives
v-model
,v-if
, ...- Custom directives(commencent toujours par v-)
<input v-model="value" type="text"/>
Tous les v- sont des directives
v-model est une directive mais type ne l est pas
Le View Model (vm
)
View ⇆ Model
new Vue({...});
Le vm se charge de sync les données avec la vue
La vm est crée quand on instancie une Vue
Elle a toute la logique et ne comporte pas de manipulation du DOM(faites dans les
directives)
Le View Model (vm
)
Props
Données passées à un component
<contact-card featured></contact-card>
<contact-card type="rounded"></contact-card>
<contact-card v-bind:contact="contact"></contact-card>
ça va remplacer le ng-class et ng-checked et plein d'autres
Ce qui est plus expressif car v-contact pourrait être une directive
Fontionnalités classiques
les impasses, mais avant on va parler des concepts de base de vue
Le v-show
/v-if
<div id="v-show">
<input v-model="show" type="checkbox"/>
<span>
{{show ? 'Hide the bear' : 'Show the bear'}}
</span>
<img v-show="show" src="images/bear-hello.gif"/>
</div>
new Vue({
el: '#v-show',
data: {
show: false
}
});
Le v-for
<div id="v-for">
<ul>
<li v-for="item in items">{{item}}</li>
</ul>
</div>
new Vue({
el: '#v-for',
data: {
items: [0, 1]
}
});
There are {{items.length}} elements
- {{item}}
Le transition
Le v-bind
<form v-bind:class="{'invalid-form': invalid}"></form>
<form :class="{'invalid-form': invalid}"></form>
<form class="form-control" :class="{'invalid-form': invalid}"></form>
Les Events(v-on)
<form v-on:submit="send()"></form>
<form @submit="send()"></form>
<button @click="select(contact)">Select</button>
Vue js fonctionne avec des events en interne. On peut emmettre
des evenements sur des components qui remontent vers les parents
Les filtres
Adapter le modèle à la vue
<div id="filters">
<p>{{obj | json}}</p>
</div>
new Vue({
el: '#filters',
data: {
obj: {
bool: true,
arr: [1, 2],
inner: {
a: null
}
}
}
});
{{obj | json}}
quand on veut modifier les données avant de les afficher
on peut les chainer les un à la suite des autres
On peut passer des argument
et on peut bien sur creer ses propres filtres
C'est tout ?
Il manque bien sur plein de trucs. c'est pour ca que lon utilise des plugins.
On evite de construire une usine a gaz
La consistence dans Vue
elles sont la pour faire que le dev n'ai pas a se poser de questions
lorsqu'il doit écrire du code.
réactif = prend une expression
Les Directives sont par défaut réactives
<p v-text="message"></p>
<a v-link="/foo">Go to foo</a>
<a v-link="'/foo'">Go to foo</a>
<a v-link.literal="/foo">Go to foo</a>
Tout ça dans le but d'être consistent et lisible
Les attributs et les props sont par défaut non réactifs
<img src="images/default-user.png"/>
<img :src="user.picture"/>
<contact-card :contact="user"></contact-card>
Ce qui a du sens pour les props car ça veut être la même chose
vue sait que c'est un lien et qu'il faut faire une requete
Mustache binding
Pour interpoler du texte
<p>URL is {{imgUrl}}</p>
<img src="{{imgUrl}}"/>
<img :src="imgUrl"/>
Binding modes
:prop='defaultOneWay'
:prop.sync='twoWay'
:prop.once='oneTime'
<mdl-checkbox :checked.sync="confirm">Confirm</mdl-checkbox>
Le sync est tres utile lorsque l'on crée des composants tels que des checkboxs
Les Hooks
created, beforeCompile, compiled, ...
ready: function() {
componentHandler.upgradeElement(this.$el);
}
Component System
Components search et contact-grid
<div id="contacts">
<search id="contacts-search" :submit="fetchResults"></search>
<contact-grid id="contacts-results" :contacts="contacts">
</contact-grid>
</div>
Le format .vue
il y a du template, du js et meme du style
Inline template
var MyComponent = Vue.extend({
template: '<p>A custom component!</p>'
});
Regrouper le template HTML avec le js
<template> <div class="contacts-card row" v-for="contact in contacts"> <img :src="contact.imgUrl" class="contacts-img col-4"/> <div class="contacts-info col-8"> <span>{{contact.firtsName}} {{contact.lastName}}</span> </div> </div> </template>
<script>
module.exports = { props: { contact: { type: Object, required: true } } };
</script>
Regrouper le template Jade avec le Coffee
<template lang="jade">
.contacts-card.row(v-for'contact in contacts') img.contacts-img.col-4(:src='contact.imgUrl') .contacts-info.col-8 span {{contact.firtsName}} {{contact.lastName}}
</template>
<script lang="coffee">
module.exports = props: contact: type: Object required: true
</script>
Ajouter le style aussi
<template lang="jade">
</template>
<style lang="stylus">
.contacts-card display: inline-block .contacts-info background-color: gray
</style>
<script lang="coffee">
</script>
Transformer les .vue
en .js
- Browserify:vueify
- Webpack:vue-loader