Alex Kyriakidis
Author - Educator - Consultant
vueschool.io @vueschool_io
Teacher @ Vue School
Full Stack developer (10 years)
Husband and Father
Teacher @ Vue School
Vue.js Community Partner
Vue.js Oslo meetups organizer
Full Stack developer & Consultant
Foodie 🌶
Oslo, Norway
Creator of Vue.js
npmtrends.com/vue
React 199k
Vue 201k
Like jQuery
<!-- hello.html -->
<html>
<body>
<script src="https://unpkg.com/vue@3"></script>
</body>
</html>
Content Delivery Network
<!-- hello.html -->
<html>
<body>
<script src="https://unpkg.com/vue@3"></script>
<script>
// we can use Vue in here
</script>
</body>
</html>
<script>
Vue.createApp({})
</script>
<script src="https://unpkg.com/vue@next"></script>
<div id="app"></div>
<script>
Vue.createApp({}).mount('#app')
</script>
⚡️ Vue Super Powers
<div id="app"></div>
<script>
Vue.createApp({}).mount('#app')
</script>
<div id="app">
{{message}}
</div>
<script>
Vue.createApp({
data() {
return {
message: 'Hello Vueschool'
}
}
}).mount('#app')
</script>
Options API
<script>
Vue.createApp({
data() {
return {
message: 'Hello Vueschool'
}
}
}).mount('#app')
</script>
Must be a function
Must return a data object
<div id="app">
{{message}}
<input v-model="message">
</div>
<script>
Vue.createApp({
data() {
return {
message: 'Hello Vueschool'
}
}
}).mount('#app')
</script>
v-model directive
in every place you want to display the message
The heading should change instantly whenever the user changes the name →
<div id="app">
{{message}}
<input v-model="message">
</div>
<div id="app">
<img v-bind:src="image.path" v-bind:alt="image.alt" />
</div>
<script>
Vue.createApp({
data() {
return {
image: {
path: '/path/to/image.jpg',
alt: 'Alternative text for an image'
}
}
}
}).mount('#app')
</script>
<div id="app">
<img src="/path/to/image.jpg" alt="Alternative text for an image" />
</div>
Rendered Output
<div id="app">
<a v-bind:href="link.href">{{ link.text }}</a>
</div>
<script>
Vue.createApp({
data() {
return {
link: {
href: 'https://amazon.com',
text: 'Amazon'
}
}
}
}).mount('#app')
</script>
<div id="app">
<a href="https://amazon.com">Amazon</a>
</div>
<div id="app">
<img v-bind:src="image.path" v-bind:alt="image.alt" />
<img :src="image.path" :alt="image.alt" />
</div>
<div id="app">
<!-- Rendered output -->
<img src="/path/to/image.jpg" alt="Alternative text for an image" />
</div>
<div id="app">
<p v-if="sunny">
It's sunny today! 🌞
</p>
</div>
<script>
Vue.createApp({
data() {
return {
sunny: true
}
}
}).mount('#app')
</script>
<div id="app">
<p v-if="sunny">It's sunny today! 🌞</p>
<p v-else>Is it raining? ☔️</p>
</div>
<script>
Vue.createApp({
data() {
return {
sunny: true
}
}
}).mount('#app')
</script>
<div id="app">
<p v-if="sunny">It's sunny today! 🌞</p>
<p v-else-if="windy">It's windy today! 🌬</p>
<p v-else>Is it raining? ☔️</p>
</div>
<script>
Vue.createApp({
data() {
return {
sunny: false,
windy: true
}
}
}).mount('#app')
</script>
<div id="app">
<p v-if="weather === 'sunny'">It's sunny today! 🌞</p>
<p v-else-if="weather === 'windy'">It's windy today! 🌬</p>
<p v-else>Is it raining? ☔️</p>
</div>
<script>
Vue.createApp({
data() {
return {
weather: 'hurricane'
}
}
}).mount('#app')
</script>
Keep it simple or extract the logic
1. add a data property animal
In the template:
2. Display a paragraph that says Dog goes woof! if the animal is a dog
3. Display a paragraph that says Cat goes meow! if the animal is a cat
4. Display a paragraph that says What does the {{animal}} say? for any other animal
⚠️ Only one paragraph should be rendered in the browser.
<script>
Vue.createApp({
data() {
return {
users: [
{id: 1, name: 'Bruce Wayne', alterEgo: 'Batman'},
{id: 2, name: 'Clark Kent', alterEgo: 'Superman'},
{id: 3, name: 'Tony Stark', alterEgo: 'Ironman'},
{id: 4, name: 'Diana Prince', alterEgo: 'Wonder Woman'}
]
}
}
}).mount('#app')
</script>
<div v-for="something in someArray">
<!-- something is available here -->
</div>
<div id="app">
<ul>
<li v-for="food in favoriteFood">{{ food }}</li>
</ul>
</div>
<script>
Vue.createApp({
data() {
return {
favoriteFood: [
'Pizza',
'Burger',
'Hummus'
]
}
}
}).mount('#app')
</script>
<div>
<ul>
<li>Pizza</li>
<li>Burger</li>
<li>Hummus</li>
</ul>
</div>
<div v-for="user in users">
{{ user.name }}
</div>
The item is available inside the element
The item is available inside child elements
<div v-for="user in users">
{{ user.name}}
<span class="pull-right">{{ user.alterEgo }}</span>
</div>
<img
v-for="image in myImages"
:src="image.src"
:alt="image.title" />
The item is available on the element
<div id="app">
<table>
<tr v-for="user in users" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
</tr>
</table>
</div>
<script>
Vue.createApp({
data() {
return {
users: [
{ id: 1, name: 'Huey' },
{ id: 2, name: 'Dewey' },
{ id: 3, name: 'Louie'},
]
}
}
}).mount('#app')
</script>
1. Create a data property with this users array:
2. Render a div for each user
3. Within, display the user name in an h2 and create a bulleted list for user's hobbies
bit.ly/2zLu5Px
<button v-on:click="raining = true">Make it rain!</button>
<button v-on:click="raining = true">Make it rain!</button>
<button v-on:click="makeItRain">Make it rain!</button>
<div id="app">
<button v-on:click="makeItRain">Make it rain!</button>
</div>
<script>
Vue.createApp({
data() {
return {
raining: false
}
},
methods: {
makeItRain () {
this.raining = true
}
}
}).mount('#app')
</script>
Methods are defined on the Vue instance
<script>
Vue.createApp({
data() {
return {
raining: false
}
},
methods: {
makeItRain () {
this.raining = true
},
makeItRainAndSayHi () {
this.makeItRain()
alert('How you doing?')
}
}
}).mount('#app')
</script>
We can access the entire Vue application instance under this
<button @click="makeItRain">Make it rain!</button>
<button v-on:click="makeItRain">Make it rain!</button>
Instead of
<form @submit.prevent="submitForm">
...
</form>
submitForm(event) {
event.preventDefault()
// ...
}
Source vuejs.org
<!-- 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>
<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div v-on:click.self="doThat">...</div>
<textarea @keydown.esc="clearText" />
1. create a list of candidates, where each candidate has a name and a votes property
2. display each candidate’s name and votes
3. add a vote button for each candidate that will increase the candidate’s votes by 1 when clicked - using a method
sample list of candidates: https://goo.gl/TxHR86 →
1. create a form using the HTML form element that adds a candidate to the list using a method.
Form fields: name, initial votes.
💡You will need to prevent default behavior.
The root element needs to be focused
(for example a vote button is clicked)
<div @keyup.l="likeImage(image)">
<img src="img.src" />
</div>
<div @keyup.fl="performAnAction">
...
</div>
<div v-click-outside="closeDropdown">
// ...
</div>
A custom directive
<!-- Dropdown example with multiple directives -->
<div v-click-outside="closeDropdown">
<ul v-if="showDropdown" class="dropdown-menu" >
<!-- dropdown items goes here -->
</ul>
<button v-else @click="openDropdown">Menu</button>
</div>
<!-- Dropdown example with multiple directives -->
<div v-click-outside="closeDropdown">
<ul v-if="showDropdown" class="dropdown-menu" >
<!-- dropdown items goes here -->
</ul>
<button v-else @click="openDropdown">Menu</button>
</div>
Directive
Argument
Value
<!-- Dropdown example with multiple directives -->
<div v-click-outside="closeDropdown">
<ul v-if="showDropdown" class="dropdown-menu" >
<!-- dropdown items goes here -->
</ul>
<button v-else @click="openDropdown">Menu</button>
</div>
Directive
(no argument or value)
<!-- Dropdown example with multiple directives -->
<div v-click-outside="closeDropdown">
<ul v-if="showDropdown" class="dropdown-menu" >
<!-- dropdown items goes here -->
</ul>
<button v-else @click="openDropdown">Menu</button>
</div>
Directive
(no argument)
Value
By Alex Kyriakidis