Vuejs Essentials

Download as pdf or txt
Download as pdf or txt
You are on page 1of 65

TWEB

Vue.js essentials

Paul Nta

1 . 1
📝 Plan 1. Vue minimal setup
2. List rendering
3. Conditional rendering
4. Events
5. Computed properties
6. Classes & Styles binding
7. Components
8. Single file components
9. Routing
10. State managment

1 . 2
🎯 Goals
A quick tour of the most
important Vue.js features

Explore common patterns

Use a real world for


illustration

Vue.js has one of the best


documentation out there. This
course is not meant to replace it
👉 https://vuejs.org
1 . 3
Imagine
Let's build this app

2 . 1
Why
Choosing
Vue.js?
Declarative rendering
Components
State management
Client side routing

2 . 2
1. Vue minimal
setup

3 . 1
Minimal setup

Add the following script tag in your HTML document to


This will load Vue and make it available as global variable

<!-- development version, includes helpful console warnings -->


<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

or

<!-- production version, optimized for size and speed -->


<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

3 . 2
Minimal setup

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>Music app</title>
7 </head>
8 <body>
9 <div id="app">
10 <h1>{{ title }}</h1>
11 </div>
12 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
13 <script>
14 const app = new Vue({
15 el: "#app",
16 data: {
17 title: "Hello world"
18 }
19 });
20 </script>
21 </body>
22 </html>

3 . 3
The Vue instance

var vm = new Vue({


// options
})

The vue is instance is the root of an application


It takes an object as parameter for options (store
data, define behaviours)

browse the full list of options in the API reference.

3 . 4
Subtitle

The Vue instance

<div id="app">
<!-- This part of the DOM is now controlled by Vue -->
</div>

<script>
var vm = new Vue({
el: '#app'
})
</script>

To connect the view instance to a part of the DOM, we use


the el option
You can use Vue template syntax directly in the DOM (in-DOM template)

3 . 5
Data binding

<div id="app">
<h1>{{ message }}</h1>
</div>

<script>
const vm = new Vue({
el: '#app',
data: {
message: 'Hello world',
}
})
</script>

The Vue instance can store informations in the data


attribute which can be accessible in the template
3 . 6
Data binding

<div id="app">
<h1>{{ message }}</h1> All the properties found in
</div>
the data object are reactive

<script>
const vm = new Vue({
When the values of those
el: '#app', properties change, the view
data: {
message: 'Hello world',
will “react”, updating to
} match the new values.
})

// Updates the view


vm.message = 'Hello paul'
</script>

3 . 7
Data binding

Text interpolation using the “Mustache” syntax 

<h1>{{ message }}</h1>

<h1>Message is: {{ message }}</h1>

You can use any JS expressions

<h1>{{ message.split('').reverse().join('') }}</h1>

3 . 8
Attribute binding

You can bind attributes to an expression using v-bind directives.


Directives are special attributes starting with a v- prefix

<h1 v-bind:id="titleId"></h1>
Shortand
<h1 :id="`title-${count}`"></h1>

<button :disabled="isButtonDisabled"></button>

<h1 :id="`title-${count}`"></h1>

3 . 9
Vue.js essentials

2. List
rendering

tracks

4 . 1
List rendering

1 <div
2 v-for="track in tracks"
3 v-bind:key="track.id"
4 />
5 {{ track.title }}
6 </div>
7

1 const vm = new Vue({


2 el: "#app",
3 data: {
4 title: "Your favorite hits",
5 tracks: [
6 { id: 1, title: 'Axel F' },
7 { id: 2, title: 'Despacito' },
8 { id: 3, title: 'Gangnam Style' },
9 // ...
10 ]
11 }
12 });

4 . 2
List rendering

<div v-for="item in array" />

<div v-for="(item, index) in array.slice(0, 3)" />

<div v-for="(value, key) in object" />

The key attribute

<div v-for="item in array" v-bind:key="item.id"/>

Vue uses the key attribute to know the relationship between


your data and the DOM elements. When the data changes, Vue
knows which elements to update or remove 
4 . 3
Vue.js essentials

3. Conditional
rendering

e.g. Errors and


loading states

5 . 1
Lifecycle hooks

The created hook can be used


const vm = new Vue({
el: "#app", to run code after an instance is
data: { created
loading: false,
error: null, Use this to access the current
tracks: [], vue instance
},
created() {
this.loading = true;
fetchTracks()
.then(tracks => {
this.tracks = tracks;
this.loading = false; Their are other lifecycle hooks
})
.catch(err => { (e.g., mounted destroyed) 
this.error = err;
this.loading = false; Don't use arrow functions
});
},
});
Don't initialize state with
undefined
5 . 2
Conditionnal rendering

<div v-if="error">
Sorry it's broken
</div>
<div v-else-if="loading">
Wait....
</div>
<template v-else>
<div>{{ playlist.title }}</div>
<div v-for="track in tracks" v-bind:key="track.id">
{{ track.title }}
</div>
</div>

Use v-if directive to conditionally render a block


Optionally, can be chained with a v-else block or multiple v-else-if blocks
Use a template element to group multiple blocks
Don't use v-if on v-for elements. 
5 . 3
Conditionnal rendering

<div v-show="false"> <div style="display: none;">


You cannot see this You cannot see this
</div> </div>

An element with v-show will always be rendered and remain in the DOM

5 . 4
Vue.js essentials

4. Events

select track

6 . 1
Events

1 <div
2 v-for="track in tracks"
3 v-bind:key="track.id"
4 />
5 <button v-on:click="selectTrack(track)">
6 Play
7 </button>
8 <span>{{ track.title }}</span>
9 </div>

new Vue({
el: '#app',
data: {
tracks: [/*...*/],
currentTrack: null
},
methods: {
selectTrack(track) {
this.currentTrack = track;
}
}
});

6 . 2
Events
Use v-on directive to listen to DOM events and run some JavaScript
when they’re triggered

<button v-on:click="currentTrack = track">...


Shortand
<button @click="currentTrack = track">...

Calls selectTrack method


<button @click="selectTrack">...

Arguments can be passed


<button @click="selectTrack(track)">...

6 . 3
Events modifiers

use prevent modifier to automatically call event.preventDefault(), thus


preventing the page to reload
<form v-on:submit.prevent="submit"></form>

use enter event key modifier to only listen to a ENTER key press
<input v-on:keyup.enter="submit">

Other modifiers are available, see:


https://vuejs.org/v2/guide/events.html#Event-Modifiers

6 . 4
Form Input Bindings
It's common to implement two-way data bindings on form elements
such as input. The idea is to treat Vue instance data as the single source
of truth

1 <div id="app">
2 <input
3 type="text"
4 v-bind:value="searchText"
5 v-on:input="searchText = $event.target.value"
6 >
7 </div>

<script>
new Vue({
el: '#app',
data: {
searchText: ''
}
})
</script>

6 . 5
Form Input Bindings

You can use the v-model directive to create two-way data bindings on
form input, textarea, and select elements

<div id="app">
<input
type="text"
v-model="searchText"
>
</div>

This is essentially syntax sugar for updating data on user input events.
Under the hood, v-model implements  v-bind:value and v-on:input

6 . 6
Vue.js essentials

5. Computed
properties

total duration

7 . 1
Methods

<div>{{ getDuration() }} seconds</div>

// ...
methods: {
getDuration() {
return this.tracks.reduce((acc, track) => acc + track.duration, 0)
}
}

You can call methods in expressions


getDuration() will re-evaluate for each render

7 . 2
Computed properties

<div>{{ duration }} seconds</div>

//...
computed: {
duration() {
return this.tracks.reduce((acc, track) => acc + track.duration, 0)
}
}

A computed property will only re-evaluate when some of its reactive


dependencies have changed.
As long as this.tracks has not changed, multiple access to the duration
computed property will immediately return the previously computed
result without having to run the function again.

7 . 3
Vue.js essentials

6. Classes
& Styles
binding

playing
track

8 . 1
Classes & styles binding

<div
v-for="track in tracks"
:key="track.id"
:class="{ isPlaying: track === currentTrack }"
/>
<button @click="currentTrack = track">Play</button>
...
</div>

Vue provides special enhancements when v-bind is used with class and
style attributes
In addition to strings, the expressions can also evaluate to objects or
arrays

8 . 2
Classes & styles binding

Use static classes just like in regular HTML


<div class="font-bold text-sm">...

Supports arrays and objects with v-bind


<div v-bind:class="['font-bold', 'text-sm']">...

<div v-bind:class="{ active: isActive }">...

<div v-bind:class="['font-bold', 'text-sm', { active: isActive }]">...

Inline styles as string like in regular HTML


<div style="font-weight: bold; font-size: small;">...

Supports object syntax with v-bind


<div v-bind:style="{ fontWeight: isActive ? 'bold' : 'regular' }">..

8 . 3
Vue.js essentials

7. Components

<track-item>

9 . 1
Components

Vue.component("track-item", {
props: ["title"],
template: '<div>{{ title }}</div>'
});

Here we tell Vue to register a <track-item> component which takes one


property title

Calling Vue.component() will registered the component globally. It


means you can now use <track-item> anywhere in the app (eg. inside
other components)

The template property lets you specify what to render

Component template should contain exactly one root element

9 . 2
Components

Vue.component("track-item", {
props: ["title"],
template: '<div>{{ title }}</div>'
});

Our component can now be used as a custom element

<track-item title="Despacito"></track-item>
<track-item title="Gangnam Style"></track-item>

9 . 3
Components

Vue.component("track-item", {
props: ["title"],
render(createElement) {
return createElement('div', this.title)
}
});

Alternatively, instead of using a Template string you can implement a


render function

Under the hood,  Vue compiles template strings into render functions.
In some rare case you may need to directly write render functions to
unlock the full power of Javascript.

Generally, it's better to use templates because they are easier to read
and much more concise

9 . 4
Components
Let's make our component a bit smarter

Components can emit custom


Vue.component("track-item", {
props: { events. This components emits a
id: String, play event when the play button is
title: String,
isPlaying: {
clicked.
type: Boolean,
default: false,
}, Components accept the same
}, options as new Vue (there are few
methods: {
onPlay() {
exceptions such the el option)
// emits a custom event with track id
this.$emit('play', this.id)
} You can define types for props. Vue
}, will throw a warning if the
template: `
<div :class="['track', { isPlaying }]"> component receive props of the
<button @click="onPlay">Play</button> wrong type
<span>{{ title }}</span>
</div>
`,
});

9 . 5
Components

You can render components multiple times with the v-for directive
and listen to custom events 

<div id="#app">
⚠ DOM templates have the
<track-item
following restrictions:
v-for="track in tracks"
:key="track.id" Component names should be
:id="track.id" kebab-case
:title="track.title"
:is-playing="isPlaying(track)" Attributes should be kebab-
@play="selectTrack(track)" case
></track-item>
</div> Self closing elements are not
allowed

9 . 6
Component anatomy

Vue.component("my-component", {
props: {
title: String,
info: Object,
email: {
type: String,
required: true,
default: 'none',
validator() {
/* return true if value is valid */
}
},
},
data() { /* must be a function */ }
created() {},
mounted() {},
methods: {},
computed: {},
watch: {},
template: `<div>....</div>`
});

9 . 7
Vue.js essentials

8. Single file
components

10 . 1
Single file components

So far we looked at the minimal setup for a Vue app. This can work well
for simple projects, where Vue is only used to enhance certain views.

However, for more complex projects, the following


disadvantages become apparent:

Global definitions - force unique names for every component


String templates – No syntax highlighting in string templates
No CSS support
No build step – Limited to HTML,  ES5 Javascript, and CSS

10 . 2
Single file
component
(SFC)
Syntax syntax highlighting

JS Modules

Component scoped CSS

Browsers don't understand the


.vue extension. You need a
build tool such as webpack to
convert your code into regular
Javascript

10 . 3
Setup a Vue project

What you need to get started with Vue and


Single file components

A code editor such as VSCode with


Vetur extension 
Node.js and NPM
Vue CLI

10 . 4
Setup a Vue project

Vue CLI is a command-line tool for rapid Vue.js development. It


provides the ability to quickly scaffold a new project via vue create
command

Install Vue CLI globally

npm install -g @vue/cli

Initialize a project

vue create my-project

Or play with this sandbox


👉 https://codesandbox.io/s/vue-cli-project-8jb1x
10 . 5
https://codesandbox.io/embed/vue-cli-project-8jb1x?
fontsize=14&hidenavigation=1&theme=dark

10 . 6
Local component registration
Importing a component from a single-file component. This is called local
component registration

<template>
<TrackItem id="1" title="Despacito" isPlaying />
</template>

<script>
import TrackItem from "@/components/TrackItem.vue";

export default {
components: { TrackItem },
};
</script>

In Single File Components..


Component name can be PascalCase
Props can be camelCase
Self-closing components are allowed

10 . 7
Vue.js essentials

9. Routing
/ /playlist/:id

11 . 1
Single page applications (SPA)

Single page applications don't require page loads every


time the route changes

11 . 2
Install Vue router

Vue router is an official plugin for Vue Router that helps link between
the browser's URL/History and Vue's components allowing for certain
paths to render whatever view is associated with it.
 

npm install vue-router

// main.js
import Vue from 'vue'
import VueRouter from 'vue-router'

// Installs the plugin


Vue.use(VueRouter)

11 . 3
Configure Vue router

// main.js Our configuration maps


import Vue from 'vue'
import VueRoute from 'vue-router' each route to one Vue
component
import App from './App.vue'
import Home from '@/views/Home.vue'
import Playlist from '@/views/Playlist.vue'
Route's path can have
Vue.use(VueRouter)
dynamic parameters
const router = new VueRouter({
mode: 'history', The router instance is
routes: [
{ injected in the root Vue
instance
path: '/',
name: 'home',
component: Home
},
{
path: '/playlist/:id',
name: 'playlist',
component: Playlist
},
]
})

new Vue({
router,
el: '#app',
render: h => h(App)
})

11 . 4
Vue Router
App.vue can use <router-view /> to let Vue route render the correct component
based on the current URL

<template>
<div>
<!-- common header for all routes -->
<router-view />
<!-- common footer for all routes -->
</div>
</template>

Components can access the current route using this.$route

// Playlist.vue
// path: /playlist/:id
export default {
created() {
const id = this.$route.params.id
}
}

11 . 5
Navigation
In the past, the only way to change the URL was to change the window.location
which always reloaded the page

window.location = '/playlist/12345';

Except, if all you changed was the hash (such as when you clicking on <a
href="#target">link</a>. This trick has been used in the past to allow client-side
routing.

Now, browsers implemented the HTML5 History API giving developers the ability
to modify a website URL without reloading the page

history.replaceState(null, null, '/playlst/12345');

11 . 6
Navigation
Using <a href=""> will cause the page to reload

<template>
<a href="/playlist/12345">Link</a>
</template>

Instead, you can use the <router-link> global component to use the HTML5 History
API

<template>
<router-link to="/playlist/12345">Link</router-link>
</template>

11 . 7
Vue.js essentials

10. State
management currentTrack?
<Queue />

<Playlist />
currentTrack?

<Player />
currentTrack?

12 . 1
Component structure

This structure is not ideal


because when if we
navigate back to the home
page, the <Playlist /> view is
destroyed as well as its
children

12 . 2
Component structure

Now <Queue /> and


<Player> stays rendered
even when route
changes

Holding the state in the


top-level parent
component is a possible

<App /> can pass the


currentTrack to child
elements as props or
using Vue provide/inject

12 . 3
External store
Having an external store is more flexible

Any component can


access data from the
store

Components can
submit actions to
mutate the store

When the store is


mutated, affected
components will re-
render

12 . 4
Vuex
Vuex is a state management pattern + library for
Vue.js applications

12 . 5
One-way data flow

12 . 6
Vuex

Installation

npm install vuex --save

import Vue from 'vue'


import Vuex from 'vuex'

Vue.use(Vuex)

12 . 7
Vuex

Create store

const store = new Vuex.Store({


state: {
currentTrack: null,
},
mutations: {
setCurrentTrack() {}
},
actions: {
playTrack() {}
}
});

12 . 8
Vuex

Create store
1 const store = new Vuex.Store({
2 state: {
3 currentTrack: null,
4 },
5 mutations: {
6 setCurrentTrack(state, track) {
7 state.currentTrack = track
8 }
9 },
10 actions: {
11 playTrack({ commit }, track) {
12 commit('setCurrentTrack', track)
13 }
14 }
15 });
16
17 new Vue({
18 el: '#app',
19 store: store,
20 //...
21 })

12 . 9
Vuex

Accessing store from components

<button @click="$store.actions.playTrack(track)">...

<span>{{ $store.state.currentTrack.title }}</span>

12 . 10
Questions ❓❔

13

You might also like