Vue.js
Introduction
Meir Rotstein
www.rotstein.co.il
4.2018
● Created by Evan You - A former Google
employee
● Vue Introduced as “progressive frontend
framework”
● First released on Oct 2015
● Latest release is 2.5.x
Popularity
Vue.js
React
Angular
Let’s dive in
Vue.js is declarative and reactive
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
<div id="app-2">
<span v-bind:title="message">
Hover your mouse over me for a few
seconds
to see my dynamically bound title!
</span>
</div>
var app2 = new Vue({
el: '#app-2',
data: {
message: 'You loaded this page on ' +
new Date().toLocaleString()
}
})
The Vue Instance
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
● Vue Components is a Vue instance
● Root component must declare the el option, which is the css selector of
the HTML element in the a page that will contain the Vue rendered
artifacts
● The Vue constructor get an options object which contains the component
configuration, some of the main configurations:
○ name
○ data
○ props
○ methods
○ computed
○ el
○ template
○ Lifecycle hooks
○ events
○ watch
○ ...
Lifecycle diagram
The Vue Component
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count
}} times.</button>'
})
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
● Components are reusable
Vue instances with a name
● The data option MUST be a
function (otherwise is will
affect ALL the instances of
the component)
● Components are organized in
a tree structure
template and directives
<span>Message: {{ msg }} </span>
<span>Message: {{ message. split('').reverse().join('') }}</span>
<p v-if="seen">Now you see me </p>
<a v-bind:href="url">Click me</a>
<a v-on:click="doSomething">Click me</a>
<form v-on:submit.prevent="onSubmit"></form>
<a :href="url">Click me</a>
<a @click="doSomething">Click me</a>
<a v-mycoolcustomdirective="cooldata">Click me</a>
● Based on the Mustache
syntax
● Common directives:
○ v-if
○ v-for
○ v-show
○ v-once
○ v-html
○ v-bind for data binding
(use : for shorthand)
○ v-on for events (use @
for shorthand)
● You can also implement your
own custom directives
Conditional Rendering
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
<h1 v-show="ok">Hello!</h1>
● Use v-if directive for
conditional rendering
● Use v-else-if and v-else for
if-else logic
● Use v-show directive for
conditional visibility
● v-if will render the element
only if the condition is met,
v-show will render the
element anyway but will
toggle its visibility.
As a thumb rule it is better to
use v-if
Use v-show only for a reason.
e.g. the component state
should be preserved
List Rendering
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
<ul id="v-for-object" class="demo">
<!--{firstName: 'John',lastName: 'Doe',age: 30}-->
<li v-for="value in object">
{{ value }}
</li>
</ul>
<div v-for="item in items" :key="item.id">
<!-- content -->
</div>
<!-- v-if will run for each v-for integration -->
<li v-for="item in items" v-if="item.exists">
<!-- content -->
</div>
● Use v-for directive for list
rendering
● Syntax is:
v-for="item in items"
Where items is the data
array and item is the
element alias
● As Vue uses the “in-place
patch” strategy it is best to
bind the key attribute with
unique key.
This will allow Vue to
optimize the list rendering
when reacting to data
changes
Starting 2.2.0 it is required for
looping over components
v-for and v-if
Bad:
<!-- v-if will run for each v-for integration -->
<li v-for="item in items" v-if="item.exists">
<!-- content -->
</li>
Good:
<ul v-if="items.length">
<li v-for="item in items">
<!-- content -->
</li>
</ul>
● v-for as higher priority than
v-if, meaning the v-if
calculation will take place for
each item on the list
● Optimize it by wrapping the
entire loop with v-if
Events
<div>
<button v-on:click= "counter += 1" >Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
<div>
<!-- `greet` is the name of a method defined in the component -->
<button v-on:click= "greet">Greet</button>
</div>
<div>
<button @click= "say('hi')" >Say hi</button>
<button @click= "say('what')" >Say what</button>
</div>
<input v-on:keyup.enter= "submit">
this.$emit('myEvent')
<my-component v-on:my-event= "doSomething" ></my-component>
● Use v-on directive to listen to
DOM and custom events
● A listener can be both
method or inline handler
● Vue provides Event Modifiers
for handling a specific variant
of event (for instance: keyup
of the Enter key)
● A component may also emit a
custom event using the
this.$emit method - use the
name of the event in camel
case
● You can use @ as a
shorthand for Events
Data distribution: parent to child
Parent:
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' },
]
}
})
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title">
</blog-post>
● A parent component passes
the data to its child
component using props
● A component should declare
its own props
● props declaration has many
useful capabilities such as
type declaration, validators,
default value etc.
Component:
Vue.component('blog-post', {
props: {
title: {
type: String,
required: true,
}
},
template: '<h3>{{ title }}</h3>'
})
Data distribution: child to parent
Parent:
new Vue({
el: '#blog-post-demo',
data: {
posts: [...],
postFontSize: 1
},
methods: {
onEnlargeText: (enlargeAmount) => {
this.postFontSize += enlargeAmount
}
}
})
<div :style="{ fontSize: postFontSize + 'em' }">
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
v-on:enlarge-text="onEnlargeText">
</blog-post>
</div>
● Sometime we would like the child component to pass data to is parent - for this we will use Events
Component:
Vue.component('blog-post', {
props: {
post: {
type: Object,
required: true,
}
},
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<button
v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
<div v-html="post.content"></div>
</div>
`
})
Data distribution: v-model
● v-model is a directive that allows two way data binding for component
● v-model is automatically supported for components that implements the value prop and the input event
Native elements:
<input
v-bind:value="searchText"
v-on:input="searchText =
$event.target.value">
Is the same as:
<input v-model= "searchText" >
Custom elements:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input',
$event.target.value)">
`
})
Usage:
<custom-input v-model="searchText"></custom-input>
Slots
● Slots allows to inject free content into your component (text, html and other components)
Template of <navigation-link> component:
<a
v-bind:href="url"
class="nav-link">
<slot></slot>
</a>
Usage:
<navigation-link url="/profile">
Your Profile
</navigation-link>
<a href="/profile" class="nav-link">
Your Profile
</a>
Usage:
<navigation-link url="/profile">
<!-- Use a component to add an icon -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
<a href="/profile" class="nav-link">
<span class="fs fs-user"></span>
Your Profile
</a>
Named Slots
● Allows a component to have multiple slots
Template of <base-layout>
component:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer">Default
footer</slot>
</footer>
</div>
Usage 1:
<base-layout>
<template slot="header">
<h1>Here might be a page
title</h1>
</template>
<p>A paragraph for the main
content.</p>
<p>And another one.</p>
<template slot="footer">
<p>Here's some contact
info</p>
</template>
</base-layout>
Usage 2:
<base-layout>
<h1 slot="header">Here might
be a page title</h1>
<p>A paragraph for the main
content.</p>
<p>And another one.</p>
<p slot="footer">Here's some
contact info</p>
</base-layout>
Scope of the Slots
As the content of the slot is declared in the parent component - it
inherits the parent scope, for example:
In this example user if declared in the parent component and
navigation-link cannot access it.
But what if you do want to the slot to access the child component
data?
<navigation-link url="/profile" :class="user.class">
Logged in as {{ user.name }}
</navigation-link>
Scoped Slots
● Introduced on v2.1.0
● Scoped Slots allows to define the scope of the slot
Template of <todo-list> component:
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id">
<!-- passing the todo as slot
prop -->
<slot v-bind:todo="todo">
<!-- Fallback content -->
{{ todo.text }}
</slot>
</li>
</ul>
Usage:
<todo-list v-bind:todos="todos">
<!-- Define `slotProps` as the name of our slot scope -->
<template slot-scope="slotProps">
<!-- Define a custom template for todo items, using -->
<!-- `slotProps` to customize each todo. -->
<span v-if="slotProps.todo.isComplete">✓</span>
{{ slotProps.todo.text }}
</template>
</todo-list>
Dynamic Components
● Sometimes, it’s useful to
dynamically switch between
components
● In this example the content is
changes on the selected tabs
● currentTabComponent prop can
hold either the component name
or object
<!-- Component changes when currentTabComponent changes
-->
<component v-bind:is= "currentTabComponent" ></component>
Computed properties
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
● Instead of using complex logic in the
template - use computed props
● they are considered as read only
properties of the component, therefore
you refer it as property, not as a
function ( no () )
● Computed props are cached - it will not
be re-evaluated if no dependency has
changed (as opposed to methods)
● Although computed props are enough
in most of the use cases, Vue offers
also a watch mechanism for handling
special cases.
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = 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('')
}
}
})
Reactivity rules
● Vue listen to changes only for properties
that were defined in the data option -
under the hoods it uses
Object.defineProperty for tracking
changes
● You cannot dynamically add properties to
data - declare empty placeholders for
future usage
● Vue cannot identify deep changes on data
- use Vue.set or re-assign the changes
property
var vm = new Vue({
data: {
// declare message with an empty value
message: ''
},
template: '<div>{{ message }}</div>'
})
vm.message = 'Hello!'
vm.message2 = 'Hello!' // not reactive
this.someObject.b = 2 // not recative
// following are recative
this.$set(this.someObject, 'b', 2) // alias of Vue.set
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2
})
Reactivity rules - cont.
● Reactivity changes are taking place on
the next event loop (tick)
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: () => {
return {
message: 'not updated'
}
},
methods: {
updateMessage: () => {
this.message = 'updated'
console.log(this.$el.textContent) // => 'not updated'
this.$nextTick(() => {
console.log(this.$el.textContent) // => 'updated'
})
}
}
})
Single File Components
● *.vue extension
● All the component assets are on the same
file - no jumping between template/js/css
files
● IDE plugins for syntax highlighting
● As the project got bigger it keeps it more
organized and reduce the amount of files
and layers.
Devtools
● VSCode extension: Vetur
● Chrome extension: vujs-devtools
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en
More info to be found in
https://vuejs.org/

More Related Content

PDF
PDF
A la découverte de vue.js
PDF
Intro to vue.js
PDF
Nuxtjs cheat-sheet
PPTX
An introduction to Vue.js
PPTX
git, 이해부터 활용까지
PDF
nexus helm 설치, docker/helm repo 설정과 예제
ODP
An Introduction to Vuejs
A la découverte de vue.js
Intro to vue.js
Nuxtjs cheat-sheet
An introduction to Vue.js
git, 이해부터 활용까지
nexus helm 설치, docker/helm repo 설정과 예제
An Introduction to Vuejs

What's hot (20)

PDF
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
PDF
Introduction to React JS
PPTX
Apache Maven
PPT
Advanced JavaScript
PPTX
Selenium Interview Questions and Answers | Selenium Tutorial | Selenium Train...
PDF
Provision GCP resources using Terraform @ GDG Craiova
PDF
An introduction to Vue.js
ODP
An Introduction to WebAssembly
PPTX
Express JS
PPTX
Advanced JavaScript
PDF
Workshop 4: NodeJS. Express Framework & MongoDB.
PPT
Angular 8
PPTX
Node js Introduction
PDF
From DevOps to GitOps with GitLab
PPTX
What's new in Java 11
PPTX
Dependency injection - the right way
PPT
Spring Boot in Action
PPTX
CI-CD WITH GITLAB WORKFLOW
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Introduction to React JS
Apache Maven
Advanced JavaScript
Selenium Interview Questions and Answers | Selenium Tutorial | Selenium Train...
Provision GCP resources using Terraform @ GDG Craiova
An introduction to Vue.js
An Introduction to WebAssembly
Express JS
Advanced JavaScript
Workshop 4: NodeJS. Express Framework & MongoDB.
Angular 8
Node js Introduction
From DevOps to GitOps with GitLab
What's new in Java 11
Dependency injection - the right way
Spring Boot in Action
CI-CD WITH GITLAB WORKFLOW
Ad

Similar to Introduction to Vue.js (20)

ODP
Basics of VueJS
PDF
Vue.js for beginners
PDF
The Point of Vue - Intro to Vue.js
PDF
Learning Vue Directives.pdf
PDF
Love at first Vue
PDF
Vue fundamentasl with Testing and Vuex
PPTX
An introduction to Vue.js
PDF
Quasar Framework Introduction for C++ develpoers
PDF
Vue js 2.x
PDF
Meet VueJs
PDF
VueJS: The Simple Revolution
PPTX
Level up apps and websites with vue.js
PPTX
Level up apps and websites with vue.js
PDF
Vue.js - An Introduction
PPTX
Don't Over-React - just use Vue!
PDF
Vue.js
PDF
Using Renderless Components in Vue.js during your software development.
PPTX
Introduction to web application development with Vue (for absolute beginners)...
PDF
Vue.js 101
PPTX
Basics of Vue.js 2019
Basics of VueJS
Vue.js for beginners
The Point of Vue - Intro to Vue.js
Learning Vue Directives.pdf
Love at first Vue
Vue fundamentasl with Testing and Vuex
An introduction to Vue.js
Quasar Framework Introduction for C++ develpoers
Vue js 2.x
Meet VueJs
VueJS: The Simple Revolution
Level up apps and websites with vue.js
Level up apps and websites with vue.js
Vue.js - An Introduction
Don't Over-React - just use Vue!
Vue.js
Using Renderless Components in Vue.js during your software development.
Introduction to web application development with Vue (for absolute beginners)...
Vue.js 101
Basics of Vue.js 2019
Ad

Recently uploaded (20)

PPTX
StacksandQueuesCLASS 12 COMPUTER SCIENCE.pptx
PDF
solman-7.0-ehp1-sp21-incident-management
PDF
Coding with GPT-5- What’s New in GPT 5 That Benefits Developers.pdf
PDF
Ragic Data Security Overview: Certifications, Compliance, and Network Safegua...
PPTX
ESDS_SAP Application Cloud Offerings.pptx
PDF
IT Consulting Services to Secure Future Growth
PPTX
Human-Computer Interaction for Lecture 2
PDF
Crypto Loss And Recovery Guide By Expert Recovery Agency.
PPTX
UNIT II: Software design, software .pptx
PPTX
Independent Consultants’ Biggest Challenges in ERP Projects – and How Apagen ...
PDF
Odoo Construction Management System by CandidRoot
PDF
Building an Inclusive Web Accessibility Made Simple with Accessibility Analyzer
PPTX
AI Tools Revolutionizing Software Development Workflows
PPTX
WJQSJXNAZJVCVSAXJHBZKSJXKJKXJSBHJBJEHHJB
PDF
Mobile App Backend Development with WordPress REST API: The Complete eBook
PPTX
DevOpsDays Halifax 2025 - Building 10x Organizations Using Modern Productivit...
PPTX
HackYourBrain__UtrechtJUG__11092025.pptx
PPTX
Presentation - Summer Internship at Samatrix.io_template_2.pptx
PPTX
Comprehensive Guide to Digital Image Processing Concepts and Applications
PPTX
Chapter_05_System Modeling for software engineering
StacksandQueuesCLASS 12 COMPUTER SCIENCE.pptx
solman-7.0-ehp1-sp21-incident-management
Coding with GPT-5- What’s New in GPT 5 That Benefits Developers.pdf
Ragic Data Security Overview: Certifications, Compliance, and Network Safegua...
ESDS_SAP Application Cloud Offerings.pptx
IT Consulting Services to Secure Future Growth
Human-Computer Interaction for Lecture 2
Crypto Loss And Recovery Guide By Expert Recovery Agency.
UNIT II: Software design, software .pptx
Independent Consultants’ Biggest Challenges in ERP Projects – and How Apagen ...
Odoo Construction Management System by CandidRoot
Building an Inclusive Web Accessibility Made Simple with Accessibility Analyzer
AI Tools Revolutionizing Software Development Workflows
WJQSJXNAZJVCVSAXJHBZKSJXKJKXJSBHJBJEHHJB
Mobile App Backend Development with WordPress REST API: The Complete eBook
DevOpsDays Halifax 2025 - Building 10x Organizations Using Modern Productivit...
HackYourBrain__UtrechtJUG__11092025.pptx
Presentation - Summer Internship at Samatrix.io_template_2.pptx
Comprehensive Guide to Digital Image Processing Concepts and Applications
Chapter_05_System Modeling for software engineering

Introduction to Vue.js

  • 2. ● Created by Evan You - A former Google employee ● Vue Introduced as “progressive frontend framework” ● First released on Oct 2015 ● Latest release is 2.5.x
  • 5. Vue.js is declarative and reactive <div id="app"> {{ message }} </div> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) <div id="app-2"> <span v-bind:title="message"> Hover your mouse over me for a few seconds to see my dynamically bound title! </span> </div> var app2 = new Vue({ el: '#app-2', data: { message: 'You loaded this page on ' + new Date().toLocaleString() } })
  • 6. The Vue Instance <div id="app"> {{ message }} </div> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) ● Vue Components is a Vue instance ● Root component must declare the el option, which is the css selector of the HTML element in the a page that will contain the Vue rendered artifacts ● The Vue constructor get an options object which contains the component configuration, some of the main configurations: ○ name ○ data ○ props ○ methods ○ computed ○ el ○ template ○ Lifecycle hooks ○ events ○ watch ○ ...
  • 8. The Vue Component Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) <div id="components-demo"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div> ● Components are reusable Vue instances with a name ● The data option MUST be a function (otherwise is will affect ALL the instances of the component) ● Components are organized in a tree structure
  • 9. template and directives <span>Message: {{ msg }} </span> <span>Message: {{ message. split('').reverse().join('') }}</span> <p v-if="seen">Now you see me </p> <a v-bind:href="url">Click me</a> <a v-on:click="doSomething">Click me</a> <form v-on:submit.prevent="onSubmit"></form> <a :href="url">Click me</a> <a @click="doSomething">Click me</a> <a v-mycoolcustomdirective="cooldata">Click me</a> ● Based on the Mustache syntax ● Common directives: ○ v-if ○ v-for ○ v-show ○ v-once ○ v-html ○ v-bind for data binding (use : for shorthand) ○ v-on for events (use @ for shorthand) ● You can also implement your own custom directives
  • 10. Conditional Rendering <div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div> <h1 v-show="ok">Hello!</h1> ● Use v-if directive for conditional rendering ● Use v-else-if and v-else for if-else logic ● Use v-show directive for conditional visibility ● v-if will render the element only if the condition is met, v-show will render the element anyway but will toggle its visibility. As a thumb rule it is better to use v-if Use v-show only for a reason. e.g. the component state should be preserved
  • 11. List Rendering <ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul> <div v-for="(value, key, index) in object"> {{ index }}. {{ key }}: {{ value }} </div> <ul id="v-for-object" class="demo"> <!--{firstName: 'John',lastName: 'Doe',age: 30}--> <li v-for="value in object"> {{ value }} </li> </ul> <div v-for="item in items" :key="item.id"> <!-- content --> </div> <!-- v-if will run for each v-for integration --> <li v-for="item in items" v-if="item.exists"> <!-- content --> </div> ● Use v-for directive for list rendering ● Syntax is: v-for="item in items" Where items is the data array and item is the element alias ● As Vue uses the “in-place patch” strategy it is best to bind the key attribute with unique key. This will allow Vue to optimize the list rendering when reacting to data changes Starting 2.2.0 it is required for looping over components
  • 12. v-for and v-if Bad: <!-- v-if will run for each v-for integration --> <li v-for="item in items" v-if="item.exists"> <!-- content --> </li> Good: <ul v-if="items.length"> <li v-for="item in items"> <!-- content --> </li> </ul> ● v-for as higher priority than v-if, meaning the v-if calculation will take place for each item on the list ● Optimize it by wrapping the entire loop with v-if
  • 13. Events <div> <button v-on:click= "counter += 1" >Add 1</button> <p>The button above has been clicked {{ counter }} times.</p> </div> <div> <!-- `greet` is the name of a method defined in the component --> <button v-on:click= "greet">Greet</button> </div> <div> <button @click= "say('hi')" >Say hi</button> <button @click= "say('what')" >Say what</button> </div> <input v-on:keyup.enter= "submit"> this.$emit('myEvent') <my-component v-on:my-event= "doSomething" ></my-component> ● Use v-on directive to listen to DOM and custom events ● A listener can be both method or inline handler ● Vue provides Event Modifiers for handling a specific variant of event (for instance: keyup of the Enter key) ● A component may also emit a custom event using the this.$emit method - use the name of the event in camel case ● You can use @ as a shorthand for Events
  • 14. Data distribution: parent to child Parent: new Vue({ el: '#blog-post-demo', data: { posts: [ { id: 1, title: 'My journey with Vue' }, { id: 2, title: 'Blogging with Vue' }, { id: 3, title: 'Why Vue is so fun' }, ] } }) <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title"> </blog-post> ● A parent component passes the data to its child component using props ● A component should declare its own props ● props declaration has many useful capabilities such as type declaration, validators, default value etc. Component: Vue.component('blog-post', { props: { title: { type: String, required: true, } }, template: '<h3>{{ title }}</h3>' })
  • 15. Data distribution: child to parent Parent: new Vue({ el: '#blog-post-demo', data: { posts: [...], postFontSize: 1 }, methods: { onEnlargeText: (enlargeAmount) => { this.postFontSize += enlargeAmount } } }) <div :style="{ fontSize: postFontSize + 'em' }"> <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="onEnlargeText"> </blog-post> </div> ● Sometime we would like the child component to pass data to is parent - for this we will use Events Component: Vue.component('blog-post', { props: { post: { type: Object, required: true, } }, template: ` <div class="blog-post"> <h3>{{ post.title }}</h3> <button v-on:click="$emit('enlarge-text', 0.1)"> Enlarge text </button> <div v-html="post.content"></div> </div> ` })
  • 16. Data distribution: v-model ● v-model is a directive that allows two way data binding for component ● v-model is automatically supported for components that implements the value prop and the input event Native elements: <input v-bind:value="searchText" v-on:input="searchText = $event.target.value"> Is the same as: <input v-model= "searchText" > Custom elements: Vue.component('custom-input', { props: ['value'], template: ` <input v-bind:value="value" v-on:input="$emit('input', $event.target.value)"> ` }) Usage: <custom-input v-model="searchText"></custom-input>
  • 17. Slots ● Slots allows to inject free content into your component (text, html and other components) Template of <navigation-link> component: <a v-bind:href="url" class="nav-link"> <slot></slot> </a> Usage: <navigation-link url="/profile"> Your Profile </navigation-link> <a href="/profile" class="nav-link"> Your Profile </a> Usage: <navigation-link url="/profile"> <!-- Use a component to add an icon --> <font-awesome-icon name="user"></font-awesome-icon> Your Profile </navigation-link> <a href="/profile" class="nav-link"> <span class="fs fs-user"></span> Your Profile </a>
  • 18. Named Slots ● Allows a component to have multiple slots Template of <base-layout> component: <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer">Default footer</slot> </footer> </div> Usage 1: <base-layout> <template slot="header"> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template slot="footer"> <p>Here's some contact info</p> </template> </base-layout> Usage 2: <base-layout> <h1 slot="header">Here might be a page title</h1> <p>A paragraph for the main content.</p> <p>And another one.</p> <p slot="footer">Here's some contact info</p> </base-layout>
  • 19. Scope of the Slots As the content of the slot is declared in the parent component - it inherits the parent scope, for example: In this example user if declared in the parent component and navigation-link cannot access it. But what if you do want to the slot to access the child component data? <navigation-link url="/profile" :class="user.class"> Logged in as {{ user.name }} </navigation-link>
  • 20. Scoped Slots ● Introduced on v2.1.0 ● Scoped Slots allows to define the scope of the slot Template of <todo-list> component: <ul> <li v-for="todo in todos" v-bind:key="todo.id"> <!-- passing the todo as slot prop --> <slot v-bind:todo="todo"> <!-- Fallback content --> {{ todo.text }} </slot> </li> </ul> Usage: <todo-list v-bind:todos="todos"> <!-- Define `slotProps` as the name of our slot scope --> <template slot-scope="slotProps"> <!-- Define a custom template for todo items, using --> <!-- `slotProps` to customize each todo. --> <span v-if="slotProps.todo.isComplete">✓</span> {{ slotProps.todo.text }} </template> </todo-list>
  • 21. Dynamic Components ● Sometimes, it’s useful to dynamically switch between components ● In this example the content is changes on the selected tabs ● currentTabComponent prop can hold either the component name or object <!-- Component changes when currentTabComponent changes --> <component v-bind:is= "currentTabComponent" ></component>
  • 22. Computed properties <div id="example"> {{ message.split('').reverse().join('') }} </div> ● Instead of using complex logic in the template - use computed props ● they are considered as read only properties of the component, therefore you refer it as property, not as a function ( no () ) ● Computed props are cached - it will not be re-evaluated if no dependency has changed (as opposed to methods) ● Although computed props are enough in most of the use cases, Vue offers also a watch mechanism for handling special cases. <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> var vm = 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('') } } })
  • 23. Reactivity rules ● Vue listen to changes only for properties that were defined in the data option - under the hoods it uses Object.defineProperty for tracking changes ● You cannot dynamically add properties to data - declare empty placeholders for future usage ● Vue cannot identify deep changes on data - use Vue.set or re-assign the changes property var vm = new Vue({ data: { // declare message with an empty value message: '' }, template: '<div>{{ message }}</div>' }) vm.message = 'Hello!' vm.message2 = 'Hello!' // not reactive this.someObject.b = 2 // not recative // following are recative this.$set(this.someObject, 'b', 2) // alias of Vue.set this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
  • 24. Reactivity rules - cont. ● Reactivity changes are taking place on the next event loop (tick) Vue.component('example', { template: '<span>{{ message }}</span>', data: () => { return { message: 'not updated' } }, methods: { updateMessage: () => { this.message = 'updated' console.log(this.$el.textContent) // => 'not updated' this.$nextTick(() => { console.log(this.$el.textContent) // => 'updated' }) } } })
  • 25. Single File Components ● *.vue extension ● All the component assets are on the same file - no jumping between template/js/css files ● IDE plugins for syntax highlighting ● As the project got bigger it keeps it more organized and reduce the amount of files and layers.
  • 26. Devtools ● VSCode extension: Vetur ● Chrome extension: vujs-devtools https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en
  • 27. More info to be found in https://vuejs.org/