Skip to main content
Vue (pronounced /vjuː/, like view) is a JavaScript framework for building user interfaces. Like React, it shines in interactive applications.

What is Vue?

Builds on top of standard HTML, CSS, and JavaScript, providing a declarative and component-based programming model.

Declarative Rendering

Vue extends HTML with a template syntax that describes the output based on JavaScript state. What you write in the template directly reflects what appears on screen.

Reactivity

Vue automatically tracks JavaScript state changes and efficiently updates the DOM — without you needing to do anything manually.

Setting Up with Vite

CommandDescription
node -vCheck if Node is installed.
npm create vue@latestCreate Vue project with official installer (create-vue). Choose TypeScript, Router, Pinia, etc.
npm installInstall project dependencies.
npm run devStart development server.
Vue uses create-vue (based on Vite) as the official scaffolding tool, just like React uses Vite.

Single File Component (.vue)

Vue uses .vue files called SFC (Single File Component). It’s the equivalent of .jsx in React. Each .vue file encapsulates the three parts of a component in one place:
  • <script> — JavaScript logic
  • <template> — HTML structure
  • <style> — CSS styles (optionally with scoped)
The scoped in style makes CSS only affect that component, without leaking to others.

API Styles: Options vs Composition

Vue has two ways to write components. Both work — they’re different interfaces over the same underlying system.
Defines component logic via an object of options (data, methods, mounted…). More familiar for those coming from object-oriented programming.
<script>
export default {
  data() {
    return { count: 0 }
  },
  methods: {
    increment() {
      this.count++
    }
  },
  mounted() {
    console.log(this.count)
  }
}
</script>
For new projects, prefer Composition API + <script setup>. Options API is more common in legacy projects or for those coming from OOP.

Reactivity: ref and reactive

In Vue, the equivalent of React’s useState is ref(). When the value changes, the interface updates automatically.
For simple values (string, number, boolean). To change, use .value in script — in template, Vue accesses automatically without .value.
<script setup>
import { ref } from 'vue'

const name = ref('Felipe')
const count = ref(0)

// in script: use .value
count.value++
</script>

<template>
  <!-- in template: no .value -->
  {{ count }}
</template>

Template Syntax

Vue’s template uses HTML with special directives. In React you use JSX with pure JavaScript — in Vue you use attributes prefixed with v- or symbols like @ and :.
SyntaxReact EquivalentDescription
{{ value }}{value}Interpolates a reactive value in HTML.
v-bind:href or :hrefhref={value}Binds an attribute to a reactive value.
v-on:click or @clickonClick={fn}Listens to DOM events.
v-if / v-else{cond && <El />}Conditional rendering.
v-for{arr.map(...)}Renders a list of elements.
v-modelvalue + onChangeTwo-way binding in inputs — binds and updates state automatically.
<p :class="active ? 'green' : 'gray'">Text</p>

Props

Just like in React, props pass data from parent component to child. In Vue with Composition API, you declare them with defineProps(). To emit events back to the parent (like a callback), use defineEmits() — the equivalent of passing a function as a prop in React.
<script setup>
const props = defineProps({
  title: String,
  done: Boolean
})

const emit = defineEmits(['delete'])
</script>
Props are read-only — never modify a prop directly in the child component.

Lifecycle Hooks

The equivalent of React’s useEffect(fn, []) (execute on mount) is Vue’s onMounted().
Vue HookReact EquivalentWhen Called
onMounted()useEffect(fn, [])After component is inserted in DOM.
onUpdated()useEffect(fn, [dep])After a reactive update re-renders the component.
onUnmounted()useEffect(() => () => cleanup, [])When component is removed from DOM. Ideal for cleaning timers and listeners.
<script setup>
import { ref, onMounted } from 'vue'

const tasks = ref([])

onMounted(async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/todos?_limit=10')
  tasks.value = await res.json()
})
</script>
Unlike React, inside onMounted you can use async directly — without needing to create an internal function.

Computed Properties

A value derived from reactive state. Vue automatically recalculates when the dependency changes — and caches it until it actually changes. Equivalent to React’s useMemo(), but without manually declaring dependencies.
<script setup>
import { ref, computed } from 'vue'

const tasks = ref([...])

// recalculates only when tasks change
const completed = computed(() => {
  return tasks.value.filter(t => t.done)
})
</script>

<template>
  {{ completed.length }} tasks completed
</template>
Don’t use computed for actions with side effects (API calls, changing state). For that, use watch.

Watchers

The watch executes a function every time a reactive value changes — equivalent to React’s useEffect(fn, [dep]). Use when you need to react to changes with side effects: save to localStorage, call APIs, start animations.
<script setup>
import { ref, watch } from 'vue'

const tasks = ref([])

// runs every time tasks change
watch(tasks, (newValue) => {
  localStorage.setItem(
    'tasks',
    JSON.stringify(newValue)
  )
}, { deep: true })
</script>
The { deep: true } makes Vue observe changes inside nested objects and arrays.

Routing with Vue Router

The equivalent of React Router Dom is Vue Router — Vue’s official routing library. Install: npm install vue-router@4
Vue RouterReact Router EquivalentUse
createRouter()createBrowserRouter()Creates router with route list.
<RouterView />RouterProviderWhere the current route’s page/component is rendered.
<RouterLink /><Link />Navigation link without page reload.
useRouter()useNavigate()Navigate programmatically between routes.
useRoute()useSearchParams()Access params and query from current route.

Next Steps

Global State

Pinia is Vue’s official state management library — equivalent to Redux/Zustand in React. Simpler and more modern than Vuex (old standard).

Forms

VeeValidate + Zod or Yup for complex form validation.

Data Fetching

VueUse (collection of utility composables) or TanStack Query (same lib as React Query, but for Vue).

Testing

Vitest + Vue Testing Library + Cypress for e2e tests.

Vue on Server

Nuxt.js is the Vue framework for SSR/SSG — equivalent to Next.js for React. Vue market standard.

UI Components

Vuetify, PrimeVue, or shadcn-vue for ready-made component libraries.