NAZAR ILKIV <NIlkiv@luxoft.com>
Javascript developer
April 12, 2017
Hello Vue.js!
Framework Overview




JS frameworks popularity trends

Vue.js is MVVM framework that is very easy to start and also a powerful tool for building UI

Quickstart
<!DOCTYPE html>
<html>
<head>
<title>Quickstart with Vue.js</title>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello World!'
}
});
</script>
<body>
</html>Template Syntax
- Text interpolation
- Attribute binging
- Built-in directives
<div>Message: {{ message }}</div><div v-html="message"></div><a v-bind:href="linkHref">Dynamic link</a><button v-bind:disabled="someDynamicCondition">Button</button><div v-if="isShown">This content is shown</div><ul>
<li v-for="fruit of fruits" :key="item.id">{{ fruit }}</li>
<ul><!-- shorthand -->
<a :href="url">Some link</a>Class and Style Bindings
<div v-bind:class="{ active: isActive }"></div><!-- Vue accepts array, object, expression and even function -->
<div id="app">
<div v-bind:class="classObject"></div>
</div>const app = new Vue({
el: '#app',
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
});<!-- Inline style bindings -->
<div v-bind:style="styleObject"></div>data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}Event handling
<div id="example">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>const app = new Vue({
el: '#example',
methods: {
say: function (message) {
alert(message)
}
}
});// or pass original DOM event
const app = new Vue({
el: '#example',
methods: {
say: function (message, event) {
event.preventDefault();
alert(message);
}
}
});Event modifiers
<!-- the click event's propagation will be stopped -->
<a v-on:click.stop="doThis"></a>
<!-- the submit event will no longer reload the page -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- modifiers can be chained -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- just the modifier -->
<form v-on:submit.prevent></form>
<!-- use capture mode when adding the event listener -->
<!-- i.e. an event targeting an inner element -->
<!-- is handled here before being handled by that element -->
<div v-on:click.capture="doThis">...</div>
<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div v-on:click.self="doThat">...</div>
<!-- the click event will be triggered at most once -->
<a v-on:click.once="doThis"></a>Key modifiers
<!-- submit() method when hit Enter key -->
<input v-on:keyup.enter="submit"><!-- or use keycode -->
<input v-on:keyup.13="submit"><!-- even mouse button modifiers -->
<div v-on:click.right="customTaskMenu"></div>Form Input Bindings
<!-- Text -->
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p><!-- Multiple checkboxes, bound to the same Array -->
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
new Vue({
el: '...',
data: {
checkedNames: []
}
})Components
// register globally
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
// create a root instance
new Vue({
el: '#example'
})<div id="example">
<my-component></my-component>
</div>// register locally
new Vue({
el: '#example',
components: {
// <my-component> will only be available in parent's template
'my-component': {
template: '<div>A custom component!</div>'
}
}
})<div id="example">
<my-component></my-component>
</div>
<div id="example2">
<!-- not available here -->
<my-component></my-component>
</div>Component props
Vue.component('someComp', {
props: ['text'],
template: '<span>{{ message }}</span>'
})<some-comp message="hello!"></some-comp>
<!-- will render -->
<span>hello!</span>Every component instance has its own isolated scope.
Data can be passed down to child components using props.
Only one way data flow. Never mutate prop inside child component
Vue.component('example', {
props: {
// basic type check (`null` means accept any type)
propA: Number,
// multiple possible types
propB: [String, Number],
// a required string
propC: {
type: String,
required: true
},
// a number with default value
propD: {
type: Number,
default: 100
},
// object/array defaults should be returned from a
// factory function
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// custom validator function
propF: {
validator: function (value) {
return value > 10
}
}
}
})Prop validation
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>Component communication
Vue.component('button-counter', {
template: '<button v-on:click="increment">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
increment: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})Directives
Built-in
- v-for
- v-model
- v-show
- etc.
Custom
// Register a global custom directive
Vue.directive('focus', {
// When the bound element
// is inserted into the DOM...
inserted: function (el) {
// Focus the element
el.focus()
}
})// Register a local custom directive
const app = new Vue({
el: '#app',
data: {
someData: 'hello'
},
directives: {
focus: {
// directive definition
}
}
});Directive hook functions
- bind: called only once, when the directive is first bound to the element. This is where you can do one-time setup work.
- inserted: called when the bound element has been inserted into its parent node (this only guarantees parent node presence, not necessarily in-document).
- update: called after the containing component has updated, but possibly before its children have updated.
- componentUpdated: called after the containing component and its children have updated.
- unbind: called only once, when the directive is unbound from the element.
Computed Properties
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>const app = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
});Watchers
<div id="watch-example">
<p>
Ask some question:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</div>const app = new Vue({
el: '#watch-example',
data: {
question: '',
answer: ''
},
watch: {
// whenever question changes, this function will run
question: function (newQuestion) {
this.answer = `Answer to question: ${this.question}`
}
}
});Vue instance lifecycle
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
How to put things together

Single File Component
<template>
<p>{{ greeting }} World!</p>
</template>
<script>
export default {
data: function() {
return {greeting: 'Hello'}
}
}
</script>
<style>
p { font-size: 2em; }
</style>Hello.vue file
What about scaling?
- Vue-router: https://github.com/vuejs/vue-router
- Vuex: https://github.com/vuejs/vuex
- Redux: https://github.com/revue/revue
Tools for building SPAs:
Additional tools:
- JSX support: https://github.com/vuejs/babel-plugin-transform-vue-jsx
- TypeScript support: https://github.com/vuejs/vue/tree/dev/types
LINKS
https://vuejs.org/v2/guide/
https://github.com/vuejs/vue
Q&A Time
Nazar Ilkiv <NIlkiv@luxoft.com>
Javascript developer
April 12, 2017
Hello Vue.js!
Framework overview
Hello Vue.js
By Nazar Ilkiv
Hello Vue.js
- 970