Reactivity
Declare state
Update state
Templating
Styling
Vue 2
<template>
<div>
<h1 class="title">I am red</h1>
<button style="font-size: 10rem">I am a button</button>
</div>
</template>
<style scoped>
.title {
color: red;
}
</style>
Loop
Event click
Vue 2
<script>
export default {
data() {
return {
count: 0,
};
},
methods: {
incrementCount() {
this.count++;
},
},
};
</script>
<template>
<div>
<p>Counter: {{ count }}</p>
<button @click="incrementCount">+1</button>
</div>
</template>
Dom ref
Conditional
Vue 2
<script>
export default {
data() {
return {
TRAFFIC_LIGHTS: ["red", "orange", "green"],
lightIndex: 0,
};
},
computed: {
light() {
return this.TRAFFIC_LIGHTS[this.lightIndex];
},
},
methods: {
nextLight() {
this.lightIndex = (this.lightIndex + 1) % this.TRAFFIC_LIGHTS.length;
},
},
};
</script>
<template>
<div>
<button @click="nextLight">Next light</button>
<p>Light is: {{ light }}</p>
<p>
You must
<span v-if="light === 'red'">STOP</span>
<span v-else-if="light === 'orange'">SLOW DOWN</span>
<span v-else-if="light === 'green'">GO</span>
</p>
</div>
</template>
static const TRAFFIC_LIGHTS = ["red", "orange", "green"];
<let/lightIndex=0>
<const/light=TRAFFIC_LIGHTS[lightIndex]>
<button onClick() { lightIndex = (lightIndex + 1) % TRAFFIC_LIGHTS.length }>
Next light
</button>
<p>Light is: ${light}</p>
<p>
You must
<if=light === "red">STOP</if>
<else if=light === "orange">SLOW DOWN</else>
<else>GO</else>
</p>
Lifecycle
On mount
On unmount
Vue 2
<script>
export default {
data() {
return {
time: new Date().toLocaleTimeString(),
timer: null,
};
},
mounted() {
this.timer = setInterval(() => {
this.time = new Date().toLocaleTimeString();
}, 1000);
},
beforeDestroy() {
clearInterval(this.timer);
},
};
</script>
<template>
<p>Current time: {{ time }}</p>
</template>
Component composition
Props
Vue 2
<script>
import UserProfile from "./UserProfile.vue";
export default {
components: {
UserProfile,
},
};
</script>
<template>
<UserProfile
name="John"
:age="20"
:favorite-colors="['green', 'blue', 'red']"
is-available
/>
</template>
Emit to parent
Vue 2
<script>
import AnswerButton from "./AnswerButton.vue";
export default {
components: {
AnswerButton,
},
data() {
return {
isHappy: true,
};
},
methods: {
onAnswerNo() {
this.isHappy = false;
},
onAnswerYes() {
this.isHappy = true;
},
},
};
</script>
<template>
<div>
<p>Are you happy?</p>
<AnswerButton @yes="onAnswerYes" @no="onAnswerNo" />
<p style="font-size: 50px">
{{ isHappy ? "😀" : "😥" }}
</p>
</div>
</template>
Slot
Slot fallback
Context
Vue 2
<script>
import UserProfile from "./UserProfile.vue";
export default {
components: { UserProfile },
provide() {
return {
user: Object.assign(this.user, {
updateUsername: this.updateUsername,
}),
};
},
data() {
return {
user: {
id: 1,
username: "unicorn42",
email: "[email protected]",
},
};
},
methods: {
updateUsername(newUsername) {
this.user.username = newUsername;
},
},
};
</script>
<template>
<div>
<h1>Welcome back, {{ user.username }}</h1>
<UserProfile />
</div>
</template>
<let/user={
id: 1,
username: "unicorn42",
email: "[email protected]",
}>
<const/updateUsername(newUsername) {
user = { ...user, username: newUsername };
}>
<h1>Welcome back, ${user.username}</h1>
<context={ ...user, updateUsername }>
<UserProfile />
</context>
Form input
Input text
Checkbox
Vue 2
<script>
export default {
data() {
return {
isAvailable: true,
};
},
};
</script>
<template>
<div>
<input id="is-available" v-model="isAvailable" type="checkbox" />
<label for="is-available">Is available</label>
</div>
</template>
Radio
Vue 2
<script>
export default {
data() {
return {
picked: "red",
};
},
};
</script>
<template>
<div>
<div>Picked: {{ picked }}</div>
<input id="blue-pill" v-model="picked" type="radio" value="blue" />
<label for="blue-pill">Blue pill</label>
<input id="red-pill" v-model="picked" type="radio" value="red" />
<label for="red-pill">Red pill</label>
</div>
</template>
Select
Vue 2
<script>
export default {
data() {
return {
selectedColorId: 2,
colors: [
{ id: 1, text: "red" },
{ id: 2, text: "blue" },
{ id: 3, text: "green" },
{ id: 4, text: "gray", isDisabled: true },
],
};
},
};
</script>
<template>
<select v-model="selectedColorId">
<option
v-for="color in colors"
:key="color.id"
:value="color.id"
:disabled="color.isDisabled"
>
{{ color.text }}
</option>
</select>
</template>
static const colors = [
{ id: 1, text: "red" },
{ id: 2, text: "blue" },
{ id: 3, text: "green" },
{ id: 4, text: "gray", isDisabled: true },
];
<let/selectedColorId=2>
<select value:=selectedColorId>
<for|{ id, isDisabled, text }| of=colors>
<option value=id disabled=isDisabled>
${text}
</option>
</for>
</select>
Webapp features
Render app
Fetch data
Vue 2
<script>
export default {
data() {
return {
isLoading: false,
error: undefined,
users: undefined,
};
},
mounted() {
this.fetchData();
},
methods: {
async fetchData() {
this.isLoading = true;
try {
const response = await fetch("https://randomuser.me/api/?results=3");
const { results: users } = await response.json();
this.users = users;
this.error = undefined;
} catch (error) {
this.error = error;
} finally {
this.users = undefined;
this.isLoading = false;
}
},
},
};
</script>
<template>
<p v-if="isLoading">Fetching users...</p>
<p v-else-if="error">An error ocurred while fetching users</p>
<ul v-else-if="users">
<li v-for="user in users" :key="user.login.uuid">
<img :src="user.picture.thumbnail" alt="user" />
<p>
{{ user.name.first }}
{{ user.name.last }}
</p>
</li>
</ul>
</template>
<try>
<await|{ results: users }|=fetch("https://randomuser.me/api/?results=3").then(res => res.json())>
<ul>
<for|{ picture, name }| of=users>
<li>
<img src=picture.thumbnail alt="user">
<p>${name.first} ${name.last}</p>
</li>
</for>
</ul>
</await>
<@placeholder>
<p>Fetching users...</p>
</@placeholder>
<@catch|error|>
<p>An error occurred while fetching users</p>
</@catch>
</try>