Getting Started with Vue 3: A Comprehensive Guide

Vue 3 GuideIntroduction to Vue 3

On September 18, 2020, Vue.js released version 3.0 (https://cn.vuejs.org/guide/introduction.html)

Key Changes in Vue 3

  • Performance Improvements
    • Bundle size reduced by 41%
    • Initial rendering 55% faster, updates 133% faster
    • Memory usage reduced by 54%
  • Source Code Upgrades
    • Uses Proxy instead of defineProperty for reactivity
    • Rebuilt virtual DOM implementation and Tree-Shaking
  • TypeScript Support
    • Better TypeScript integration
  • New Features
    • Composition API
    • New built-in components
    • Other enhancements

Creating a Vue Application

Introduction to Vite

Vite official website: https://vitejs.cn

  • What is Vite? - A next-generation frontend build tool
  • Advantages:
    • No bundling during development, fast cold start
    • Lightweight and fast HMR
    • True on-demand compilation

Creating a Vue Project

How to set up a Vue single-page application locally. The created project will use Vite-based build setup and support Vue single-file components (SFC).

Prerequisites: Node.js 18.3 or higher installed (npm package manager https://nvm.uihtm.com/)

// Create the application
npm create vue@latest
// Initial configuration options
✔ Project name: … <your-project-name>
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit testing? … No / Yes
✔ Add an End-to-End Testing Solution? … No / Cypress / Playwright
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes

Scaffolding project in ./<your-project-name>...
Done.
// Navigate to project directory
cd <your-project-name>
// Install dependencies
npm install
// Start the project
npm run dev

Entry File (main.js)

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'

import ArcoVue from '@arco-design/web-vue';
import '@arco-design/web-vue/dist/arco.css';

const app = createApp(App)  // Create instance
const pinia = createPinia() // Create Pinia instance

app.use(ArcoVue)  // Register Arco components
app.use(pinia)    // Mount Pinia
app.use(router)   // Mount router

app.mount('#app') // Mount instance, .mount() should be called after all app configuration and resource registration

Common Composition APIs

setup

setup(): The entry point for using Composition API in components.

<script>
import { ref } from 'vue'
export default {
 setup() {
   const count = ref(0)
   return {
     count
   }
 },
}
</script>

<template>
 <button @click="count++">{{ count }}</button>
</template>

<script setup>: Recommended for Composition API with single-file components.

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
 <button @click="count++">{{ count }}</button>
</template>

<style scoped lang="scss">
</style>

ref()

  • Can define any data type, requires .value for operations, direct access in templates
  • Can reassign entire object via .value
const user = ref({ name: 'Alice' });
user.value = { name: 'Bob' }; // Replace while maintaining reactivity

reactive()

  • Defines reactive data of object type, no .value needed for operations
  • Limitation: Cannot define primitive data types, cannot reassign entire object
const state = reactive({ name: 'Alice' });
// ❌ Error! Breaks reactivity
state = { name: 'Bob' }; 
// ✅ Only modify properties
state.name = 'Bob';

Computed()

Similar to Vue 2, different syntax. Expects a getter function, returns a computed ref.

<script setup>
import { ref, computed } from 'vue'
   
let xing = ref('张')
let ming = ref('三丰')
let xingming = computed(() => {
 	return xing.value + ming.value
})
</script>

watch()

Similar to Vue 2, different usage scenarios.

<script setup>
import { ref, reactive, watch } from 'vue'

const xing = ref('张')
const ming = ref('三丰')
const person = reactive({
 name: '张无忌',
 age: 18
})

function changeAge() {
 person.age ++
}
   
watch(xing, (newValue, oldValue) => {
 console.log(newValue, oldValue, 'xing被监听了')
}, { immediate: true })
</script>

watchEffect()

Automatically tracks reactive dependencies in the callback.

watchEffect(() => {
 const name = xing.value + ming.value
 console.log(name, '==watchEffect')
})

Lifecycle Hooks

<script setup>
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated } from 'vue'
onBeforeMount(() => {
 console.log('==onBeforeMount==')
})
onMounted(() => {
 console.log('==onMounted==')
})
</script>

Composables

"Composables" are functions that encapsulate reusable stateful logic using Vue's Composition API.

// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
 const x = ref(0)
 const y = ref(0)

 function update(event) {
   x.value = event.pageX
   y.value = event.pageY
 }

 onMounted(() => window.addEventListener('mousemove', update))
 onUnmounted(() => window.removeEventListener('mousemove', update))

 return { x, y }
}

Components

Registration Methods

  • Global Registration
  • Local Registration

Props

Parent-child component communication still uses props,单向数据流. .sync modifier is deprecated, use v-model instead.

Events

Trigger custom events using $emit in templates or defineEmits in <script setup>.

Slots

Default slots, named slots, scoped slots work similarly to Vue 2.

Dependency Injection

Use provide() to expose dependencies and inject() to consume them.

v-model

Vue 3.4+ recommends using defineModel() macro for two-way binding.

useAttrs

Access passed-through attributes using useAttrs().

Global API

app.config exposes configuration settings for the application instance.

Built-in Directives and Components

  • v-memo: Skips updates for unchanged sub-trees
  • <Transition>: Provides animation transitions
  • <KeepAlive>: Caches dynamic components
  • <Teleport>: Moves template content to another DOM location

Single-File Components

Vue single-file components (SFC) use *.vue extnesion with <template>, <script>, and <style> blocks.

Compiler Macros

  • defineProps() and defineEmits()
  • defineModel()
  • defineExpose()
  • defineOptions()

Vue 2 vs Vue 3 Differences

  • Root instance creation: new Vue() vs createApp()
  • Composition API vs Options API
  • Reactivity: Object.defineProperty() vs Proxy
  • Lifecycle hooks: beforeCreate/created replaced by setup()
  • v-if vs v-for priority
  • Template refs: $refs vs ref()

Vue Router

Installation

npm install vue-router@4

Router Instance

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
 {
   path: '/',
   component: () => import('@/views/layout/index.vue'),
   redirect: '/main/home',
   children: [
     {
       path: '/main/home',
       name: 'home',
       component: () => import('@/views/home/index.vue')
     }
   ]
 }
]

const router = createRouter({
 history: createWebHistory(import.meta.env.BASE_URL),
 routes
})

export default router

Navigation Guards

Global, per-route, and component-level guards for controlling navigation.

Pinia

Installation

npm install pinia

Store Definition

Two store types: Option Store and Setup Store.

State Management

Direct state mutation, $patch method, and actions.

Subscriptions

Watch state changes using $subscribe() or watch().

Plugins

Extend Pinia stores with custom functionality.

Common Issues

  • beforeRouteEnter guard usage
  • Component communication patterns

Tags: Vue.js Vue 3 Composition API Vite Pinia

Posted on Mon, 06 Jul 2026 16:34:39 +0000 by MichaelHe