Vue 3 Cheat Sheet with Composition API
Learn the basic Vue 3 syntax and features, using the all new Composition API. Get up to speed with Vue.
Let's take a look at some of the most common Vue 3 features and syntax. Keep in mind, this is not a comprehensive guide. Though, it should be enough to get you started with Vue 3 and Composition API.
I've got a course on Vue you might like:
Setting up with Vite
The first step is to create a new Vue project. The best way is to use Vite - popular swiss-knife tool for all things frontend. Start a Vue 3 project using Vite by running the following commands:
npm init vite@latest my-vue-project --template vue
cd my-vue-project
npm install
npm run dev
Vite offers a faster development experience with features like hot module replacement (when running locally, all changes you made will be reflected in the browser after save, without having to refresh!).
Single File Components with <script setup>
Vue 3 allows using the <script setup>
syntax, a more concise way to write components.
<template>
<div>{{ message }}</div>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const message = ref("Hello Vue!");
</script>
<style>
div {
color: blue;
}
</style>
In <script setup>
, top-level bindings are automatically exposed to the template.
Template Syntax and Binding
Vue's template syntax integrates seamlessly with JavaScript.
Text Interpolation
Display reactive data:
<template>
<div>{{ message }}</div>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const message = ref("Hello Vue!");
</script>
Attribute Binding
Dynamically bind attributes:
<template>
<img :src="imageSrc" />
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const imageSrc = ref("path/to/image.jpg");
</script>
Directives
v-if, v-else-if, v-else
Conditionally render elements:
<template>
<div v-if="showTypeA">Type A</div>
<div v-else-if="showTypeB">Type B</div>
<div v-else>Type C</div>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const showTypeA = ref(true);
const showTypeB = ref(false);
</script>
v-for
Render a list of items:
<template>
<ul>
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const items = ref([
{ id: 1, text: "Item 1" },
{ id: 2, text: "Item 2" },
]);
</script>
v-on (@ shorthand)
Listen to events:
<template>
<button @click="greet">Greet</button>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const greet = () => alert("Hello!");
</script>
v-model
Create two-way data bindings:
<template>
<input v-model="message" />
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const message = ref("");
</script>
Class and Style Bindings
Apply dynamic styles and classes:
<template>
<div :class="{ active: isActive, 'text-danger': hasError }"></div>
<div :style="{ fontSize: fontSize + 'px' }"></div>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const isActive = ref(true);
const hasError = ref(false);
const fontSize = ref(16);
</script>
Computed Properties and Watchers
Handle complex logic and respond to changes:
<script setup>
import { ref, computed, watch } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const firstName = ref("John");
const lastName = ref("Doe");
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
watch(firstName, (newValue) => console.log(`First name changed to ${newValue}`));
</script>
Slots
Slots allow parent components to inject content into child components, offering flexibility and reusability.
Basic Slot
A child component with a slot:
<!-- ChildComponent.vue -->
<template>
<div>
<slot></slot>
</div>
</template>
In the parent component, any content inside <ChildComponent>
gets projected into the slot.
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<p>This will be displayed where the slot is.</p>
</ChildComponent>
</template>
Named Slots
Child components can have multiple slots with different names.
<!-- ChildComponent.vue -->
<template>
<div>
<slot name="header"></slot>
<slot name="footer"></slot>
</div>
</template>
In the parent, specify which slot to render the content into:
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<template #header>
<h1>Header content here</h1>
</template>
<template #footer>
<p>Footer content here</p>
</template>
</ChildComponent>
</template>
Scoped Slots
Scoped slots allow child components to pass data back to parent components within a slot.
<!-- ChildComponent.vue -->
<template>
<div>
<slot :text="slotText"></slot>
</div>
</template>
<script setup>
import { ref } from "content/blog/maintaining-reactivity-in-vuejs-the-pitfall-of-destructuring-props.mdx";
const slotText = ref("Text from Child Component");
</script>
The parent can use this data:
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<template #default="{ text }">
<p>{{ text }}</p>
</template>
</ChildComponent>
</template>
Here, the child component provides the text property, and the parent uses it within its slot template.