88
Enjoy the Vue.js @andywoodme

Enjoy the vue.js

Embed Size (px)

Citation preview

Page 1: Enjoy the vue.js

Enjoy the Vue.js

@andywoodme

Page 2: Enjoy the vue.js
Page 3: Enjoy the vue.js
Page 4: Enjoy the vue.js
Page 5: Enjoy the vue.js
Page 6: Enjoy the vue.js
Page 7: Enjoy the vue.js

<html> <head> <title>My Fab App</title> </head> <body> <my-fabulous-app></my-fabulous-app> </body> </html>

Page 8: Enjoy the vue.js

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>My Fab App</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="app"> <my-fabulous-app></my-fabulous-app> </div> <script src="app.js"></script> </body> </html>

Page 9: Enjoy the vue.js

Vue.js can do this*

Page 10: Enjoy the vue.js

Vue.js 2.0

Page 11: Enjoy the vue.js
Page 12: Enjoy the vue.js

Progressive Web Framework by Evan You

Page 13: Enjoy the vue.js

Less More

React Vue Angular Ember MeteorTemplating!Engines

Backbone

Page 14: Enjoy the vue.js

<body> <div id="app"> {{ name }} </div> <script src="vue.js"></script> <script> var app = new Vue({ el: '#app', data: { name: 'Hello!' } }) </script> </body>

index.html

Page 15: Enjoy the vue.js

DOM (Page)

Data (State)

Reactive

Page 16: Enjoy the vue.js
Page 17: Enjoy the vue.js

<body> <div id="app"> <input v-model="name"> {{ name }} </div> <script src="vue.js"></script> <script> var app = new Vue({ el: '#app', data: { name: 'Hello!' } }) </script> </body>

index.html

Page 18: Enjoy the vue.js
Page 19: Enjoy the vue.js
Page 20: Enjoy the vue.js

<div id="app"> <select v-model="type"> <option value="icon-dice">Board Game</option> <option value="icon-spades">Card Game</option> </select> <input v-model="name"> <p> <span :class="type"></span> {{ name }} </p> </div>

index.html

! data: { name: 'Snakes and Ladders', type: 'icon-dice' }

Page 21: Enjoy the vue.js
Page 22: Enjoy the vue.js

One-way text interpolation !{{ message }} !!One-way binding !<option v-bind:selected="value">...</option> !!Two-way binding !<input v-model="message">

Page 23: Enjoy the vue.js

</select> <input v-model="game"> <button @click="games.push({name: name, type: type})”>Add</button> ! <p v-if="games.length == 0">Zarro Boords!</p> <ul v-else> <li v-for="game in games"> <span :class="game.type"></span> {{ game.name }} </li> </ul> </div>

index.html

! data: { name: 'Snakes and Ladders', type: 'icon-dice', games: [] }

Page 24: Enjoy the vue.js
Page 25: Enjoy the vue.js

<input v-model="name"> <button @click="games.push({name: name, type: type})">Add</button> <p v-if="empty">Zarro Boords!</p> <ul v-else> <li v-for="game in games"> !

index.html

! data: { name: '', type: 'dice', games: [] }, computed: { empty: function() { return this.games.length == 0 } }

Page 26: Enjoy the vue.js

</select> <input v-model="name" @keyup.enter="addGame"> <button @click="addGame">Add</button> <p v-if="empty">Zarro Boords!</p> <ul v-else> !

index.html

computed: { empty: function() { return this.games.length == 0 } }, methods: { addGame: function () { this.games.push({ name: this.name, type: this.type }) } }

Page 27: Enjoy the vue.js

<select v-model="type"> <option value="dice">Board Game</option> <option value="spades">Card Game</option> </select> : : <span :class="icon(game.type)"></span>

index.html

computed: { empty: function() { return this.games.length == 0 } }, methods: { icon: function (type) { return 'icon-' + type }, addGame: function () { this.games.push({

Page 28: Enjoy the vue.js
Page 29: Enjoy the vue.js

<div id="app"> <select v-model="type"> <option value="dice">Board Game</option> <option value="spades">Card Game</option> </select> <input v-model="name" @keyup.enter="addGame"> <button @click="addGame">Add</button> <p v-if="empty">Zarro Boords!</p> <ul v-else> <li v-for="game in games"> <span :class="icon(game.type)"></span> {{ game.name }} </li> </ul> </div>

index.html

Page 30: Enjoy the vue.js

<script> var app = new Vue({ el: '#app', data: { name: '', type: 'dice', games: [] }, computed: { empty: function() { return this.games.length == 0 } }, methods: { addGame: function () { this.games.push({ name: this.name, type: this.type }) }, icon: function (type) { return 'icon-' + type } } }) </script>

index.html

Page 31: Enjoy the vue.js

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>My Fab App</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="app"> <my-fabulous-app></my-fabulous-app> </div> <script src="app.js"></script> </body> </html>

Page 32: Enjoy the vue.js

Components

Page 33: Enjoy the vue.js

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>iBoards</title> <link rel="stylesheet" href="css/fonts.css"> </head> <body> <div id="app"> <board-library></board-library> </div> <script src="dist/app.js"></script> </body> </html>

index.html

Page 34: Enjoy the vue.js

var Vue = require('vue') var BoardLibrary = require('./BoardLibrary.vue') !Vue.component('board-library', BoardLibrary) var app = new Vue({ el: '#app' })

main.js

Page 35: Enjoy the vue.js

<template> <div> <select v-model="type"> <option value="dice">Board Game</option> : </div> </template> !<script> module.exports = { data: function() { return { game: '', type: 'dice', games: [] : </script>

BoardLibrary.vue

Page 36: Enjoy the vue.js

!// dependencies var Vue = require('vue') !// module implementation function myFunc() { : } !// exported module.exports = { myFunc: myFunc }

CommonJS

Node / Server Side

Page 37: Enjoy the vue.js

BoardLibrary.vue

main.js

app.js

npm install -g vue-cli vue init browserify-simple my-project !Using grunt or gulp already? vueify or vue-loader slot straight in

vue.js

Page 38: Enjoy the vue.js
Page 39: Enjoy the vue.js

Components

Page 40: Enjoy the vue.js

Component

Page 41: Enjoy the vue.js

Sub-components

Page 42: Enjoy the vue.js

Properties

:data="value"

props: ['data']

Page 43: Enjoy the vue.js

<p v-if="empty">Zarro Boords!</p> <ul v-else> <board-game v-for="game in games" :type="game.type" :name="game.name"></board-game> </ul>

BoardLibrary.vue

<script> var BoardGame = require('./BoardGame.vue') !module.exports = { data: function() { : components: { BoardGame: BoardGame } } </script>

Page 44: Enjoy the vue.js

<template> <li> <span :class="icon"></span> {{ name }} </li> </template> !<script> module.exports = { props: [ 'name', 'type' ], computed: { icon: function () { return 'icon-' + this.type } } } </script>

BoardGame.vue

Page 45: Enjoy the vue.js

<ul> <board-game v-for="game in games" :type="game.type" :name=“game.name"></board-game> </ul>

BoardLibrary.vue

! props: ['name', ‘type’], computed: { icon: ...

BoardGame.vue

<li> <span :class="icon"></span> {{ name }} </li>

! data: { games: [ { name: 'Carcasonne', type: 'dice' }, { name: 'Linkee', type: 'spade' } ] }

kebab

camel

Page 46: Enjoy the vue.js

Events

props: ['data']

@event="handler"

this.$emit('event')

:data="value"

Page 47: Enjoy the vue.js

<template> <div> <board-add @add="handleAdd"></board-add> <p v-if="empty">Zarro Boords!</p> <ul v-else> <board-game v-for="game in games" :type="game.type" :name="game.name"></board-game> </ul> </div> </template> !<script> var BoardAdd = require('./BoardAdd.vue') var BoardGame = require('./BoardGame.vue') !module.exports = { data: function() { return { games: [] } }, : methods: { handleAdd: function (game) { this.games.push(game) } }, components: { BoardAdd: BoardAdd, BoardGame: BoardGame } } </script>

BoardLibrary.vue

Page 48: Enjoy the vue.js

<template> <div> <select v-model="type"> <option value="dice">Board Game</option> <option value="spades">Card Game</option> </select> <input v-model="name" @keyup.enter="add"> <button @click="add">Add</button> </div> </template> !<script> module.exports = { data: function() { return { name: '', type: 'dice', } }, methods: { add: function () { this.$emit('add', { name: this.name, type: this.type }) } } } </script>

BoardAdd.vue

Page 49: Enjoy the vue.js
Page 50: Enjoy the vue.js

<template> <span class="icon-bin" @click="del"></span> </template> !<script> module.exports = { props: [ 'index' ], methods: { del: function () { this.$emit('delete', this.index) } } } </script>

BoardDelete.vue

Page 51: Enjoy the vue.js

<board-game v-for="(game, index) in games" :type="game.type" :name="game.name"> <board-delete :index="index" @delete="handleDelete"></board-delete> </board-game>

BoardLibrary.vue

methods: { handleAdd: function (game) { this.games.push(game) }, handleDelete: function (index) { this.games.splice(index, 1) } }, components: { BoardDelete: BoardDelete,

Page 52: Enjoy the vue.js

<template> <tr> <td><span :class="icon"></span></td> <td>{{ name }}</td> <td><slot></slot></td> </tr> </template>

BoardGame.vue

Page 53: Enjoy the vue.js
Page 54: Enjoy the vue.js

<table v-else> <thead> <tr> <board-sort v-model="sortCol" col="type">Type</board-sort> <board-sort v-model="sortCol" col="name">Name</board-sort> <th></th> </tr> </thead> <tbody> <board-game v-for="game in sorted" :type="game.type" :name="game.name"> <board-delete :index="game.index" @delete="handleDelete"></board-delete> </board-game> </tbody> </table>

BoardLibrary.vue

Page 55: Enjoy the vue.js

BoardLibrary.vue data: function() { return { sortCol: 'type', games: [] } }, computed: { sorted: function() { // update each game with its index in the array this.games.forEach(function (value, index) { value.index = index }) return _.sortBy(this.games, [this.sortCol]) }, :

Page 56: Enjoy the vue.js
Page 57: Enjoy the vue.js

! _.sortBy(this.games, [this.sortCol]) ![ { name: 'Codenames', type: 'Card', index: 2 }, { name: 'Snake Oil', type: ‘Card', index: 0 }, { name: 'Star Wars', type: 'Board', index: 1 } ]

games: [ { name: 'Snake Oil', type: 'Card' }, { name: 'Star Wars', type: 'Board' }, { name: 'Codenames', type: 'Card' } ], sortCol: 'name'

sorted()

data

<board-game v-for="game in sorted" ...>

Page 58: Enjoy the vue.js

<button class="button-primary" :disabled="blankName" @click="add">Add</button>

BoardAdd.vue

computed: { blankName: function() { return this.name.trim().length == 0 } }, methods: { add: function () { if (!this.blankName) { this.$emit('add', { name: this.name.trim(), type: this.type }) this.name = '' } } }, mounted: function() { this.$refs.name.focus() }

Page 59: Enjoy the vue.js

BoardAdd.vue} </script> !<style scoped> input, select { width: 100%; } button { margin-top: 2.9rem; } button[disabled] { opacity: 0.5; } button[disabled]:hover { background-color: #33C3F0; border-color: #33C3F0; } </style>

Page 60: Enjoy the vue.js
Page 61: Enjoy the vue.js
Page 62: Enjoy the vue.js
Page 63: Enjoy the vue.js
Page 64: Enjoy the vue.js
Page 65: Enjoy the vue.js

1. It’s Approachable

Page 66: Enjoy the vue.js

Alice Bartlett Origami Components Lead, FT

Page 67: Enjoy the vue.js
Page 68: Enjoy the vue.js

2. Single File Components

Page 69: Enjoy the vue.js

concern

concern

concern

concern

concern

Page 70: Enjoy the vue.js

concern

concern

concern

concern

concern

Page 71: Enjoy the vue.js

3. Incremental Adoptability

Page 72: Enjoy the vue.js

more Library-ish than Framework-esque

Page 73: Enjoy the vue.js

Vue Resource !

Vue Router !

Vuex

AJAXy GET/POSTs !

Single Page App URLs !

State Machine

Page 74: Enjoy the vue.js

4. Plays well with Others

Page 75: Enjoy the vue.js

<script lang="coffee"> module.exports = props: ['options'] methods: sort: (event) -> @$emit ‘change' event.target.value </script> !<style lang="sass"> @import "components"; div.dashboard-sort { margin-right: 1.45em; margin-bottom: 1em; @include select(1.25em); } </style>

Page 76: Enjoy the vue.js

5. Goes with the Grain

Page 77: Enjoy the vue.js

One of Ruby’s friends really makes her crazy. When they try to wrap Christmas presents together Ruby wants to be creative and have many different ways of using the wrapping paper.  !- No, says Django. 

There is one - and only one - obvious way to wrap a present. 

Page 78: Enjoy the vue.js

Gotchas

Page 79: Enjoy the vue.js

google vue events !

use of this. !

array manipulations

Page 80: Enjoy the vue.js

</thead> <transition-group name="board-list" tag="tbody"> <board-game v-for="game in sorted" :type="game.type" :name="game.name" :key="game.id"> <board-delete :id="game.id" @delete="handleDelete"></board-delete> </board-game> </transition-group> </table>

BoardLibrary.vue

methods: { handleAdd: function (game) { game.id = idGenerator++ this.games.push(game) },

Page 81: Enjoy the vue.js

<style> .board-list-move { transition: transform 1s; } .board-list-enter-active, .board-list-leave-active { transition: all 0.5s; } .board-list-enter, .board-list-leave-active { opacity: 0; } .board-list-enter { transform: translateX(960px); } .board-list-leave-active { transform: translateX(-960px); } :

BoardLibrary.vue

Page 82: Enjoy the vue.js
Page 83: Enjoy the vue.js
Page 84: Enjoy the vue.js
Page 85: Enjoy the vue.js
Page 86: Enjoy the vue.js

Thank you

@andywoodme

Page 87: Enjoy the vue.js

CreditsDoge / Minecraft - http://www.yoyowall.com/wallpaper/dog-mountains.html LED Lightbulb - http://edisonlightglobes.com/ Bricksauria T.rex - https://www.flickr.com/photos/115291125@N07/12107675253/ CSS Windows - https://twitter.com/neonick/status/747423962783748096 DJECO - http://www.djeco.com/en !JS Framework Spectrum - The Progressive Framework, Evan You Documentation isn’t Complicated - Can't you make it more like Bootstrap, Alice Bartlett Only one obvious way to wrap a present - Ruby & Django, Linda Liukas !Further Reading !Vue.js - https://vuejs.org Vue Awesome - https://github.com/vuejs/awesome-vue How popular is Vue.js - https://www.quora.com/How-popular-is-VueJS-in-the-industry iBoards code examples - https://github.com/woodcoder/vue-2-list-example

Page 88: Enjoy the vue.js

AMD — RequireJS / client side ! define(['vue'], function (Vue) { …

UMD — two-in-one ! (function (root, factory) { if (typeof define === 'function' && define.amd) { …

ES2015 / ES6 — tree shakeable ! import Vue from ‘vue’ ! export default {...

XKCD 927 — standards