VUE.JS QUICK REFERENCE
Templates, reactivity, components, composition API, router
Template Syntax
Text & Expressions
{{ message }}
{{ count + 1 }}
{{ ok ? 'Yes' : 'No' }}
Directives
| {{ expr }} | Text interpolation |
| v-bind:attr / :attr | Bind attribute to expression |
| v-on:event / @event | Attach event listener |
| v-model | Two-way binding (forms) |
| v-if / v-else-if / v-else | Conditional rendering |
| v-show | Toggle display CSS (stays in DOM) |
| v-for | List rendering |
| v-slot / #name | Named 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 |
| Template | Both auto-unwrap (no .value needed) |
| Destructure | reactive 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: true | Run callback immediately on creation |
| deep: true | Deep watch nested objects |
| flush: 'post' | Run after DOM update |
| once: true | Trigger 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
Fallback content
Custom content here
Named Slots
#header>Title
Main content
#footer>Footer
Scoped Slots
#default="{ item }">
{{ item.text }}
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/:id | Dynamic segment (route.params.id) |
| name: 'user' | Named route for programmatic nav |
| children: [...] | Nested routes |
| beforeEnter | Per-route navigation guard |
| meta: { auth: true } | Custom metadata for guards |
| redirect: '/new-path' | Route redirect |
Lifecycle Hooks
Hook Order
| onBeforeMount | Before initial DOM render |
| onMounted | DOM is ready (fetch data, add listeners) |
| onBeforeUpdate | Before reactive state re-renders DOM |
| onUpdated | After DOM re-render |
| onBeforeUnmount | Before component is destroyed |
| onUnmounted | Cleanup (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-if | Conditionally render (add/remove from DOM) |
| v-else-if | Else-if chain |
| v-else | Fallback branch |
| v-show | Toggle 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.lazy | Sync on change instead of input |
| v-model.number | Auto-typecast to number |
| v-model.trim | Auto-trim whitespace |
Event Modifiers
| @click.prevent | Call preventDefault() |
| @click.stop | Call stopPropagation() |
| @click.once | Trigger at most once |
| @keyup.enter | Only on Enter key |
| @submit.prevent | Prevent form submission default |