Vue 3 Fundamentals

Enviroment Setup

Vue 3 requires Node.js for development. Install the Vue CLI globally:

npm install -g @vue/cli
vue --version  # Verify version (≥4.5.0)
vue create project-name
# Select "Manually select features" during setup

Composition API Fundamentals

Reactive State Management

ref() for Primitive Values

<template>
  <div>
    {{ counter }} <button @click="increment">+</button>
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
  setup() {
    const counter = ref(0);
    const increment = () => counter.value++;
    return { counter, increment };
  }
});
</script>

reactive() for Objects

const userProfile = reactive({
  name: 'Alex',
  age: 30,
  address: {
    city: 'Berlin',
    country: 'Germany'
  }
});

Setup Function Details

  • Executes before beforeCreate lifecycle hook
  • Cannot use 'this' to access component options
  • Cannot be async functon
  • Receives props and context: setup(props, { attrs, slots, emit })

Reactivity System

Vue 2 vs Vue 3 Implementation

Vue 2 uses Object.defineProperty() with getters/setters for each property. Vue 3 leverages Proxy and Reflect for more efficient deep reactivity:

new Proxy(data, {
  get(target, prop) {
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    return Reflect.set(target, prop, value);
  }
});

Computed Properties

const doubled = computed(() => counter.value * 2);
// With setter
const profile = computed({
  get: () => `${firstName.value} ${lastName.value}`,
  set: (val) => {
    [firstName.value, lastName.value] = val.split(' ');
  }
});

Watch Mechanisms

// Basic watcher
watch(counter, (newVal) => {
  console.log('Counter changed:', newVal);
});

// Multiple sources
watch([() => userProfile.age, counter], () => { /* ... */ });

// Effect watcher
watchEffect(() => {
  console.log('Profile updated:', userProfile.name);
});

Lifecycle Hooks

import { onMounted, onUpdated } from 'vue';

setup() {
  onMounted(() => console.log('Component mounted'));
  onUpdated(() => console.log('Component updated'));
}

Composition Utilities

Custom Hooks

// useUser.js
import { reactive, onMounted } from 'vue';
export default function useUser(initialName) {
  const user = reactive({ name: initialName });
  onMounted(() => console.log('User hook mounted'));
  return { user };
}

Ref Conversions

const nameRef = toRef(userProfile, 'name');
const { name, age } = toRefs(userProfile);

Advanced Reactivity

Shallow Reactivity

const shallowUser = shallowReactive({ details: { age: 30 } });
const shallowCounter = shallowRef({ value: 0 });

Readonly Objects

const protectedConfig = readonly({ settings: { darkMode: true } });
const surfaceProtected = shallowReadonly({ permissions: { admin: false } });

Raw Conversions

const original = toRaw(reactiveObject);
const nonReactive = markRaw({ immutable: true });

Custom Reactivity

const customRef = customRef((track, trigger) => ({
  get() {
    track();
    return internalValue;
  },
  set(newVal) {
    internalValue = newVal;
    trigger();
  }
}));

Component Communication

// Parent component
provide('config', reactive({ theme: 'dark' }));

// Child component
const configuration = inject('config');

Type Checking

isRef(value);         // Check for ref object
isReactive(value);    // Check for reactive proxy
isReadonly(value);    // Check for readonly proxy
isProxy(value);       // Check for reactive or readonly proxy

Special Components

Teleport

<Teleport to="body">
  <Modal />
</Teleport>

Suspense

<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <Loader />
  </template>
</Suspense>

Tags: vue3 CompositionAPI Reactivity Proxy TypeScript

Posted on Sat, 01 Aug 2026 16:18:24 +0000 by tiki