(last pun, I promise!)
@chrisvfritz (slack.lansing.codes)
@chrisvfritz
@chrisvfritz
HTML
CSS
JS
TodoList
HTML
CSS
JS
Todo
HTML
CSS
JS
Button
HTML
CSS
JS
...but which component system?
"My biggest frustration is the constant migration from tool to tool or framework to framework. Never any time to master one before something better comes along."
<div id="app">
<input v-model="greeting">
<p>{{ greeting }} World</p>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
new Vue({
el: '#app',
data: {
greeting: 'Hello'
}
})
</script>
Hello world!
Angular
<script src="https://unpkg.com/angular/angular.js"></script>
<script>
angular.module('HelloWorldApp', [])
.controller('HelloWorldController', function ($scope) {
$scope.greeting = 'Hello'
})
</script>
<div ng-app="HelloWorldApp">
<div ng-controller="HelloWorldController">
<input ng-model="greeting">
<p>{{ greeting }} world</p>
</div>
</div>
and with Angular 1...
<div id="app">
<input v-model="newTodoText" @keydown.enter="addTodo">
<ul>
<li v-for="(todo, index) in todos">
{{ todo.text }}
<button @click="removeTodo(index)">X</button>
</li>
</ul>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
new Vue({
el: '#app',
data: {
newTodoText: '',
todos: []
},
methods: {
addTodo: function () {
this.todos.push({ text: this.newTodoText })
this.newTodoText = ''
},
removeTodo: function (index) {
this.todos.splice(index, 1)
}
}
})
</script>
Simple todo app
Angular
<script src="https://unpkg.com/angular/angular.js"></script>
<script>
angular.module('TodoApp', [])
.controller('TodoController', function ($scope) {
$scope.newTodoText = ''
$scope.todos = []
$scope.addTodo = function () {
$scope.todos.push({ text: $scope.newTodoText })
$scope.newTodoText = ''
}
$scope.removeTodo = function (index) {
$scope.todos.splice(index, 1)
}
})
</script>
<div ng-app="TodoApp">
<div ng-controller="TodoController">
<input ng-model="newTodoText" ng-keydown="$event.which === 13 && addTodo()">
<ul>
<li ng-repeat="todo in todos">
{{ todo.text }}
<button ng-click="removeTodo($index)">X</button>
</li>
</ul>
</div>
</div>
and with Angular 1...
<div id="app">
It will have been 2 minutes since I loaded this page in
<auto-counter
:initial-value="120"
:increment-by="-1"
:stop-at="0"
></auto-counter>
seconds.
</div>
<script src="https://unpkg.com/vue"></script>
<script>
Vue.component('auto-counter', {
template: '<span>{{ number }}</span>',
props: {
initialValue: {
type: Number,
default: 0
},
incrementBy: {
type: Number,
default: 1
},
interval: {
type: Number,
default: 1000
},
stopAt: {
type: Number
}
},
data: function () {
return {
number: this.initialValue
}
},
created: function () {
var vm = this
vm.counter = setInterval(function () {
vm.number += vm.incrementBy
if (this.stopAt === vm.number) {
clearInterval(vm.counter)
}
}, vm.interval)
},
beforeDestroy: function () {
clearInterval(this.counter)
}
})
new Vue({ el: '#app' })
</script>
Reusable components
Angular
<script src="https://unpkg.com/angular/angular.js"></script>
<script>
angular.module('App', [])
.component('autoCounter', {
template: '<span>{{ $ctrl.number }}</span>',
controller: function ($scope) {
var vm = this
vm.$onInit = function () {
vm.number = vm.initialValue || 0
vm.incrementBy = vm.incrementBy || 1
vm.interval = vm.interval || 1000
vm.counter = setInterval(function () {
$scope.$apply(function () {
vm.number += vm.incrementBy
if (vm.stopAt === vm.number) {
clearInterval(vm.counter)
}
})
}, vm.interval)
}
vm.$onDestroy = function () {
clearInterval(vm.counter)
}
},
bindings: {
initialValue: '<',
incrementBy: '<',
interval: '<',
stopAt: '<'
}
})
</script>
<div ng-app="App">
It will have been 2 minutes since I loaded this page in
<auto-counter
initial-value="120"
increment-by="-1"
stop-at="0"
></auto-counter>
seconds.
</div>
and with Angular 1...
Build on web standards, don't reinvent them
<template>
<button :class="'btn btn-' + kind">
<slot></slot>
</button>
</template>
<script>
export default {
props: {
kind: {
validator (value) {
return ['primary', 'warning'].indexOf(value) !== -1
},
required: true
}
}
}
</script>
<style lang="scss" scoped>
$text-color: #fff;
$primary-bg-color: #0074d9;
$warning-bg-color: #d5a13c;
.btn {
color: $text-color;
&.btn-primary {
background: $primary-bg-color;
&:hover {
background: lighten($primary-bg-color, 20%);
}
}
&.btn-warning {
background: $warning-bg-color;
&:hover {
background: lighten($warning-bg-color, 20%);
}
}
}
</style>
<template>
<textarea :value="markdown" @input="updateMarkdown"></textarea>
<div v-html="preview"/>
</template>
<script>
import debounce from 'lodash/debounce'
import compileMarkdown from 'marked'
export default {
el: '#editor',
data: {
markdown: '# hello'
},
computed: {
preview: function () {
return compileMarkdown(this.markdown)
}
},
methods: {
updateMarkdown: debounce(function (event) {
this.markdown = event.target.value
}, 300)
}
})
</script>
Markdown Editor
Visualization with D3
I need to create a page that displays the latest activity from the users, so I just need to get the data from the REST endpoint and display it in some sort of filterable table, and update it if anything changes in the server.
REST
In-browser devtools
With time travel!
Hot module reloading
Is anyone actually using it in production?
Official support for practically required libs (like for routing and state management)
github.com/vuejs/vue-router
github.com/vuejs/vuex
github.com/vuejs/vue-cli
github.com/vuejs/vue-rx
...
Ajax
Routing
Flux State
CLI Generator
Devtools
Observables
...
@chrisvfritz (slack.lansing.codes)
@chrisvfritz
@chrisvfritz
slides.com/chrisfritz/vue-mmcfug