Vue.js
Vue is a progressive JavaScript framework for building user interfaces, created by Evan You in 2014. "Progressive" means you can adopt it incrementally — sprinkle it onto a server-rendered page or build a full single-page application with routing, state management, and server rendering. Vue combines HTML-based templates with a fine-grained reactivity system that tracks exactly which state each part of the page depends on.
Vue 3 introduced the Composition API, TypeScript-first internals, and much better performance. It powers applications at companies like Alibaba, GitLab, Nintendo, and many agencies and SaaS products, and it has a cohesive official ecosystem: Vue Router, Pinia for state, Vite for tooling, and Nuxt for full-stack apps.
TL;DR
- Components are single-file components (
.vue) with<template>,<script setup>, and<style scoped>. - The Composition API:
refandreactivefor state,computedfor derived values,watchfor side effects. - Templates use directives:
v-if,v-for,v-bind(:),v-on(@),v-model. - Components communicate with props down, events up (
defineProps,defineEmits). - Reuse logic with composables (
useSomething()functions). - Use Pinia for shared state, Vue Router for routing, and Nuxt for SSR and full-stack apps.
Quick Example
A searchable user list using <script setup>, TypeScript props, computed state, and a composable:
Core Concepts
Reactivity
Vue tracks dependencies automatically through proxies, so only components that read changed state re-render.
Templates and Directives
Templates compile to optimized render functions. Key directives: v-if/v-else/v-show for conditional rendering, v-for with :key for lists, :attr for binding attributes, @event for listeners with modifiers (@submit.prevent), and v-model for two-way binding on inputs and custom components.
Components: Props, Events, Slots
Parents pass data with props and listen to events; children never mutate props. Slots let parents inject markup, and scoped slots pass data back to that markup. provide/inject shares values down a component tree without prop drilling.
Composition API vs Options API
The Options API (data, methods, computed objects) is still supported and approachable. The Composition API groups code by feature rather than option type, works better with TypeScript, and enables composables. New projects typically use <script setup> with the Composition API.
Ecosystem
- Vue Router — nested routes, guards, lazy-loaded route components.
- Pinia — the official store: typed, devtools-integrated, modular. See State Management.
- Vite — the default build tool.
- Nuxt — SSR, static generation, file-based routing, server routes.
- VueUse — hundreds of ready-made composables.
Best Practices
Use <script setup> With TypeScript
It's the most concise syntax and gives typed props and emits via defineProps<>() and defineEmits<>().
Extract Composables for Reusable Logic
Data fetching, form handling, and browser APIs belong in useX() functions rather than copied across components.
Always Key v-for Lists
Stable keys (:key="item.id") let Vue reuse elements correctly. Avoid using the index when items can reorder.
Keep Computed Properties Pure
Computed values should only derive data. Put side effects in watch or event handlers.
Lazy-Load Routes
component: () => import("./views/Settings.vue") splits code per route for faster initial loads.
Common Mistakes
Destructuring Reactive Objects
const { count } = reactive(state) produces a plain value. Use toRefs() or keep the object intact.
Forgetting .value in Script
Refs need .value in <script> (but not in templates). TypeScript and Volar help catch this.
v-if and v-for on the Same Element
Their precedence is confusing. Filter with a computed list or wrap with a <template>.
Mutating Props
Props are one-way. Emit an event or use defineModel() for two-way binding.
Overusing Watchers
Chains of watchers syncing state are fragile. Most of the time a computed is the right tool.
Comparison
FAQ
What is Vue.js used for?
Building interactive user interfaces and single-page applications, from small widgets embedded in existing pages to large apps with routing and server rendering via Nuxt.
Should I learn the Composition API or Options API?
Learn the Composition API with <script setup> for new projects; it scales better and works well with TypeScript. Knowing the Options API helps when maintaining older codebases.
Is Vue better than React?
Neither is universally better. Vue offers a cohesive official ecosystem and gentle learning curve; React has the largest ecosystem and job market. Both are excellent for production apps.
What is Pinia?
Pinia is Vue's official state management library, replacing Vuex. It provides typed stores with state, getters, and actions and integrates with Vue devtools.
When should I use Nuxt?
Use Nuxt when you need server-side rendering for SEO or performance, static site generation, file-based routing, or server API routes alongside your Vue app.
Related Topics
- Nuxt — Full-stack framework for Vue
- React — The most popular alternative
- Svelte — A compiler-based alternative
- State Management — Pinia and patterns for shared state
- TypeScript — Typed Vue components