Vue3零基础入门到实战:完整学习路线与核心API解析
2026/8/30 2:07:23 网站建设 项目流程

2026 年了,Vue3 早就不是“要不要学”的问题,而是“怎么学才最省时间”的问题。如果你正打算零基础入门 Web 前端,又不想被网上一堆碎片化教程绕晕,这篇可以按顺序从头看到尾。本文会用一条完整的路线,带你从环境安装、项目创建、组合式 API、组件通信、路由、Pinia,一直走到项目实战和面试题。

Vue3 当前最值得关注的是组合式 API(Composition API)和<script setup>语法,它们让组件逻辑更集中、复用更简单。同时 Vite 构建工具的普及让冷启动和热更新变得非常快,开发体验比 Vue2 + Webpack 时代提升明显。文章会按住 ESC 拆解关键知识点,并给出大量可直接复制的代码示例。

如果你已经在用 Vue2,想了解 Vue2 和 Vue3 的核心差异,或者是刚学会 HTML/CSS/JavaScript、准备系统学习 Vue3 的小白,这篇都适合。为了让你学完能真正上手,文章还会穿插高频 Vue3 面试题(computedwatch怎么选、defineEmits怎么用、动态路由怎么配置等等)。

1. Vue3 核心能力速览

在学习之前,先用一张表搞清楚 Vue3 的生态现状和基本诉求:

维度说明
框架类型渐进式 JavaScript 前端框架,主打组件化和响应式 UI
当前主流版本Vue 3.x,搭配 Vite 构建工具使用
核心语法组合式 API(Composition API)、<script setup>、响应式 API
常用生态Vue Router 4、Pinia、Element Plus、Axios、Vite
技术门槛前置要求:HTML、CSS、JavaScript 基础;不需要后端知识也能学
启动方式npm run dev/pnpm dev,浏览器访问本地开发服务器
是否支持 TypeScript官方一等公民,Vue3 + TypeScript 是当前企业项目标配
适合场景Web 后台管理系统、中台项目、PC 端应用、移动端 H5、跨端开发(uni-app)
就业方向Web 前端开发、Vue 全栈开发、低代码平台开发、可视化大屏

从技能树看,Vue3 核心要掌握的知识点包括:模板语法、指令、响应式原理、组件化、生命周期、组件通信、Composition API、路由、状态管理、组件库使用、接口请求封装、项目部署。下面从零开始搭建。

2. 适用场景与学习路线

2.1 适合谁学

  • 刚学完 HTML / CSS / JavaScript,想快速进入前端框架阶段的小白。
  • 学校课程或自学过程中接触过 Vue2,正准备升级到 Vue3 的开发者。
  • 工作中维护 Vue3 后台管理系统,但一直对组合式 API 不熟的页面开发者。
  • 准备前端面试,需要系统梳理 Vue3 高频考点的求职者。

2.2 一条主线学习路径

推荐按下面的顺序推进,每步都以“能写出来”为验收标准:

  1. 掌握 JavaScript ES6+ 语法:解构赋值、箭头函数、Promise、async/await、模块化。
  2. 安装 Node.js 和包管理工具,学会创建 Vue3 项目。
  3. 理解 Vue3 模板语法:插值、指令、事件、表单双向绑定。
  4. 掌握响应式核心:refreactivecomputedwatch
  5. 掌握组件化:组件定义、Props、事件、插槽、v-model
  6. 掌握组合式 API:setup<script setup>、自定义 Hook。
  7. 学习 Vue Router 4:路由配置、嵌套路由、动态路由、导航守卫。
  8. 学习 Pinia:状态管理、模块拆分、持久化。
  9. 结合 Element Plus / Vant 开发完整页面。
  10. 接口请求封装 + Axios 拦截器 + 环境变量配置。
  11. 用 Vite 构建部署,输出静态文件到服务器。

这套路径在速成时也是最稳的,每一步都有可以运行的结果,不容易产生“学了不会用”的挫败感。

3. 开发环境准备与前置条件

3.1 安装 Node.js

Vue3 项目依赖 Node.js,建议直接安装 LTS 长期支持版本。安装完成后打开终端(Windows 用 PowerShell / CMD,macOS 用 Terminal)检查版本:

node -v npm -v

如果提示node不是内部或外部命令,说明没装好或没配置 PATH 环境变量。Windows 用户安装时注意勾选 “Add to PATH”。

3.2 安装包管理工具

npm 会随 Node.js 一起安装。另一个推荐的工具是 pnpm,安装更快、磁盘占用更少:

npm install -g pnpm

3.3 开发工具推荐

  • VS Code
  • 插件:Vue - Official(Volar 的正式版,Vue3 语法提示必备)、ESLint、Prettier

注意:如果你之前装过 Vetur,建议在 Vue3 项目中禁用,因为 Volar 对<script setup>的支持更完整。

3.4 浏览器与调试工具

推荐 Chrome 或 Edge,并安装 Vue.js Devtools 浏览器扩展,用于查看组件树、响应式数据、Pinia 状态和路由信息。这对后续调试组合式 API 非常有用。

4. 创建 Vue3 项目与目录结构分析

4.1 用 Vite 创建 Vue3 项目

官方推荐使用 Vite 创建新项目:

# 方式一:npm npm create vue@latest # 方式二:pnpm pnpm create vue@latest

这个命令会创建基于 Vue3 + Vite 的官方脚手架,创建过程中可以按需选择 TypeScript、Vue Router、Pinia、ESLint 等:

✔ Project name: … vue3-demo ✔ 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 ESLint for code quality? … No / Yes

进入项目并启动:

cd vue3-demo npm install npm run dev

终端会显示本地访问地址,例如http://localhost:5173/。在浏览器打开就能看到默认页面。

如果你之前用的是vue create(Vue CLI),这里建议尽快切到 Vite 创建方式。Vue CLI 已经进入维护期,新项目基本不再推荐。

4.2 Vite 项目目录结构

vue3-demo/ ├── index.html ├── package.json ├── vite.config.js ├── public/ │ └── favicon.ico └── src/ ├── main.js ├── App.vue ├── assets/ └── components/

其中index.html是页面入口,src/main.js负责创建应用实例:

import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app')

App.vue是根组件。Vue3 项目一切皆组件,后续所有页面和通用模块都可以按组件拆分。

5. Vue3 基础语法:模板、指令与响应式

5.1 模板语法

Vue3 模板中可以直接使用{{ }}插值表达式输出数据:

<template> <div> <h1>{{ title }}</h1> <p>count 的值为:{{ count }}</p> </div> </template>

5.2 响应式数据:ref 与 reactive

Vue3 组合式 API 中最常用的两个响应式 API 是refreactive

ref可以定义基本类型和引用类型,在<script setup>中使用:

<script setup> import { ref } from 'vue' const count = ref(0) const increment = () => { count.value++ } </script> <template> <div> <p>当前计数:{{ count }}</p> <button @click="increment">+1</button> </div> </template>

在模板中count会自动解包,不需要写count.value;但在 JavaScript 逻辑中修改时必须使用.value

reactive更适合定义对象的响应式状态:

<script setup> import { reactive } from 'vue' const user = reactive({ name: '张三', age: 20 }) const updateName = () => { user.name = '李四' } </script>

reactive直接访问属性即可,不需要.value。但注意它只能用于对象、数组等引用类型,不能用于基本类型。

5.3 常用指令

  • v-if/v-else-if/v-else:条件渲染
  • v-show:切换 display 显隐
  • v-for:列表渲染
  • v-model:表单双向绑定
  • v-bind(简写:):动态绑定属性
  • v-on(简写@):绑定事件
  • v-html:渲染 HTML 字符串
  • v-once:只渲染一次
  • v-memo:性能优化用,按依赖条件缓存渲染结果

一个典型例子:

<script setup> import { ref } from 'vue' const inputValue = ref('') const list = ref(['Vue', 'React', 'Angular']) </script> <template> <input v-model="inputValue" placeholder="请输入内容" /> <p>你输入的是:{{ inputValue }}</p> <ul> <li v-for="(item, index) in list" :key="index">{{ item }}</li> </ul> </template>

6. 组合式 API 核心:setup、computed 与 watch

6.1 setup 与 script setup

在 Vue3 中,setup是组合式 API 的入口。推荐直接使用<script setup>语法,更简洁,定义的数据和函数默认都能在模板中使用:

<script setup> import { ref } from 'vue' const message = ref('Hello Vue3') </script> <template> <div>{{ message }}</div> </template>

不需要return,代码量明显减少,这也是现在企业项目中最主流的写法。

6.2 computed 计算属性

computed用于派生状态,必须依赖其他响应式数据。典型场景:全选反选、商品总价、搜索过滤。

<script setup> import { ref, computed } from 'vue' const price = ref(100) const count = ref(2) const totalPrice = computed(() => { return price.value * count.value }) </script> <template> <p>单价:{{ price }}</p> <p>数量:{{ count }}</p> <p>总价:{{ totalPrice }}</p> </template>

6.3 watch 与 watchEffect

watch用于监听数据变化并执行副作用,例如监听搜索关键词发请求、监听路由变化、监听表单值变化做校验。

<script setup> import { ref, watch } from 'vue' const keyword = ref('') watch(keyword, (newVal, oldVal) => { console.log('keyword 变化', newVal, oldVal) }) </script>

watchEffect不需要指定监听源,会自动收集依赖:

<script setup> import { ref, watchEffect } from 'vue' const count = ref(0) watchEffect(() => { console.log('count 变化了', count.value) }) </script>

这里有一个 Vue3 面试高频题:computedwatch怎么选?

  • computed侧重计算派生值,必须有返回值,适合依赖响应式数据的同步计算结果。
  • watch侧重监听并执行操作,可以没有返回值,适合异步请求、DOM 操作、日志上报等副作用场景。

7. 组件通信:Props、defineEmits 与 v-model

7.1 父传子:Props

子组件通过defineProps声明接收的属性:

<!-- Child.vue --> <script setup> const props = defineProps({ title: { type: String, default: '' }, count: { type: Number, default: 0 } }) </script> <template> <div> <h3>{{ title }}</h3> <p>count: {{ count }}</p> </div> </template>

父组件传值:

<script setup> import { ref } from 'vue' import Child from './Child.vue' const title = ref('子组件标题') const count = ref(10) </script> <template> <Child :title="title" :count="count" /> </template>

7.2 子传父:defineEmits

这是一个非常高频的 Vue3 面试点。子组件通过defineEmits声明事件,在需要时触发,父组件监听事件并处理:

<!-- Child.vue --> <script setup> const emit = defineEmits(['updateData', 'delete']) const handleClick = () => { emit('updateData', '这是子组件传给父组件的数据') } </script> <template> <button @click="handleClick">点击触发事件</button> </template>

父组件:

<script setup> import Child from './Child.vue' const handleUpdate = (data) => { console.log('父组件接收到的数据:', data) } </script> <template> <Child @update-data="handleUpdate" /> </template>

模板里的事件名update-data会自动匹配emit('updateData'),不需要额外处理。

7.3 v-model 的组件化用法

Vue3 中v-model可以在自定义组件上使用,默认对应modelValue属性和update:modelValue事件:

<!-- CustomInput.vue --> <script setup> const props = defineProps({ modelValue: { type: String, default: '' } }) const emit = defineEmits(['update:modelValue']) const onInput = (e) => { emit('update:modelValue', e.target.value) } </script> <template> <input :value="modelValue" @input="onInput" /> </template>

父组件:

<script setup> import { ref } from 'vue' import CustomInput from './CustomInput.vue' const text = ref('') </script> <template> <CustomInput v-model="text" /> </template>

这种模式在封装表单组件时非常常用。

8. 生命周期与组件挂载顺序

Vue3 组合式 API 中,生命周期钩子带上on前缀:

Vue2 Option APIVue3 Composition API说明
beforeCreate不再需要setup 阶段
created不再需要setup 阶段
beforeMountonBeforeMount挂载前
mountedonMounted挂载后
beforeUpdateonBeforeUpdate更新前
updatedonUpdated更新后
beforeUnmountonBeforeUnmount卸载前
unmountedonUnmounted卸载后

一个基础示例:

<script setup> import { onMounted, onUnmounted } from 'vue' onMounted(() => { console.log('组件挂载完成') }) onUnmounted(() => { console.log('组件卸载,清理定时器/事件监听') }) </script>

建议在onMounted中发初始化请求,在onUnmounted中清理定时器、取消订阅,避免内存泄漏。

9. Vue Router 4:路由配置与动态路由

9.1 基础路由配置

安装 Vue Router 4:

npm install vue-router@4

src/router/index.js中配置:

import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' import About from '../views/About.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', component: About } ] const router = createRouter({ history: createWebHistory(), routes }) export default router

main.js中注册:

import { createApp } from 'vue' import App from './App.vue' import router from './router' const app = createApp(App) app.use(router) app.mount('#app')

9.2 编程式导航与路由跳转不刷新页面

模板中使用<router-link>,逻辑中使用useRouteruseRoute

<script setup> import { useRouter } from 'vue-router' const router = useRouter() const goHome = () => { router.push('/') } const goBack = () => { router.back() } </script>

如果你想跳转到相同路由但参数变化时页面不刷新,可以用watch监听route.paramsroute.query

<script setup> import { useRoute } from 'vue-router' import { watch } from 'vue' const route = useRoute() watch( () => route.params.id, (newId) => { console.log('路由参数变化', newId) } ) </script>

9.3 动态路由与权限路由

后台管理系统中,菜单和页面权限通常由后端返回,前端再动态添加路由。Vue Router 4 提供了router.addRoute方法:

import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/login', component: () => import('../views/Login.vue') } ] }) // 登录成功后根据权限动态添加路由 export function addDynamicRoutes(menus) { menus.forEach(menu => { router.addRoute({ path: menu.path, name: menu.name, component: () => import(`../views/${menu.component}.vue`) }) }) } export default router

动态路由的重点是权限控制和刷新后路由丢失问题,需要配合 Pinia 或本地存储保存路由结构,并在路由守卫中重新添加。

10. Pinia 状态管理与 provide/inject

10.1 Pinia 基本使用

Pinia 是 Vue3 官方推荐的状态管理库,相比 Vuex 更轻量,去掉了mutations,直接在actions中修改状态。

安装:

npm install pinia

创建 store,例如src/stores/user.js

import { defineStore } from 'pinia' export const useUserStore = defineStore('user', { state: () => ({ token: '', userInfo: {} }), getters: { isLogin: (state) => !!state.token }, actions: { setToken(token) { this.token = token }, setUserInfo(info) { this.userInfo = info }, logout() { this.token = '' this.userInfo = {} } } })

在组件中使用:

<script setup> import { useUserStore } from '../stores/user' const userStore = useUserStore() const handleLogin = () => { userStore.setToken('token-xxx') } </script> <template> <p>登录状态:{{ userStore.isLogin }}</p> </template>

10.2 Pinia 模块化与持久化

大型项目中 store 按业务拆分为多个模块,例如user.jsmenu.jsapp.js,使用时分别 import 即可。持久化可以自己写 localStorage 同步,也可以使用pinia-plugin-persistedstate插件。

10.3 provide 与 inject 跨层级通信

跨多级组件传递数据时,不需要逐层传 Props,可以用provideinject

<!-- 父组件 --> <script setup> import { provide, ref } from 'vue' const theme = ref('dark') provide('theme', theme) </script>
<!-- 任意后代组件 --> <script setup> import { inject } from 'vue' const theme = inject('theme') </script>

适合主题切换、全局配置、登录信息等跨层级场景。

11. Vue3 中接口请求与 Axios 封装

11.1 在 setup 中使用 axios

npm install axios

简单请求示例:

<script setup> import { ref, onMounted } from 'vue' import axios from 'axios' const list = ref([]) const loading = ref(false) const fetchList = async () => { loading.value = true try { const res = await axios.get('/api/list') list.value = res.data.data } catch (error) { console.error('请求失败', error) } finally { loading.value = false } } onMounted(() => { fetchList() }) </script>

11.2 封装请求工具与拦截器

企业项目中建议把 axios 封装成独立模块:

// src/utils/request.js import axios from 'axios' import { useUserStore } from '../stores/user' import { ElMessage } from 'element-plus' const request = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || '/api', timeout: 10000 }) // 请求拦截器:自动携带 token request.interceptors.request.use( (config) => { const userStore = useUserStore() if (userStore.token) { config.headers.Authorization = `Bearer ${userStore.token}` } return config }, (error) => { return Promise.reject(error) } ) // 响应拦截器:统一处理错误码 request.interceptors.response.use( (response) => { const res = response.data if (res.code !== 200) { ElMessage.error(res.message || '接口异常') return Promise.reject(new Error(res.message)) } return res }, (error) => { ElMessage.error(error.message || '网络异常') return Promise.reject(error) } ) export default request

在 Vite 中跨域配置可以在vite.config.js中设置 proxy:

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } } })

12. 组件库集成:Element Plus 与 Vant

12.1 Element Plus 后台管理常用组件库

npm install element-plus

完整引入:

// main.js import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import App from './App.vue' const app = createApp(App) app.use(ElementPlus) app.mount('#app')

推荐按需自动导入,配合unplugin-vue-componentsunplugin-auto-import

npm install -D unplugin-vue-components unplugin-auto-import

vite.config.js中配置:

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ vue(), AutoImport({ resolvers: [ElementPlusResolver()] }), Components({ resolvers: [ElementPlusResolver()] }) ] })

12.2 移动端 Vant 组件库

移动端 H5 项目常用 Vant:

npm install vant

页面中使用:

<script setup> import { ref } from 'vue' import { showToast } from 'vant' const text = ref('') const onSubmit = () => { showToast('提交成功') } </script> <template> <van-form @submit="onSubmit"> <van-field v-model="text" name="内容" label="内容" placeholder="请输入" /> <van-button round block type="primary" native-type="submit">提交</van-button> </van-form> </template>

13. Vue3 面试高频考点与实战注意点

结合社区最常见的问题,这里按速查方式整理:

考点核心要点
Vue2 和 Vue3 区别响应式原理(Object.defineProperty -> Proxy)、组合式 API、多根节点、Teleport、Fragments、Vite 构建
refreactive怎么选基本类型用 ref,对象用 reactive;ref 更通用,模板访问更友好
computedwatch区别computed 有缓存且有返回值,watch 执行副作用
defineEmits写法const emit = defineEmits(['updateData']),模板中@update-data监听
动态路由router.addRoute+ 路由守卫 + 权限控制
setup中如何使用 axios直接在<script setup>中调用封装好的请求函数
路由跳转不刷新页面watch监听route.params/route.query变化
Vue3 强制更新v-if加 key 重新渲染、reactive赋值整个对象、nextTick后操作 DOM
JSX 支持Vite 创建项目时选择 JSX,或安装@vitejs/plugin-vue-jsx
自定义指令const vFocus = { mounted(el) { el.focus() } }

14. Vue3 常见问题与排查方法

问题现象可能原因排查方式解决方案
页面打不开开发服务未启动或端口被占用检查终端日志、netstat -ano查看端口换端口npm run dev -- --port 5174或重启
控制台提示 “Cannot read properties of undefined”响应式数据还没赋值就访问嵌套属性打印数据,确认接口返回结构使用可选链?.或默认值兜底
修改了数组内容但页面没更新直接通过索引修改数组在 Vue3 中检查是否用了reactive包裹splice/ 赋值新数组 /ref+ 整个替换
路由切换后组件不刷新动态路由或相同组件复用控制台观察路由参数变化watch监听route参数
组件事件触发后父组件收不到defineEmits没声明检查子组件事件名和模板事件大小写统一用 kebab-case 监听
接口请求跨域Vite 代理未配置检查 Network 面板请求 URL配置server.proxy
打包后白屏静态资源路径错误检查线上 URLvite.config.js设置base: './'
ElMessage 无法正常显示组件样式未引入或自动导入配置问题检查控制台样式报错完整引入 Element Plus 样式

15. Vue3 最佳实践与学习建议

15.1 项目规范建议

  • 目录按业务模块拆分,组件、页面、路由、store、接口分目录管理。
  • API 请求统一封装,每个业务模块对应一个 api 文件。
  • 公共组件放到components下,命名大写开头。
  • 路由使用路由懒加载,页面首次加载更快。
  • store 中只放跨页面共享的全局状态,页面内部状态不放入 Pinia。
  • 所有请求加 loading 状态,异常必须有用户可感知的提示。
  • 批量接口任务注意取消重复请求和超时处理。

15.2 学习方法建议

  • 第一遍先跟着项目把代码敲通,不要纠结响应式原理,先知道怎么写,再理解为什么。
  • 第二遍带着问题回看官方文档,重点看refreactivecomputedwatch、生命周期。
  • 第三遍自己从零开发一个后台管理系统,把组合式 API、路由、Pinia、Axios 全部用上。
  • 遇到报错先看控制台,再查官方文档,最后再搜索,不要一上来就复制网上代码。

15.3 版本与依赖注意点

  • Node.js 版本不要太老,建议 18+。
  • npm install后如果出现 lock 文件版本冲突,优先删除node_modules和 lock 文件后重装。
  • 尽量保持 Vue、Vite、Vue Router、Pinia 均为最新稳定版本。
  • 遇到新项目不要混合 Vue2 和 Vue3 的写法,Vue.extendfiltersVue.use这种 Vue2 写法在 Vue3 中不可用。

16. 总结

Vue3 学习路径并不复杂:先搭环境,再写基础语法,然后进入组件化开发和组合式 API,最后用 Vue Router、Pinia、Axios 和组件库串起一个完整项目。很多人学不会,不是 Vue3 难,而是跳过了“先抄后懂”的过程,直接啃原理。

如果你是从 Vue2 过来的,重点只需要搞清楚三件事:setup代替了大部分 Options API 写法、refreactive替代了data、响应式原理从 defineProperty 换成了 Proxy。剩下的模板语法和组件通信思路是相通的。

如果是零基础,建议先确认自己是否掌握了 JavaScript 的 ES6 语法,环境装好之后,把本文中的代码示例全部在本地跑一遍。前端开发的核心能力是“能写出来”,不是“看起来会了”。

下一步根据自己的方向继续扩展:做后台系统就深入 Element Plus 和权限动态路由,做移动端就看看 Vant 和 uni-app,做可视化就学 ECharts 配合 Vue3 使用。这套路线走完,你已经可以独立开发完整的前端项目了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询