enjoy the vue.js

Post on 07-Jan-2017

227 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Enjoy the Vue.js

@andywoodme

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

<!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>

Vue.js can do this*

Vue.js 2.0

Progressive Web Framework by Evan You

Less More

React Vue Angular Ember MeteorTemplating!Engines

Backbone

<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

DOM (Page)

Data (State)

Reactive

<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

<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' }

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

</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: [] }

<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 } }

</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 }) } }

<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({

<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

<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

<!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>

Components

<!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

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

main.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

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

CommonJS

Node / Server Side

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

Components

Component

Sub-components

Properties

:data="value"

props: ['data']

<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>

<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

<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

Events

props: ['data']

@event="handler"

this.$emit('event')

:data="value"

<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

<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

<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

<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,

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

BoardGame.vue

<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

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]) }, :

! _.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" ...>

<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() }

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>

1. It’s Approachable

Alice Bartlett Origami Components Lead, FT

2. Single File Components

concern

concern

concern

concern

concern

concern

concern

concern

concern

concern

3. Incremental Adoptability

more Library-ish than Framework-esque

Vue Resource !

Vue Router !

Vuex

AJAXy GET/POSTs !

Single Page App URLs !

State Machine

4. Plays well with Others

<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>

5. Goes with the Grain

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. 

Gotchas

google vue events !

use of this. !

array manipulations

</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) },

<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

Thank you

@andywoodme

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

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

top related