Share
Embed
Level-up apps and websites with vue.js
Firenze, piazza madonna della neve. Organized by Commit University.
Lorenzo Girardi
February 22, 2018
Transcript
80 slides
-
i am a front-end dev and a passionate musician twitter:
@loregirardi github: @liqueflies -
digital company with strong focus on strategy and technology website:
https://www.develondigital.com/ -
Our team was searching for a tool with data driven
development in mind... ...and a lean learning curve because we had to be production-ready ASAP. twitter: @loregirardi github: @liqueflies -
website: https://vuejs.org/ numbers > 82k stars (87k react, 32k angular)
~ 4000 packages depends on it > 1.000.000 download last month $ 11.567 per month by 204 patreons 2 vueconf in 2018 (amsterdam, new orleans) -
<script src="vue.js"></script> <div id="app"> <p>{{ message }}</p> </div> <script> new
Vue({ el: '#app', data: { message: 'Hello commit people!' } }) </script> https://vuejs.org/ hello world -
<script src="vue.js"></script> <div id="app"> <img v-bind:src="src" :alt="alt" /> </div> <script>
new Vue({ el: '#app', data: { src: 'https://picsum.photos/200/300', alt: 'A random pic from the web.' } }) </script> https://vuejs.org/v2/guide/syntax.html attributes binding -
<script src="vue.js"></script> <div id="app"> <p v-if="visible"> I’m not rendered </p>
<p v-show="visible"> I’m hidden [i.e. display: none] </p> </div> <script> new Vue({ el: '#app', data: { visible: false } }) </script> https://vuejs.org/v2/guide/syntax.html conditional render/display -
<script src="vue.js"></script> <ul id="app"> <li v-for="todo in todos" :key="todo"> {{
todo }} </li> </ul> <script> new Vue({ el: '#app', data: { todos: ['eat', 'sleep', 'repeat'] } }) </script> https://vuejs.org/v2/guide/syntax.html loop through elements -
<script src="vue.js"></script> <div id="app"> <p> {{ message }} </p> <button
@click="message = ''"> Reset </button> </div> <script> new Vue({ el: '#app', data: { message: 'Please, reset me!' } }) </script> https://vuejs.org/v2/guide/syntax.html handle user input -
<script src="vue.js"></script> <div id="app"> <p> you typed: {{ message }}
</p> <input v-model="message" placeholder="start typing..." /> </div> <script> new Vue({ el: '#app', data: { message: '' } }) </script> https://vuejs.org/v2/guide/syntax.html handle user input -
syntax Focusing - semantic code - easy to read -
easy to maintain - easy to share code in teams. -
setting data Focusing set data in vue.js is not async.
is the same as you do in javascript. this.setState({ counter: this.state.counter++ }) this.setState({ counter: this.state.counter++ }) have you ever tried? -
<ul id="app"> <p> The higher number is: {{ higherNumber }}
</p> </ul> new Vue({ el: '#app', data: { numbers: [100, 2, 345, 42, 56] }, computed: { higherNumber: function () { return Math.max(...this.numbers) } } }) https://vuejs.org/v2/guide/syntax.html computed -
<div id="app"> <p v-show="visible"> I am visible. </p> <button @click="toggleVisibility">
toggle visibility </button> </div> new Vue({ el: '#app', data: { visible: false }, methods: { toggleVisibility: function (event) { this.visible = !this.visible } } }) https://vuejs.org/v2/guide/syntax.html methods -
computed Focusing - runs when its own dependencies updates -
called and used as data properties - is cached -
methods Focusing - runs when you need to use it
- called as a function in event bindings - is not cached -
summary Focusing - no this hell (context is auto-binded) -
no async data beginner failures - no shouldUpdate worries - no build steps needed -
<the-header /> <aside> <main-menu /> </aside> <main> <blog-posts /> </main>
<the-footer /> https://vuejs.org/v2/components.html components tree structure -
component Focusing - encapsulation of elements that can be accessed
through one single element. - encapsulation of logic, but in different instances - encapsulation of style (module, scoped) -
// ...in root component <div id="app"> <card-item /> </div> Vue.component('card-item',
{ template: '...', data: function () { return { ... } } }) https://vuejs.org/v2/components.html -
<script type="text/x-template" id="card-template"> <article> <h2> {{ title }} </h2> <img
:src="img" :alt="title" /> </article> </script> Vue.component('card-item', { template: '#card-template', data: function () { return { title: 'A card title' img: 'https://picsum.photos/200/300' } } }) https://vuejs.org/v2/components.html -
{ ... data () { return { title: 'A card
title' img: 'https://picsum.photos/200/300' } } ... } https://vuejs.org/v2/components.html data is a function -
now we can encapsulate logic and style in a component.
by for now, we are using it statically. twitter: @loregirardi github: @liqueflies -
Vue.component('card-item', { template: '#card-template', props: ['title', 'img'] }) // ...in
root component <div id="app"> <card-item title="Title from parent" src="https://picsum.photos/200/300" /> </div> https://vuejs.org/v2/components.html … better use props -
<div id="app"> <card-item propA="..." propB="..." propC="..." propD="..." ... /> </div>
https://vuejs.org/v2/components.html this could be sick -
Vue.component('card-item', { inheritAttrs: false, // important to avoid unwanted markup
template: '#card-template', props: ['title', 'img'] }) <div id="app"> <card-item v-bind="card" /> </div> new Vue({ el: '#app', data: { card: { title: 'Card title', img: 'https://picsum.photos/200/300' } } }) https://vuejs.org/v2/components.html v-bind to the rescue -
lifecycle Focusing each vue instance goes through a series of
initialization steps when it’s created running functions called lifecycle hooks, giving users the opportunity to add their own code at specific stages. -
Vue.component('card-item', { template: '...', data: function () { return {
image: '...' } }, mounted: function () { var image = this.image this.image = '...my-spinner-image.png' new imagesLoaded(this.$el, { this.image = image }) } }) https://vuejs.org/v2/components.html -
<div id="app"> <component :is="componentName" /> </div> new Vue({ el: '#app',
data: { componentName: '...' } }) https://vuejs.org/v2/components.html the :is attribute -
<template lang="pug"> // ... </template> <script> // export default {}
</script> <style lang="sass|scss|stylus" module|scoped> // ... </style> https://vuejs.org/v2/components.html single file components -
by passing props we can mutate child data from parent.
how can we mutate parent data from its children? twitter: @loregirardi github: @liqueflies -
<script type="text/x-template" id="slider-pag-template"> <div> <button @click="$emit('next-slide')"> Next slide </button> <button
@click="$emit('prev-slide')"> Prev slide </button> </div> </script> Vue.component('slider-pag', { template: '#slider-pag-template' }) <div id="app"> <slider-pag @next-slide="slide++" @prev-slide="slide--" /> </div> https://vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events -
and what if we want to change data... ...wherever in
the component tree? twitter: @loregirardi github: @liqueflies -
// broadcast event var bus = new Vue() // send
event bus.$emit('event-name', ...arguments) // receive event bus.$on('event-name', ...arguments) // unbind event bus.$off('event-name') event bus https://vuejs.org/v2/components.html#Content-Distribution-with-Slots -
// send event new Vue({ ... methods: { myMethod: function
() { bus.$emit('event-name', ...arguments) } } }) event bus https://vuejs.org/v2/components.html#Content-Distribution-with-Slots -
// receive event new Vue({ ... created: function () {
bus.$on('event-name', myMethod) }, methods: { myMethod: function () { ... } } }) event bus https://vuejs.org/v2/components.html#Content-Distribution-with-Slots -
transitions Focusing transition component allows to add enter/leave effects to:
- conditions (v-if / v-show) - dynamic components - component root node - switching :key attribute website: https://vuejs.org/v2/guide/transitions.html -
<div id="app"> <transition name="fade"> <p v-show="visible"> I am visible. </p>
</transition> <button @click="visible = !visible"> toggle </button> </div> <style> .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to { opacity: 0; } </style> https://vuejs.org/v2/guide/syntax.html -
<div id="app"> <transition name="fade"> <p v-show="visible"> I am visible. </p>
</transition> <button @click="visible = !visible"> toggle </button> </div> <style> .fade-enter-active { transition: opacity .2s ease; } .fade-leave-active { transition: opacity .3; } .fade-enter, .fade-leave-to { opacity: 0; } </style> https://vuejs.org/v2/guide/syntax.html -
<div id="app"> <transition name="fade" mode="out-in|in-out"> <component :is="pageName" /> </transition> </div>
<script> new Vue({ el: '#app', props: ['pageName'] }) </script> https://vuejs.org/v2/guide/syntax.html -
<div id="app"> <transition @enter="enterAnimation"> <component :is="pageName" /> </transition> </div> <script>
new Vue({ el: '#app', props: ['pageName'], methods: { enterAnimation (el, done) { /* your code */ } } }) </script> https://vuejs.org/v2/guide/syntax.html -
in real use cases we have to display data from
server. what’s the better way to achieve that? twitter: @loregirardi github: @liqueflies -
<script src="vue.js"></script> <ul id="star-wars"> <li v-for="person in people" :key="person.name"> {{
person.name }} </li> </ul> <script> new Vue({ el: '#star-wars', data: { people: [] }, created: function () { fetch('https://swapi.co/api/people').then(function (response) { this.people = response.results }) } }) </script> -
in fast connections we will immediately see results. how can
we add a loader for slow connections? twitter: @loregirardi github: @liqueflies -
no build steps required Easy to start up, also in
old legacy projects. website: https://vuejs.org/ -
effortless api update and modify data is easy. context is
auto-binded and rendering updates are out of the box. website: https://vuejs.org/ -
add modularly what you need if your app / website
needs to scale just add modules from vue.js ecosystem to fit your needs. website: https://vuejs.org/ -
no es6 knowledge needed i am not telling you to
not learn es6. but if you want you can still use old es2015 syntax so beginner / not-frontend dev can easily get into it. website: https://vuejs.org/ -
super fast on mobile devices is easy achieve fast rendering
on desktop, vue.js get the best experience on mobile devices. website: https://vuejs.org/ -
useful resources - curated list: https://github.com/vuejs/awesome-vue - official forum: https://forum.vuejs.org/
- vuex: https://github.com/vuejs/vuex - vue-router: https://router.vuejs.org/en/ - vue-cli: https://github.com/vuejs/vue-cli - server-side rendering: https://vuejs.org/v2/guide/ssr.html website: https://vuejs.org/ -
vue people - evan you: https://twitter.com/youyuxi - kazupon: https://twitter.com/kazu_pon -
linusborg: https://twitter.com/Linus_Borg - akryum: https://twitter.com/Akryum - katashin: https://twitter.com/ktsn - sarah drasner: https://twitter.com/sarah_edo website: https://vuejs.org/team.html -
vue community is growing quickly but is recent. let’s share
knowledge, code and passion. twitter: @loregirardi github: @liqueflies