Template Syntax
Text & Expressions
{{ message }} {{ count + 1 }} {{ ok ? 'Yes' : 'No' }}
Directives
{{ expr }}Text interpolation
v-bind:attr / :attrBind attribute to expression
v-on:event / @eventAttach event listener
v-modelTwo-way binding (forms)
v-if / v-else-if / v-elseConditional rendering
v-showToggle display CSS (stays in DOM)
v-forList rendering
v-slot / #nameNamed slot content
Attribute Binding
Reactivity
ref (Primitives)
import { ref } from 'vue' const count = ref(0) console.log(count.value) // 0 count.value++ // reactive update
reactive (Objects)
import { reactive } from 'vue' const state = reactive({ count: 0, name: 'Vue' }) state.count++ // no .value needed
ref vs reactive
ref()Any type; access via .value in script
reactive()Objects/arrays only; direct property access
TemplateBoth auto-unwrap (no .value needed)
Destructurereactive loses reactivity; use toRefs()
Computed & Watchers
Computed Properties
import { ref, computed } from 'vue' const items = ref([1, 2, 3, 4, 5]) const evenItems = computed(() => items.value.filter(n => n % 2 === 0) )

Computed values are cached and only re-evaluate when dependencies change

Watchers
import { ref, watch, watchEffect } from 'vue' const query = ref('') // Watch specific source watch(query, (newVal, oldVal) => { console.log(`Changed: ${oldVal} → ${newVal}`) }) // Auto-track dependencies watchEffect(() => { console.log(`Query is: ${query.value}`) })
Watch Options
immediate: trueRun callback immediately on creation
deep: trueDeep watch nested objects
flush: 'post'Run after DOM update
once: trueTrigger only once then stop
Components
Single-File Component (SFC)
Registering Components
SFC Blocks
<script setup>Composition API (recommended)
<template>HTML template
<style scoped>Component-scoped CSS
<style module>CSS Modules ($style object)
Props & Events
Defining Props
Emitting Events
Parent Usage
v-model on Components
Slots
Default Slot

Custom content here

Named Slots

Main content

Scoped Slots
Composition API
Composable Function
// useMouse.js import { ref, onMounted, onUnmounted } from 'vue' export function useMouse() { const x = ref(0) const y = ref(0) function update(e) { x.value = e.pageX y.value = e.pageY } onMounted(() => window.addEventListener('mousemove', update)) onUnmounted(() => window.removeEventListener('mousemove', update)) return { x, y } }
Using Composables
provide / inject
// Parent import { provide, ref } from 'vue' const theme = ref('dark') provide('theme', theme) // Descendant (any depth) import { inject } from 'vue' const theme = inject('theme', 'light') // default
Router (Vue Router)
Route Definitions
import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/user/:id', component: User }, ] })
Template Navigation
Home User 1
Programmatic Navigation
import { useRouter, useRoute } from 'vue-router' const router = useRouter() const route = useRoute() router.push('/about') router.push({ name: 'user', params: { id: 1 } }) console.log(route.params.id)
Route Features
/user/:idDynamic segment (route.params.id)
name: 'user'Named route for programmatic nav
children: [...]Nested routes
beforeEnterPer-route navigation guard
meta: { auth: true }Custom metadata for guards
redirect: '/new-path'Route redirect
Lifecycle Hooks
Hook Order
onBeforeMountBefore initial DOM render
onMountedDOM is ready (fetch data, add listeners)
onBeforeUpdateBefore reactive state re-renders DOM
onUpdatedAfter DOM re-render
onBeforeUnmountBefore component is destroyed
onUnmountedCleanup (remove listeners, timers)
Usage
Lists & Conditionals
v-for
  • {{ item.name }}
  • {{ index }}: {{ item.name }}
  • {{ key }}: {{ val }}

    Always use :key with v-for for efficient DOM updates

    v-if vs v-show
    v-ifConditionally render (add/remove from DOM)
    v-else-ifElse-if chain
    v-elseFallback branch
    v-showToggle display: none (stays in DOM)

    Use v-show for frequent toggles, v-if for rare changes

    Conditionals Example
    Loading...
    Error!
    {{ data }}
    Form Handling
    v-model Basics
    v-model Modifiers
    v-model.lazySync on change instead of input
    v-model.numberAuto-typecast to number
    v-model.trimAuto-trim whitespace
    Event Modifiers
    @click.preventCall preventDefault()
    @click.stopCall stopPropagation()
    @click.onceTrigger at most once
    @keyup.enterOnly on Enter key
    @submit.preventPrevent form submission default