Innov8ProTech
Vue.js

Vue.js,
made obvious.

The progressive framework. Templates that read like HTML. Reactivity that just works, without dependency arrays or stale closures.

Vue 3 + Composition API
Nuxt 3 for SSR
ReactivePlayground.vue

ref

count.value

3

v-model

computed

doubled6
greetingHello, Amara!
isHighfalse

Live demo. Click the buttons.

why we use it

Less ceremony. More shipping.

React makes you choose everything — router, state, forms, styling, build tool. Vue makes the obvious choices for you, and lets you override when you need to.

Days to productive

Templates read like HTML. State is a ref. Effects are automatic. New engineers ship real features in their first week.

Reactivity done right

No dependency arrays. No stale closures. Change a ref, and only what depends on it re-renders.

Progressive by design

Start with a single component on a PHP page. Scale up to a full SPA or SSR app. No rewrite in between.

when to pick Vue

Vue vs React vs Angular.

All three are production-ready. The choice depends on your team, not the framework.

CriterionVueReactAngular
Learning curveGentle — daysModerate — weeksSteep — months
Batteries includedYes — router, state, buildNo — you chooseYes — opinionated
Template styleHTML templatesJSXHTML + decorators
TypeScript supportFirst-classFirst-classNative
Hiring poolGood in AfricaLargest globallyEnterprise-heavy
Best forTeams that want speedScale and ecosystemEnterprise structure

two syntaxes. one component.

Write it how you think it.

Vue doesn't force JSX on you. Templates for readability, or render functions for maximum control — the compiler treats them the same.

Template syntaxvue
<template>
<button @click="increment">
Clicked {{ count }} times
</button>
</template>
<script setup>
const count = ref(0);
const increment = () => count.value++;
</script>
Render functionts
// Same component, full control
import
{ ref, h } from 'vue';
const count = ref(0);
const increment = () => count.value++;
export default
{
setup() {
return
() => h('button', { onClick: increment },
`Clicked ${count.value} times`)
}
}

still on Vue 2?

Vue 2 hit end-of-life.

Security patches stopped in December 2023. The migration path below is what we use on live codebases — phased, so the app stays in production throughout.

Step 01

Options API

Composition API

Step 02

Vuex

Pinia

Step 03

Webpack

Vite

Step 04

Vue 2 reactivity

Proxy-based reactivity

reference

Vue technical reference.

Every pattern we use on a Vue project — from install to migration.

Overview

Vue is a progressive framework for building user interfaces. Template-based, reactive by default, and — unlike React — works without a build step if you want it to. Drop a script tag on a page and you have a Vue app.

Install

terminalbash
# SPA with Vite
$ npm create vue@latest my-app
# Full-stack with SSR
$ npm create nuxt@latest my-app

Reactivity

Vue 3 uses Proxy-based reactivity. Primitives are function calls: ref() for any value, reactive() for objects, computed() for derived state.

reactivity.tsts
import
{ ref, computed } from 'vue';
const count = ref(0);
const doubled = computed(() => count.value * 2);
count.value++; // doubled.value === 2

Template syntax

HTML-first templates. Bind data with double braces, listen with @, bind attributes with colon.

Counter.vuevue
<template>
<button @click="increment">
Count: {{ count }}
</button>
</template>
<script setup>
const count = ref(0);
const increment = () => count.value++;
</script>

Composition API

Logic lives in composables — functions starting with use. Reusable across components, testable in isolation.

composables/useCounter.tsts
export function
useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
return
{ count, increment };
}

Components

Typed props, typed emits. Data flows down through props, events flow up through emits.

TodoItem.vuevue
<script setup lang="ts">
interface
Props { item: Todo; }
const props = defineProps<Props>();
const emit = defineEmits<{
(e: 'toggle', id: string): void;
}>();
</script>

Router

Vue Router is the official router. Lazy-loaded routes, nested layouts, and navigation guards.

router/index.tsts
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/dashboard', component: Dashboard },
],
});

State (Pinia)

Pinia is the official state store for Vue 3. Modular, typed, and devtools-friendly.

stores/cart.tsts
export const
useCartStore = defineStore('cart', () => {
const items = ref([]);
const total = computed(() => items.value.length);
return
{ items, total };
});

Migration Vue 2 to 3

Vue 2 hit end-of-life in December 2023. The migration is phased — the app stays in production throughout.

Options to Compositionvue

Before

data() {
return { count: 0 };
}

After

const count = ref(0);

SSR / Nuxt

Nuxt 3 is the full-stack Vue framework. File-based routing, server routes, and hybrid rendering — SSR, SSG, or ISR, per route.

Testing

Vitest for units, Vue Test Utils for components, Playwright for end-to-end.

useCounter.test.tsts
it('increments', () => {
const { count, increment } = useCounter();
increment();
expect(count.value).toBe(1);
});

Tooling

The stack we pair with Vue on every project.

Vite

Build tool

Vue DevTools

Browser extension

Volar

VS Code extension

Vitest

Unit testing

Playwright

E2E testing

TypeScript

Type safety

ESLint

Linting

Prettier

Formatting

Tailwind

Styling

where we use it

Vue interfaces across four sectors.

Fintech

Customer dashboards, trading UIs

Education

Interactive learning platforms

Healthcare

Clinical interfaces with real-time data

Retail

Storefronts and admin panels

questions

Common
questions.

Vue is more approachable. Templates read like HTML, the Composition API is simpler than hooks, and reactivity is automatic — no dependency arrays, no stale closures.

Building with Vue?

We can help — whether you need a team or just engineers.