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>