Vue 3 Composition API: Templates and Directives with TypeScript

In this lesson, we’ll look at the basic Vue 3 templates and directives, and learn how to work with interpolation, conditional rendering, and lists. All the examples use the Composition API and TypeScript, which are the most modern approaches in Vue development.
Interpolation of {{ }}
Interpolation — output of data to a template
<template>
<div>
<h1>{{ title }}</h1>
<p>counter: {{ counter }}</p>
</div>
</template>
<script setup lang="ts">
const title: string = "Vue 3 + TypeScript";
const counter: number = 0;
</script>
How it works:
- Data from the
<script setup>automatically becomes available in the template - Vue monitors variable changes and updates the DOM
The v-bind directive
Binds HTML attributes to component data
<template>
<button
:class="{ active: isActive }"
:disabled="isDisabled"
>
Click me
</button>
</template>
<script setup lang="ts">
const isActive: boolean = true;
const isDisabled: boolean = false;
</script>
Key points:
- Shortened entry :class instead of v-bind:class
- You can transfer objects, arrays, or strings.
The v-model directive
Two-way binding for forms
<template>
<input v-model="message" placeholder="Введите текст">
<p>You have entered: {{ message }}</p>
</template>
<script setup lang="ts">
const message: string = "";
</script>
For custom components
defineProps<{ modelValue: string }>();
defineEmits<{ (e: 'update:modelValue', value: string): void }>();
Conditional rendering (v-if vs v-show)
v-if - completely removes/adds an element from the DOM
<template>
<div v-if="isVisible">Visible only if isVisible = true</div>
</template>
<script setup lang="ts">
const isVisible: boolean = true;
</script>
v-show - toggles the CSS property display
<template>
<div v-show="isVisible">Hidden via display: none</div>
</template>
When to use what:
- v-if — for expensive items (for example, heavy components)
- v-show — for frequent switching (for example, tabs)
Working with lists (v-for)
It works like a regular loop only in the template
<template>
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index + 1 }}. {{ item.name }}
</li>
</ul>
</template>
<script setup lang="ts">
interface Item {
id: number;
name: string;
}
const items: Item[] = [
{ id: 1, name: "Vue" },
{ id: 2, name: "TypeScript" }
];
</script>
Important points:
- Always specify :key for stable rendering
- Use interfaces for data typing
Conclusion
{{ }}— output of data to a template- v-bind — dynamic attribute
- v-model — two-way binding
- v-if/v-show — conditional rendering
- v-for — list rendering (don’t forget about :key)
Homework assignment
- Create a to-do list component with v-for and the Todo interface
- Implement the switching of themes (light/dark) via v-bind:class
- Add a modal window that is displayed by v-if