资讯动态

Vue3快速入门:组合式API与script setup实战解析

发布时间:2026/10/13 14:33:58 来源:尧图企业网站定制
最近接到不少私信都是问Vue3该怎么入门、和Vue2到底差在哪、学起来会不会很吃力之类的问题。我也带过一些新人上手Vue3今天就基于自己的项目实操经验把Vue3快速入门这条路上最该关注的几个核心点完整讲清楚。这篇内容不会扯太多用不上的概念一切以“你看完能马上开始写代码”为标准不管是零基础、刚从Vue2转过来还是React想看看Vue3是怎么回事都可以直接参考。先说个结论Vue3真正让你觉得“值得升级”的不是那点性能提升而是组合式API带来的代码组织方式变化。它把过去散落在data、methods、computed里的逻辑按功能收拢到一起代码读起来更像是在讲一个故事。这篇博文会从环境搭建、组合式API核心、组件通信、实际开发细节、常见问题几个维度逐个拆解。1. Vue3整体设计和思路拆解为什么它值得学1.1 Vue2时代真正让人头疼的问题我在Vue2上写项目写了很久坦白说维护成本相当高。一个非常典型的场景做一个用户列表页面里面涉及请求用户数据、筛选、分页、弹窗编辑。在Vue2的选项式API里数据部分有list、keyword、page、loading这些methods里有fetchList、handleSearch、handlePageChange、openDialogcomputed里可能还有filteredList。这还只是一个页面的逻辑一旦页面复杂起来data和methods里的内容会越来越多但彼此在代码结构上却是“按类型”排列而非“按功能”排列的。维护这种代码时你得反复在data、computed、methods、watch之间跳来跳去才能把一条完整的业务逻辑串起来。比如“搜索用户”这个功能触发点在methods依赖的数据在data派生数据在computed副作用在watch——四个地方来回切换。更要命的是mixin复用项目一复杂mixin里数据和方法的来源变得非常混沌出了问题根本不知道是哪个mixin里的逻辑导致的。1.2 Vue3用组合式API解决了什么Vue3的Composition API思路和Vue2完全不一样。它不再强制你把代码按data、methods、computed这样的类型去归档而是让你按功能去组织。还是用户列表页面的例子你可以把搜索用户相关的一组数据ref和函数放在一起把分页相关的一组放在一起把弹窗编辑相关的一组放在一起。这样每个功能模块的代码在物理位置上靠拢阅读和维护的思路就顺了很多。再加上setup函数或者script setup语法糖配合hooks函数类似自定义hook的抽取很多跨页面的公共逻辑可以像函数一样被复用。这一点对中大型项目来说价值很大代码复用不再依赖mixin那套隐式合并机制而是变成一种显式的函数调用关系类型推导和IDE智能提示都友好得多。1.3 选择Vue3的几个现实理由现在新项目如果还不选择Vue3我觉得是有点亏的。首先是生态层面社区里优秀的组件库比如Element Plus、Naive UI都是围绕Vue3开发的且新特性更新节奏很快。其次是技术栈层面Vue3对TypeScript的支持从底层就重新设计了这与前端工程化趋势一致你可以在Vue3里非常自然地和TS配合开发而Vue2的TS支持可以说是“硬凑”的。当然中文文档的质量也很重要。Vue3的官方文档重写过后结构清晰、示例周全对新手相当友好。再加上Vue DevTools对Vue3调试做了大量优化调试体验整体上了一个台阶。基于这些原因如果你是刚接触Vue的新人直接学Vue3是更理性的选择不必再在Vue2上花太多时间。2. 搭建你的第一个Vue3项目环境准备与工程结构2.1 环境要求Node.js版本怎么选在开始之前先把环境整明白。Vue3的构建工具链Vite对Node.js版本有要求一般建议用Node.js 18及以上版本我自己用的是18.x LTS运行很稳定。你可以在终端里执行node -v查看当前版本如果版本过低建议先升级到长期支持版本避免后续装依赖时出现各种奇奇怪怪的报错。包管理器方面npm是Node自带的直接用如果安装速度慢也可以换成pnpm或者yarn。npm create vuelatest命令会自动检测并提示你选择包管理器所以这个环节不用纠结太多。2.2 使用脚手架创建项目创建Vue3项目最简单的方式是使用官方脚手架create-vue它底层已经集成了Vite。打开终端执行npm create vuelatest执行后会出现交互式问答会让你选择是否启用TypeScript、JSX、Vue Router、Pinia、ESLint、Prettier等。对初学者我建议第一轮先选No用最简单的JavaScript版本跑通流程。等理解了Vue3的核心概念再回过头在项目里加入TypeScript、Pinia这些就不会被一堆配置干扰判断。选完之后脚手架会生成项目文件并且自动安装依赖。启动开发服务器的命令如下npm install npm run dev命令行会输出一个本地地址比如http://localhost:5173浏览器打开就能看到Vue3默认的欢迎页面。2.3 项目目录结构逐一看懂Vite创建的项目结构很干净核心内容都集中在src目录里。初次看到这个结构不要慌我逐个说一下index.html是真正的页面入口Vite会把src/main.js编译后注入到这里。src/main.js负责创建Vue应用实例并挂载到页面上。src/App.vue是根组件它类似于整棵组件树的根节点。src/components目录用来放子组件。src/assets目录通常放静态资源比如图片、全局样式。.vue文件是Vue的单文件组件里面通常包含template结构、script逻辑、style样式三个部分。Vue3里script部分还可以开启setup语法糖写法会更简洁。2.4 跑通第一个页面的心路历程我自己第一次跑通Vue3页面时其实是在App.vue里改了一行文本然后看页面热更新也是在这个瞬间理解了Vite的HMR热模块替换有多顺畅。改动保存后浏览器几乎是瞬间反映出来这种即时反馈对学习阶段的信心建立很关键。建议你在这个阶段做的事很简单把默认的演示代码删掉在App.vue里写一个最简单的计数器按钮用ref定义一个变量再把点击事件和模板绑定起来。能跑通这个流程后你就已经跨过了Vue3最基础也是最重要的一步——理解响应式变量与模板渲染之间的关系。3. 组合式API核心细节与实操要点Vue3的魂3.1 ref和reactive响应式数据的两种定义方式组合式API里最核心的入门点是两个函数ref和reactive。它们都是用来创建响应式数据的但适用场景不同。ref可以传入任意类型的值包括基本类型、对象、数组。但需要注意的是在使用ref时脚本中访问值必须通过.value比如count.value而在模板中则不需要写.valueVue会自动解包。很多新手会在这里卡住在JavaScript里忘写.value导致读到undefined这是Vue3入门里第一个容易踩的坑。reactive则只能接收对象它返回的是一个深层响应式代理对象直接操作对象的属性即可。它的优点是写法与普通对象一致没有.value的负担但限制也明显——不能直接重新赋值整个对象否则会丢失响应式连接。从我个人经验来看建议在开发中优先使用ref。原因很简单ref在赋值和解构时不容易丢失响应式也更容易在函数之间传递。reactive的对象在解构或者直接替换整个对象时非常容易踩坑对新手并不友好。3.2 computed计算属性别把运算逻辑堆在模板里模板里如果直接写复杂的运算表达式过一段时间你会发现模板变得很难读。Vue3的computed可以把依赖响应式数据的派生状态声明出来并且它带有缓存性质只有依赖项变化时才会重新计算性能上更优。用法示例如下import { ref, computed } from vue const price ref(100) const count ref(2) const total computed(() price.value * count.value)我在实际开发中的体会是计算属性适合用来表达“由现有数据推导出的新数据”。它让模板里的内容保持纯粹也方便单独测试。3.3 watch和watchEffect侦听数据变化watch用来监听一个或多个响应式数据源当数据发生变化时执行回调。它适合处理一些副作用比如数据变化后重新请求接口、同步到localStorage、或者更新其他关联数据。需要注意如果要监听reactive对象内部的某个属性必须用getter函数的方式传值比如watch(() obj.name, ...)。watchEffect和watch不同它会自动追踪回调函数里用到的所有响应式依赖只要依赖发生变化就会重新执行。它的好处是“不用显式声明监听谁”代码更简洁但副作用也同样明显只要依赖有变化就会执行你可能需要额外判断是否真的需要做某些操作。从实际使用上看watch适合精确控制“监听谁再做什么”watchEffect适合在一些初始化逻辑和执行时机比较灵活的场合。3.4 生命周期钩子用函数式的写法替代选项式Vue3组合式API里的生命周期钩子不再是选项式API里的created、mounted这种写法而是使用onMounted、onUpdated、onUnmounted等函数并且需要在setup中导入后使用。它们的执行时机会让人产生疑惑尤其是created的生命周期被setup本身替代了在setup中直接写的代码就相当于过去的created阶段。例如import { onMounted } from vue onMounted(() { // 组件挂载完成后执行 fetchData() })这些钩子在script setup语法糖里使用时不需要额外配置直接导入调用即可。有一点要记住onMounted里拿到的DOM和组件实例是在组件完成挂载之后的状态适合做依赖DOM尺寸的初始化、请求接口这类操作。3.5 Vue3的响应式原理从defineProperty到ProxyVue2的响应式是通过Object.defineProperty去改写对象属性的getter和setter实现的但这种方式有几个天生的缺陷无法监听新增属性、无法监听删除属性、对数组索引和length变化也监听得不完整。所以在Vue2里你常常需要调用Vue.set或者this.$set这种补救方法。Vue3把整个底层换成了ES6的Proxy。Proxy可以拦截整个对象的读写操作不管是新增属性、删除属性还是读取某个不存在的属性都能被拦截到。这意味着响应式数据的行为更加自然代码里不再需要额外的补丁函数。同时Vue3在编译阶段会对模板中的动态节点做标记PatchFlags配合虚拟DOM的diff算法优化渲染性能也有明显提升。用生活化的比喻来说Vue2的响应式像你请了一个门卫只看得到这栋楼里已有的房间新增房间他管不了而Vue3的Proxy像是给整栋楼装了一套智能门禁系统任何房间的进出、增加、拆除都会被系统记录。这个底层差异也直接决定了Vue3的响应式在开发体验上更省心。4. 模板语法与组件通信写页面绕不开的实操细节4.1 模板语法核心插值、指令、事件绑定Vue3模板语法大部分与Vue2一致双大括号插值{{ }}用于输出文本内容v-bind用于绑定属性v-on用于绑定事件。v-bind可以简写为冒号v-on可以简写为符号比如:src绑定图片地址、click绑定点击事件。这些简写在实际开发中随处可见建议从一开始就直接用简写阅读代码更清爽。v-for和v-if在同一个元素上不建议一起使用。原因是v-for的优先级更高v-if无法访问v-for作用域内的变量而且同时使用会带来不必要的性能消耗。在实际项目中遇到这个需求时我一般会用计算属性先过滤列表再遍历渲染。另外列表渲染时一定要绑定稳定的key不要用index作为key否则列表顺序变化可能引发渲染错位或状态复用错误。4.2 props和emit父子组件通信的经典通道父子组件通信是Vue开发的基础。父组件通过props向子组件传数据子组件通过emit向父组件发送事件。在Vue3的script setup语法糖中props需要用defineProps来声明事件需要用defineEmits来声明。它们是编译时期的宏不需要手动导入。举例!-- 父组件 -- Child :msgmessage updatehandleUpdate / !-- 子组件 -- script setup const props defineProps({ msg: String }) const emit defineEmits([update]) function sendUpdate() { emit(update, new value) } /scriptprops是单向数据流的子组件不能直接修改props的值。如果你确实需要修改父组件传来的数据一种方式是让父组件通过v-model传响应式数据进来配合子组件触发更新事件实现数据同步另一种方式是把值复制到子组件的本地ref中再处理。强制直接改props不仅会触发Vue的警告还会让代码里的数据流向变得不可追踪排查问题难度大增。4.3 v-model表单与组件的双向绑定v-model在Vue3里本质上还是语法糖用在原生表单元素上很好理解比如input的value和input事件。用在自定义组件上时它等价于传入modelValue属性并监听update:modelValue事件。这个设计比Vue2灵活很多你可以在一个组件上使用多个v-model甚至自定义v-model的参数名和修饰符。举个例子自定义一个弹窗组件希望外部用v-model控制显示隐藏那就没必要显式传visible和监听close事件直接Dialog v-modeldialogVisible /子组件内部通过props接收modelValue通过emit(update:modelValue, false)来更新状态。这在写组件库或者复用性强的公共组件时能省掉很多冗余代码。4.4 provide和inject跨层级传值的另一把钥匙有些场景下父组件和子组件之间层级很深比如从页面到卡片再到按钮中间还有好几个中间层。如果每一层都用props去传不仅写法啰嗦还容易在重构时漏掉某个环节。Vue3的provide和inject可以让我们在祖先组件提供数据在任意深度的后代组件中直接注入使用。不过要留意provide/inject适合传“相对稳定”的内容比如主题配置、用户信息、某个全局状态。它不像props那样有明确的显式接口过度使用会让组件的依赖关系变得隐晦。我在项目里的习惯是跨两层以上的公共数据才用provide/inject一两层以内的常规传参还是老老实实走props。5. script setup语法糖和组合式函数提升开发效率的关键5.1 为什么推荐优先使用script setupscript setup是Vue3.2版本引入的语法糖它的出现让组合式API的代码变得更加简洁。有了它你不用显式写setup函数也不用把所有变量方法都return出去才能在模板中使用在script setup里声明的变量、函数、组件、computed、watch模板可以直接用这让组件代码的骨架精简了不少。引入组件也不需要注册步骤import进来就能在模板里直接使用。配合defineProps、defineEmits这些编译宏整个组件写起来更接近“一个普通的JavaScript模块”的体验。我自己在项目里已经完全习惯了这种写法再回到setup函数去写手动return的代码确实会觉得麻烦。5.2 组合式函数Hooks把逻辑抽出来复用组合式API最大的优势之一是逻辑复用。假设你有一个“使用鼠标追踪位置”的需求在多个组件里都要用你可以把它抽成一个自定义Hook比如useMousePosition。这个Hook内部封装了需要响应的坐标、事件绑定和生命周期清理逻辑。// useMousePosition.js import { ref, onMounted, onUnmounted } from vue export function useMousePosition() { const x ref(0) const y ref(0) function update(event) { x.value event.clientX y.value event.clientY } onMounted(() window.addEventListener(mousemove, update)) onUnmounted(() window.removeEventListener(mousemove, update)) return { x, y } }这样一来任何组件需要鼠标坐标时只需要调用这个函数并解构出x和y即可。这种复用方式对比mixin的优势很明显调用关系清晰、响应式数据来源明确代码排查时不用再猜数据是哪来的。5.3 路由和状态管理Vue Router 4与Pinia快速上手Vue3项目里引入Vue Router 4创建路由实例时会用到createRouter和createWebHistory。与Vue2不同的是Router的创建方式改成了API调用的模式。在实际使用时页面跳转和参数传递方式与Vue2差异不大学习成本可控。状态管理方面我建议直接用Pinia而不是Vuex。Pinia的API更加简洁去掉了mutations的概念state和actions直接平铺写起来很像在操作普通对象。它对TypeScript的支持也比Vuex好得多是官方推荐的状态管理库。在一个Vue3项目里引入Pinia只需要createPinia后挂载到应用实例上即可。6. 常见问题与排查技巧实录踩过的坑和避坑建议6.1 响应式丢失为什么我改了数据页面没更新这个场景我见过特别多次。常见原因有几种直接把整个reactive对象重新赋值了比如obj newObj这会导致响应式连接断开或者把一个reactive对象解构出来单独使用解构出的属性会丧失响应式。这两个问题本质都是因为丢失了与响应式对象的引用关系。解决办法是改用ref或者用ref替换整个对象又或者在解构时使用toRefs把属性转为ref再使用。6.2 watch为什么没触发watch不触发多半是监听的数据源写法不对。比如你直接监听reactive对象的某个属性传了obj.name这种形式Vue会警告并且不生效必须用getter函数包一层watch(() obj.name, ...)。另外如果监听的是ref定义的基本类型变量直接传ref变量名即可不需要加.value。还有一点容易忽略的是watch默认不会深度监听对象的内部变化。如果你要监听reactive对象内部任意属性的变化需要显式设置deep: true但深度监听本身比较消耗性能使用时要权衡一下。6.3 生命周期执行顺序疑惑不少刚从Vue2转过来的人会问created没有了初始化逻辑写在哪答案很简单script setup里直接写的代码行为上就是在组件创建阶段执行。如果你要操作DOM那还是要写在onMounted里。如果在onMounted里请求接口然后又希望根据props变化重新请求还需要搭配watch来监听props而不是把所有逻辑都堆在生命周期里。6.4 关于项目优化和新人的一些建议Vue3的性能底子不错但具体项目里还需要注意细节。列表渲染记得写key大型列表可以用v-memo优化渲染组件的状态不要一股脑全放到全局状态管理里很多组件内部状态用ref或reactive维护就够了。路由页面级别做懒加载也就是动态import组件避免首屏bundle过大。对刚刚上手Vue3的话我的建议是不要急着去抄各种复杂的项目模板。先把ref、reactive、computed、watch、props、emit这几个最基本的API用熟然后自己动手写一个两三页面的小项目比如待办事项、个人记账本。写完这个小项目后再接触脚手架里的TypeScript、Pinia、Router这些相对进阶的部分循序渐进会稳得多。另外Vue3的官方文档值得从头到尾读一遍它的“基础”章节把许多原理性的问题都讲得很透。工作中遇到问题优先去官方文档搜其次再查社区分享这些一线经验心得往往能帮你少走很多弯路。我在实际使用中也是这么过来的遇到问题不怕耐心读文档、动手验证基本都能找到答案。希望这篇内容能让你对Vue3体系有一个整体把握后续在自己的项目里大胆用起来踩过几个坑之后你自然会发现Vue3这套体系写起来是真的顺畅。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑