Vue.js 3 Essentials: Lifecycle Hooks, State Management & More Explained Simply

Author

Kritim Yantra

Jul 22, 2025

Vue.js 3 Essentials: Lifecycle Hooks, State Management & More Explained Simply

🚀 Picture this: You're building your first Vue.js app, and everything seems magical—until your component doesn’t update when it should, your state feels chaotic, or API calls fire at the wrong time. Suddenly, Vue.js feels less like a superpower and more like a puzzle.

Sound familiar? Don’t worry!

In this guide, we’ll break down Vue.js essentials—lifecycle hooks, reactive state, component communication, routing, form validation, Pinia (Vuex’s modern replacement), and API calls—in a way that’s easy, practical, and beginner-friendly.

By the end, you’ll confidently control your app’s behavior like a pro. Let’s dive in!


🔄 1. Lifecycle Hooks: Controlling Your Component’s Life

Every Vue component has a lifecycle—it’s born (mounted), updates (when data changes), and eventually gets destroyed (unmounted). Lifecycle hooks let you run code at these key moments.

Key Lifecycle Hooks

Vue 3 Hooks  When It Runs Use Case
onMounted After component is added to the DOM Fetching API data, setting up event listeners
onUpdated After component updates (data changes) Debugging re-renders, DOM manipulations
onUnmounted Before component is removed Cleaning up timers, subscriptions

Example: Fetching Data on Mount

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
  console.log('Component is ready!');
  fetchData(); // Load data when component appears
});
</script>

💡 Pro Tip: Avoid heavy logic in onUpdated—it runs on every re-render and can cause performance issues!


💡 2. Reactive State: ref() vs. reactive()

Vue’s reactivity system makes your UI update automatically when data changes.

ref()

  • Best for primitive values (strings, numbers, booleans).
  • Access/modify with .value.
import { ref } from 'vue';
const count = ref(0); // count.value = 1

reactive()

  • Best for objects/arrays.
  • No .value needed.
import { reactive } from 'vue';
const user = reactive({ name: 'Alice' }); // user.name = 'Bob'

📌 Which to use?

  • Use ref for simple values.
  • Use reactive for complex objects.

đŸ—Łïž 3. Component Communication

Components need to talk! Here’s how:

Method Use Case
Props Parent → Child data flow
Emits Child → Parent events
Provide/Inject Grandparent → Grandchild (avoid prop drilling)
Slots Dynamic content inside components

Example: Parent → Child via Props

<!-- Parent -->
<ChildComponent :message="hello" />

<!-- Child -->
<script setup>
defineProps(['message']); // Access via props.message
</script>

🧭 4. Routing with vue-router

Need multiple pages? vue-router has you covered.

Key Features

  • <router-link> for navigation (like <a> but faster).
  • useRoute() to access current route (params, query).
  • useRouter() to programmatically navigate (router.push('/home')).

Example: Basic Navigation

import { useRouter } from 'vue-router';
const router = useRouter();

function goHome() {
  router.push('/'); // Redirect to home
}

📝 5. Form Validation (VeeValidate, Vuelidate, or Custom)

Forms are tricky—validation shouldn’t be!

Option 1: VeeValidate (Recommended)

<template>
  <Form @submit="onSubmit">
    <Field name="email" rules="required|email" />
    <ErrorMessage name="email" />
  </Form>
</template>

Option 2: Custom Validation

const email = ref('');
const errors = ref({});

function validate() {
  if (!email.value) errors.value.email = 'Required!';
}

đŸȘ 6. State Management with Pinia (Vuex Replacement)

For global state (like user auth, shopping cart), Pinia is the modern choice.

Example: Creating a Store

// stores/counter.js
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() { this.count++; }
  }
});

Using the Store in Components

import { useCounterStore } from '@/stores/counter';
const counter = useCounterStore();

counter.increment(); // Updates globally!

🌐 7. API Calls with Axios

Fetching data? Axios is your friend.

Best Practice: Call APIs in onMounted

import { onMounted, ref } from 'vue';
import axios from 'axios';

const posts = ref([]);

onMounted(async () => {
  const response = await axios.get('https://api.example.com/posts');
  posts.value = response.data;
});

📌 Tip: Handle errors with try/catch!


đŸ”„ Final Thoughts & Next Steps

Now you’ve got the essential Vue.js toolkit:
✅ Control component timing with lifecycle hooks.
✅ Manage state reactively with ref()/reactive().
✅ Communicate between components without chaos.
✅ Add routing, forms, global state, and API calls like a pro.

Your challenge: Pick one concept (like Pinia or onMounted) and implement it in a project today!


❓ FAQs

Q1: Should I use Vuex or Pinia?
A: Pinia! It’s the official recommendation, simpler, and works with Vue 3.

Q2: When should I use ref vs. reactive?
A: Use ref for single values (numbers, strings) and reactive for objects/arrays.

Q3: Is Axios better than fetch()?
A: Yes! Axios has better error handling and request/response interceptors.


What’s your biggest Vue.js struggle right now? Let’s discuss in the comments! 👇💬

Tags

Vue

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts