Last Updated: November 21, 2025
Template Syntax
<!-- Text Interpolation -->
<p>{{ message }}</p>
<!-- Directives -->
<div v-if="isVisible">Visible</div>
<div v-show="isShown">Shown</div>
<div v-for="item in items" :key="item.id">{{ item.name }}</div>
<!-- Attribute Binding -->
<img :src="imageUrl" :alt="imageAlt">
<button :disabled="isDisabled">Click</button>
<!-- Event Handling -->
<button @click="handleClick">Click</button>
<input @input="handleInput" v-model="text">
<!-- Class & Style Binding -->
<div :class="{ active: isActive }"></div>
<div :style="{ color: textColor }"></div>
Composition API (Vue 3)
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
// Reactive state
const count = ref(0);
const user = reactive({ name: 'John', age: 30 });
// Computed properties
const doubled = computed(() => count.value * 2);
// Methods
const increment = () => {
count.value++;
};
// Watchers
watch(count, (newVal, oldVal) => {
console.log(`Count changed from ${oldVal} to ${newVal}`);
});
// Lifecycle hooks
onMounted(() => {
console.log('Component mounted');
});
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
Options API
export default {
data() {
return {
message: 'Hello Vue!',
count: 0
};
},
computed: {
doubled() {
return this.count * 2;
}
},
methods: {
increment() {
this.count++;
}
},
watch: {
count(newVal, oldVal) {
console.log('Count changed');
}
},
mounted() {
console.log('Component mounted');
}
};
Directives
| Directive | Description |
|---|---|
v-if
|
Conditional rendering (adds/removes from DOM) |
v-show
|
Conditional display (toggles CSS display) |
v-for
|
List rendering |
v-model
|
Two-way data binding |
v-bind (:)
|
Bind attribute or prop |
v-on (@)
|
Attach event listener |
v-slot (#)
|
Named slots |
💡 Pro Tip:
Use Composition API for better TypeScript support and code reusability!