Summary of Vue JS2 Tutorial by Net Ninja (Part 1 of 3)

JL’s Self-teaching Story #2

Lim
10 min readAug 30, 2018

[JL’s Self-teaching Story] Series

[Net Ninja] JS Regular Expressions
[Net Ninja] Vue JS2 (Part1(current), Part2, Part3)
[Net Ninja] Vuex
[Net Ninja] Python3 (Part1, Part2, Part3)
[Net Ninja] Django (Part1, Part2, Part3)
[Net Ninja] Sass (Part1, Part2)
[Sean Larkin] Webpack4 (Part1, Part2, Part3, Part4)

🌲 This is the first part of my summary of Vue JS Tutorial by Net Ninja on YouTube.

1) Vue Instance
2) Data & Methods
3) Data Binding
4) Events
5) Event Modifiers
6) Keyboard Events
7) Two-Way Data Binding
8) Computed Properties
9) Dynamic CSS
10) Conditionals (v-if vs v-show)
11) Looping with v-for
12) Simple Punching Game
13) Multiple Vue Instances
14) Intro to Components
15) Refs

“Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces.

Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects.

On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.” (Official Vue website)

1) Vue Instance (YouTube)

Every Vue.js app is bootstrapped by creating a root Vue instance with the Vue constructor function.

[index.html]
<body>
<div id="vue-app">
<h1>{{ name }}</h1>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
name : 'Jen'
}
});

2) Data & Methods (YouTube)

“When a Vue instance is created, it adds all the properties found in its data object to Vue’s reactivity system. When the values of those properties change, the view will “react”, updating to match the new values.” (Official Vue website)

A Vue method is a function associated with the Vue instance.

[index.html]
<body>
<div id="vue-app">
<h1>{{ greet('night')}}</h1>
<p>{{ name }}</p>
<p>Job: {{ job }}</p>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
name : 'Jen',
job: 'Ninja'
},
methods: {
greet: function(time){
return 'Good ' + time + ', '+ this.name;
}

}
});

Depending on what we write in greet(), the output is changed.

Check out JSFiddle

3) Data Binding (YouTube)

Vue.js uses an HTML-based template syntax that allows you to declaratively bind the rendered DOM to the underlying Vue instance’s data. All Vue.js templates are valid HTML that can be parsed by spec-compliant browsers and HTML parsers.

Under the hood, Vue compiles the templates into Virtual DOM render functions. Combined with the reactivity system, Vue is able to intelligently figure out the minimal number of components to re-render and apply the minimal amount of DOM manipulations when the app state changes.

If you are familiar with Virtual DOM concepts and prefer the raw power of JavaScript, you can also directly write render functions instead of templates, with optional JSX support.” (Official Vue website)

[index.html]
<body>
<div id="vue-app">
<h1>Data Binding</h1>
<a v-bind:href="website">Google</a>
<p v-html="websiteTag"></p>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
website: 'https://www.google.com/',
websiteTag: '<a href=
"https://www.google.com/">Google yay!</a>'
}
});

There are two ways to link a webpage: v-bind:href & v-html.

> v-bind: can be shortened as : .

4) Events (YouTube)

Vue allows us to intercept any DOM event by using directive(s) on element(s).

[index.html]
<body>
<div id="vue-app">
<h1>Events</h1>
<button @click="add(1)">Add a year</button>
<button @click="subtract(1)">Subtract a year</button>
<button @dblclick="add(10)">Add 10 years</button>
<button @dblclick="subtract(10)">Subtract 10 years</button>
<p>My age is {{ age }}</p>
<div id="canvas" @mousemove="updateXY">{{ x }},{{ y }}</div>
</div>
</body>
-----------------------------------
[styles.css]
#canvas{
width: 600px;
padding: 200px 20px;
text-align: center;
border: 1px solid #333;
}
-----------------------------------[app.js]
new Vue({
el: '#vue-app',
data: {
age: 25,
x: 0,
y: 0
},
methods: {
add: function(inc){
this.age += inc;
},
subtract: function(dec){
this.age -= dec;
},
updateXY: function(event){
this.x = event.offsetX;
this.y = event.offsetY;
},
}
});
  1. We can control how much we would like to increment when clicking buttons by changing a number in @click="add()" .
  2. “The offsetX & offsetX read-only property of the MouseEvent interface provides the offset in the X and Y coordinates of the mouse pointer between that event and the padding edge of the target node.” (MDN)

> v-on: can be shortened as @ .

5) Event Modifiers (YouTube)

“It is a very common need to call event.preventDefault() or event.stopPropagation() inside event handlers. Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details.

To address this problem, Vue provides event modifiers for v-on. Recall that modifiers are directive postfixes denoted by a dot.” (Official Vue website)

  • .stop : the click event’s propagation will be stopped
  • .prevent : the submit event will no longer reload the page
  • .capture : use capture mode when adding the event listener
  • .self : only trigger handler if event.target is the element itself
  • .once : listen for the event only once
  • .passive : correspond to addEventListener‘s passive option.

6) Keyboard Events (YouTube)

[index.html]
<body>
<div id="vue-app">
<h1>keyboard event</h1>
<label>Name: </label>
<input type="text" @keyup.enter="logName"/>

<label>Age: </label>
<input type="text" @keyup.alt.enter="logAge"/>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
methods: {
logName: function(){
alert('you entered your name');
},
logAge: function(){
alert('you entered your age');
}
}
});

The full list of key modifier aliases is the following : (Official Vue website)

  • .enter
  • .tab
  • .delete (captures both “Delete” and “Backspace” keys)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

You can also define custom key modifier aliases via the global config.keyCodes object:

// enable `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

7) Two-Way Data Binding (YouTube)

[index.html]
<body>
<div id="vue-app">
<h1>keyboard event</h1>
<label>Name: </label>
<input type="text" v-model="name"/>
<span>{{ name }}</span>

<label>Age: </label>
<input type="text" v-model="age"/>
<span>{{ age }}</span>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
name: '',
age: ''
}
});

As a text is entered in the input field, the text is outputted next to the input field.

8) Computed Properties (YouTube)

#1 Methods

When it comes to “methods”, Vue doesn’t know which one to run depending on what has been updated.

So, when clicking a button, both ‘add to A’ & ‘add to B’ functions run, although only a corresponding value is changed. (e.g., Only the age of A is changed when ‘add to A’ button is clicked. But, both ‘AddtoA’ & ‘AddtoB’ are printed on the console.)

[index.html]
<body>
<div id="vue-app">
<h1>Computed Properties : #1 Methods</h1>
<button @click="a++">Add to A</button>
<button @click="b++">Add to B</button>
<p>A - {{ a }}</p>
<p>B - {{ b }}</p> -->
<p>Age + A = {{ addToA() }}</p>
<p>Age + B = {{ addToB() }}</p>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
age: 20,
a: 0,
b: 0
},
methods: {
addToA: function(){
console.log('addtoA');
return this.a + this.age;
},
addToB: function(){
console.log('addtoB');
return this.b + this.age;
}
}
});

Check out JS Bin here.

#2 Computed

“Computed” properties watch variables they need & run them only when needed.

[index.html]
<body>
<div id="vue-app">
<h1>Computed Properties : #1 Methods</h1>
<button @click="a++">Add to A</button>
<button @click="b++">Add to B</button>
<p>A - {{ a }}</p>
<p>B - {{ b }}</p> -->
<p>Age + A = {{ addToA }}</p>
<p>Age + B = {{ addToB }}</p>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
age: 20,
a: 0,
b: 0
},
computed: {
addToA: function(){
console.log('addtoA');
return this.a + this.age;
},
addToB: function(){
console.log('addtoB');
return this.b + this.age;
}
}
});

> Instead of {{ addToA() }}, enter {{ addToA }}.

> Instead of methods:, enter computed:.

Check out JS Bin here.

9) Dynamic CSS (YouTube)

We can style code differently based on user interaction.

[index.html]
<body>
<div id="vue-app">
<h1>Dynamic CSS</h1>
<button @click="nearby = !nearby">Toggle Nearby</button>
<button @click="available = !available">Toggle Available</button>
<div v-bind:class="compClasses">
<span>Jen</span>
</div>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
available: false,
nearby: false
},
computed: {
compClasses: function(){
return {
available: this.available,
nearby: this.nearby
}
}
}
});
-----------------------------------
[style.css]
span{
background: red;
display: inline-block;
padding: 10px;
color: #fff;
margin: 10px 0;
}
.available span{
background: green;
}
.nearby span:after{
content: "nearby";
margin-left: 10px;
}

> When clicking “Toggle Nearby” button, content “nearby” is toggled.

> When clicking “Toggle Available” button, the color of content(s) “Jen” (and “nearby”) is changed.

10) Conditionals (v-if vs v-show) (YouTube)

#1 v-if

<p> tag is removed from the DOM completely or taken into the DOM when clicking a button.

[index.html]
<body>
<div id="vue-app">
<h1>Conditionals</h1>
<button @click="error = !error">Toggle Error</button>
<button @click="success = !success">Toggle Success</button> -->
<p v-if="error">There has been an error.</p>
<p v-else-if="success">yay! success!</p>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
error: false,
success: false
}
});

#2 v-show

<p> tag is never removed from the DOM completely. When the <p> tag becomes “false”, display: none becomes active.

[index.html]
<body>
<div id="vue-app">
<h1>Conditionals</h1>
<button @click="error = !error">Toggle Error</button>
<button @click="success = !success">Toggle Success</button> -->
<p v-show="error">There has been an error.</p>
<p v-show="success">yay! success!</p>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
error: false,
success: false
}
});

11) Looping with v-for (YouTube)

[index.html]
<body>
<div id="vue-app">
<h1>Looping through Lists</h1>
<ul>
<li v-for="character in characters">{{ character }}</li>
</ul>
<ul>
<li v-for="ninja in ninjas">{{ ninja.name }} : {{ ninja.age }} </li>
</ul>
<ul>
<li v-for="(ninja, index) in ninjas">{{ index }}. {{ ninja.name }} : {{ ninja.age }}</li>
</ul>
<template v-for="ninja in ninjas">
<div v-for="(val,key) in ninja">
<p>{{ key }} : {{ val }}</p>
</div>
</template>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
characters: ['A', 'B', 'C', 'D'],
ninjas: [
{ name: 'A', age: 25 },
{ name: 'B', age: 35 },
{ name: 'C', age: 55 }
]
}
});

> 1 & 2. By setting the name of a data property as a plural form, we can use a singular form of the data property when looping with v-for.

> 3 & 4. For an object, we can display index & cycle through key-value pairs.

12) Simple Punching Game (YouTube)

This game is to punch a bag until a health level reaches to zero. When the game is over, an image of a burst bag appears in the screen. A user can restart the game anytime.

[index.html]
<body>
<div id="vue-app">
<!-- bag image -->
<div id="bag" v-bind:class="{ burst: ended }"></div>
<!-- bag health -->
<div id="bag-health">
<div v-bind:style="{ width: health + '%'}"></div>
</div>
<!-- game controls -->
<div id="controls">
<button @click="punch" v-show="!ended">Punch</button>
<button @click="restart">Restart</button>
</div>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
health: 100,
ended: false
},
methods: {
punch: function(){
this.health -= 10;
if(this.health <= 0){
this.ended = true;
}
},
restart: function(){
this.health = 100;
this.ended = false;
}
}
});
-----------------------------------
[style.css]
#bag{
width: 200px;
height: 450px;
margin: 0 auto;
background: url(https://s25.postimg.cc/fl0ff76vz/bag.png) center no-repeat;
background-size: 80%;
}
#bag.burst{
background: url(https://s25.postimg.cc/hctea4de7/bag-burst.png) center no-repeat;
background-size: 80%;
}
#bag-health{
width: 200px;
border: 2px solid #000;
margin: 0 auto 20px auto;
}
#bag-health div{
height: 20px;
background: crimson;
}
#controls{
width: 120px;
margin: 0 auto;
}
  1. “Punch” button is displayed only when the game is still in progress : v-show="!ended".
  2. The health bar is controlled by binding the style through v-bind: style.
  3. In order to show a burst bag image only when the burst is true, “burst” class is bound to “bag” id with a bag image.

> I uploaded images to PostImage.

13) Multiple Vue Instances (YouTube)

[index.html]
<body>
<h1>Multiple Vue Instances</h1>

<div id="vue-app-one">
<h2>{{ title }}</h2>
<p>{{ greet }}</p>
</div>

<div id="vue-app-two">
<h2>{{ title }}</h2>
<p>{{ greet }}</p>
<button @click="changeTitle">Change App 1 title</button>
</div>
</body>
-----------------------------------
[app.js]
var one = new Vue({
el: '#vue-app-one',
data:{
title: 'Vue App 1'
},
computed:{
greet: function(){
return 'Hello from app 1'
}
}
});
var two = new Vue({
el: '#vue-app-two',
data:{
title: 'Vue App 2'
},
methods:{
changeTitle: function(){
one.title = 'title changed'
}
},
computed:{
greet: function(){
return 'Hello from app 2 !!!'
}
}
});
two.title = 'changed from outside!';
  1. For a “method” property, we need to put () in mustaches like {{ greet() }}. For a “computed” property, there is no need to put () in mustaches like {{ greet }}.
  2. We can access a Vue instance from outside of the instance. (e.g., two.title = 'changed from outside!')

If you constantly interact with several Vue instances in a large application, you might re-consider how you structure your application. It might be better to bundle everything together in one or two Vue instance(s), because it’s more natural to communicate between data in that way.

14) Intro to Components (YouTube)

Components are reusable Vue instances with a name. (Official Vue website)

[index.html]
<body>
<div id="vue-app-one">
<h2>Vue App 1</h2>
<greeting></greeting>
</div>

<div id="vue-app-two">
<h2>Vue App 2</h2>
<greeting></greeting>
</div>
</body>
-----------------------------------
[app.js]
Vue.component("greeting", {
template: "<p>Hey! I\'m {{ name }}. <button @click="changeName">Change name</button></p>",
data: function(){
return{
name: "Jen"
}
},
methods: {
changeName: function(){
this.name = "Mario";
}
}
});
new Vue({
el: "#vue-app-one"
});
new Vue({
el: "#vue-app-two"
});
  1. Template with a name of “greeting” is inserted to the html document as <greeting></greeting>.
  2. In template, data must be a function. By providing data as a function, every time we create a new instance of it, a fresh copy of the function is returned. Modifying data in an instance doesn’t affect the shared data in another instance.

When app.js is changed like the following, shared data in the instances is updated together when “Change Name” button is clicked.

[app.js]
let data = {
name : "Jen"
}
Vue.component("greeting", {
...
data: function(){
return data
},
...
});
...

15) Refs (YouTube)

We use refs to reference an element on a page & grab information about it.

[index.html]
<body>
<div id="vue-app">
<h2>Refs</h2>
<input type="text" ref="input"/>
<button @click="readRefs">submit</button>
<p>Your fav food: {{ output }} </p>
<div ref="try">hello</div>
</div>
</body>
-----------------------------------
[app.js]
new Vue({
el: '#vue-app',
data: {
output: 'what\'s your answer?'
},
methods: {
readRefs: function(){
console.log(this.$refs.try.innerText);
this.output = this.$refs.input.value;
}
}
});
  1. this.$refs : allows us to access a number of things (you can find that out with console.log(this.$refs).)
  2. this.$refs.<name-of-ref>.value : content typed in the input field
  3. this.$refs.<name-of-ref>.innerText : element in the div with the ref name

Check out JS Bin here.

If you’d like to read the next parts of my summary of Vue JS2 Tutorial by Net Ninja, please visit here for part 2 and here for part 3.

Thanks for reading! 💕 If you like this blog post, please clap👏

--

--