Vue3零基础入门到实战:完整学习路线与核心API解析 2026 年了Vue3 早就不是“要不要学”的问题而是“怎么学才最省时间”的问题。如果你正打算零基础入门 Web 前端又不想被网上一堆碎片化教程绕晕这篇可以按顺序从头看到尾。本文会用一条完整的路线带你从环境安装、项目创建、组合式 API、组件通信、路由、Pinia一直走到项目实战和面试题。Vue3 当前最值得关注的是组合式 APIComposition API和script setup语法它们让组件逻辑更集中、复用更简单。同时 Vite 构建工具的普及让冷启动和热更新变得非常快开发体验比 Vue2 Webpack 时代提升明显。文章会按住 ESC 拆解关键知识点并给出大量可直接复制的代码示例。如果你已经在用 Vue2想了解 Vue2 和 Vue3 的核心差异或者是刚学会 HTML/CSS/JavaScript、准备系统学习 Vue3 的小白这篇都适合。为了让你学完能真正上手文章还会穿插高频 Vue3 面试题computed和watch怎么选、defineEmits怎么用、动态路由怎么配置等等。1. Vue3 核心能力速览在学习之前先用一张表搞清楚 Vue3 的生态现状和基本诉求维度说明框架类型渐进式 JavaScript 前端框架主打组件化和响应式 UI当前主流版本Vue 3.x搭配 Vite 构建工具使用核心语法组合式 APIComposition 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 一条主线学习路径推荐按下面的顺序推进每步都以“能写出来”为验收标准掌握 JavaScript ES6 语法解构赋值、箭头函数、Promise、async/await、模块化。安装 Node.js 和包管理工具学会创建 Vue3 项目。理解 Vue3 模板语法插值、指令、事件、表单双向绑定。掌握响应式核心ref、reactive、computed、watch。掌握组件化组件定义、Props、事件、插槽、v-model。掌握组合式 APIsetup、script setup、自定义 Hook。学习 Vue Router 4路由配置、嵌套路由、动态路由、导航守卫。学习 Pinia状态管理、模块拆分、持久化。结合 Element Plus / Vant 开发完整页面。接口请求封装 Axios 拦截器 环境变量配置。用 Vite 构建部署输出静态文件到服务器。这套路径在速成时也是最稳的每一步都有可以运行的结果不容易产生“学了不会用”的挫败感。3. 开发环境准备与前置条件3.1 安装 Node.jsVue3 项目依赖 Node.js建议直接安装 LTS 长期支持版本。安装完成后打开终端Windows 用 PowerShell / CMDmacOS 用 Terminal检查版本node -v npm -v如果提示node不是内部或外部命令说明没装好或没配置 PATH 环境变量。Windows 用户安装时注意勾选 “Add to PATH”。3.2 安装包管理工具npm 会随 Node.js 一起安装。另一个推荐的工具是 pnpm安装更快、磁盘占用更少npm install -g pnpm3.3 开发工具推荐VS Code插件Vue - OfficialVolar 的正式版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 vuelatest # 方式二pnpm pnpm create vuelatest这个命令会创建基于 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 createVue 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 pcount 的值为{{ count }}/p /div /template5.2 响应式数据ref 与 reactiveVue3 组合式 API 中最常用的两个响应式 API 是ref和reactive。ref可以定义基本类型和引用类型在script setup中使用script setup import { ref } from vue const count ref(0) const increment () { count.value } /script template div p当前计数{{ count }}/p button clickincrement1/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 李四 } /scriptreactive直接访问属性即可不需要.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-modelinputValue placeholder请输入内容 / p你输入的是{{ inputValue }}/p ul li v-for(item, index) in list :keyindex{{ item }}/li /ul /template6. 组合式 API 核心setup、computed 与 watch6.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 /template6.3 watch 与 watchEffectwatch用于监听数据变化并执行副作用例如监听搜索关键词发请求、监听路由变化、监听表单值变化做校验。script setup import { ref, watch } from vue const keyword ref() watch(keyword, (newVal, oldVal) { console.log(keyword 变化, newVal, oldVal) }) /scriptwatchEffect不需要指定监听源会自动收集依赖script setup import { ref, watchEffect } from vue const count ref(0) watchEffect(() { console.log(count 变化了, count.value) }) /script这里有一个 Vue3 面试高频题computed和watch怎么选computed侧重计算派生值必须有返回值适合依赖响应式数据的同步计算结果。watch侧重监听并执行操作可以没有返回值适合异步请求、DOM 操作、日志上报等副作用场景。7. 组件通信Props、defineEmits 与 v-model7.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 pcount: {{ 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 :titletitle :countcount / /template7.2 子传父defineEmits这是一个非常高频的 Vue3 面试点。子组件通过defineEmits声明事件在需要时触发父组件监听事件并处理!-- Child.vue -- script setup const emit defineEmits([updateData, delete]) const handleClick () { emit(updateData, 这是子组件传给父组件的数据) } /script template button clickhandleClick点击触发事件/button /template父组件script setup import Child from ./Child.vue const handleUpdate (data) { console.log(父组件接收到的数据, data) } /script template Child update-datahandleUpdate / /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 :valuemodelValue inputonInput / /template父组件script setup import { ref } from vue import CustomInput from ./CustomInput.vue const text ref() /script template CustomInput v-modeltext / /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 4npm install vue-router4在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逻辑中使用useRouter或useRoutescript setup import { useRouter } from vue-router const router useRouter() const goHome () { router.push(/) } const goBack () { router.back() } /script如果你想跳转到相同路由但参数变化时页面不刷新可以用watch监听route.params或route.queryscript setup import { useRoute } from vue-router import { watch } from vue const route useRoute() watch( () route.params.id, (newId) { console.log(路由参数变化, newId) } ) /script9.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/inject10.1 Pinia 基本使用Pinia 是 Vue3 官方推荐的状态管理库相比 Vuex 更轻量去掉了mutations直接在actions中修改状态。安装npm install pinia创建 store例如src/stores/user.jsimport { 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 /template10.2 Pinia 模块化与持久化大型项目中 store 按业务拆分为多个模块例如user.js、menu.js、app.js使用时分别 import 即可。持久化可以自己写 localStorage 同步也可以使用pinia-plugin-persistedstate插件。10.3 provide 与 inject 跨层级通信跨多级组件传递数据时不需要逐层传 Props可以用provide和inject!-- 父组件 -- 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 中使用 axiosnpm 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() }) /script11.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中设置 proxyimport { 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 与 Vant12.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-components和unplugin-auto-importnpm 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 项目常用 Vantnpm install vant页面中使用script setup import { ref } from vue import { showToast } from vant const text ref() const onSubmit () { showToast(提交成功) } /script template van-form submitonSubmit van-field v-modeltext name内容 label内容 placeholder请输入 / van-button round block typeprimary native-typesubmit提交/van-button /van-form /template13. Vue3 面试高频考点与实战注意点结合社区最常见的问题这里按速查方式整理考点核心要点Vue2 和 Vue3 区别响应式原理Object.defineProperty - Proxy、组合式 API、多根节点、Teleport、Fragments、Vite 构建ref和reactive怎么选基本类型用 ref对象用 reactiveref 更通用模板访问更友好computed和watch区别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后操作 DOMJSX 支持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 学习方法建议第一遍先跟着项目把代码敲通不要纠结响应式原理先知道怎么写再理解为什么。第二遍带着问题回看官方文档重点看ref、reactive、computed、watch、生命周期。第三遍自己从零开发一个后台管理系统把组合式 API、路由、Pinia、Axios 全部用上。遇到报错先看控制台再查官方文档最后再搜索不要一上来就复制网上代码。15.3 版本与依赖注意点Node.js 版本不要太老建议 18。npm install后如果出现 lock 文件版本冲突优先删除node_modules和 lock 文件后重装。尽量保持 Vue、Vite、Vue Router、Pinia 均为最新稳定版本。遇到新项目不要混合 Vue2 和 Vue3 的写法Vue.extend、filters、Vue.use这种 Vue2 写法在 Vue3 中不可用。16. 总结Vue3 学习路径并不复杂先搭环境再写基础语法然后进入组件化开发和组合式 API最后用 Vue Router、Pinia、Axios 和组件库串起一个完整项目。很多人学不会不是 Vue3 难而是跳过了“先抄后懂”的过程直接啃原理。如果你是从 Vue2 过来的重点只需要搞清楚三件事setup代替了大部分 Options API 写法、ref和reactive替代了data、响应式原理从 defineProperty 换成了 Proxy。剩下的模板语法和组件通信思路是相通的。如果是零基础建议先确认自己是否掌握了 JavaScript 的 ES6 语法环境装好之后把本文中的代码示例全部在本地跑一遍。前端开发的核心能力是“能写出来”不是“看起来会了”。下一步根据自己的方向继续扩展做后台系统就深入 Element Plus 和权限动态路由做移动端就看看 Vant 和 uni-app做可视化就学 ECharts 配合 Vue3 使用。这套路线走完你已经可以独立开发完整的前端项目了。