Vue3 setup是什么?和Options API比有啥优势?新手用它难不难?
setup的核心身份其实是Vue3组件的统一入口+数据逻辑聚合地,你可以把它想象成组件的“大脑前室”——所有需要用的响应式数据、计算属性、方法、生命周期钩子、自定义事件处理,甚至组件内外的状态共享逻辑,都得先在这里“报到”或者“生成”,然后再“分配”给组件的模板、子组件这些部分去用。
先搞懂setup的基本使用规则
很多人刚接触setup会懵,它的写法和之前熟悉的Options API完全不一样,得先把几个硬规则记牢,不然写两行就报错。 第一个规则是执行时机,这也是最容易踩坑的点,setup是在组件实例创建之前、数据观察(data/props响应式绑定)之后、beforeCreate钩子之前就执行的,这意味着什么?你在setup里不能用this!因为this指向的组件实例还没出生呢,那之前Options API里的this.$refs、this.$emit、this.$store这些怎么办?别急,Vue3都给你准备了对应的工具函数或者组合式API。 第二个规则是参数接收,setup有两个可选参数:props和context,第一个props是响应式的,不过别随便解构它,解构之后会丢失响应性,如果非要解构可以用toRefs或者toRef包装,第二个context是一个普通的JavaScript对象,里面有attrs、slots、emit、expose这四个东西,都是非响应式的,所以放心大胆解构用就行。 第三个规则是返回值处理,setup可以返回两种东西:要么是一个JavaScript对象,里面的属性和方法会自动暴露给组件的模板和Options API的其他选项(不过现在Options API很少和setup混用了,除非是老项目改造);要么是一个渲染函数(h函数),用来直接生成虚拟DOM,这种情况一般用于复杂的自定义组件封装,新手暂时不用碰。
聊透setup比Options API强的地方
很多老Vue2开发者一开始抵触setup,觉得Options API分data、methods、computed、watch这些块,逻辑按类型分挺清楚的啊,为啥要换?等你做过稍微大一点的项目,比如一个有收藏、评论、点赞、分享四个功能的文章详情页组件,你就懂setup的香了。 第一个优势是逻辑关注点聚合,不会出现代码“横跳”的情况,比如在Options API里,收藏功能的响应式数据(isCollected、collectedCount)在data里,切换收藏状态的方法(toggleCollect)在methods里,监听isCollected变化发送请求的逻辑在watch里,显示收藏按钮文本的计算属性(collectBtnText)在computed里,这四个部分的代码可能隔了好几十行,甚至上百行,维护的时候得来回翻,但在setup里,你可以把这四个部分的代码全放在一起,甚至可以封装成一个叫useCollect的小函数,以后别的详情页组件想用收藏功能,直接把这个函数复制过去(或者抽成hooks文件导入)就行,不用再一个个找对应的块。 第二个优势是更好的TypeScript支持,Vue3本身就是用TypeScript重写的,setup天生就是为TS设计的,在Options API里用TS,你得写一堆复杂的装饰器或者接口声明,代码看起来很臃肿,而且类型推导经常出问题,比如computed的返回值类型有时候得自己手动指定,但在setup里,所有的响应式数据、方法、计算属性的类型都能自动推导,不用写太多额外的TS代码,开发体验提升了不止一个档次。 第三个优势是更灵活的代码复用方式,之前Vue2复用逻辑主要靠mixin,mixin这东西简直是“代码毒药”,用多了之后你根本不知道某个数据或者方法是从哪个mixin里来的,而且多个mixin里的同名数据或者方法还会互相覆盖,排查 bug 能排查到怀疑人生,setup搭配组合式API(也就是那些use开头的工具函数,比如useState、useEffect的Vue版本——ref、reactive、computed、watch、onMounted这些),可以把复用的逻辑抽成独立的hooks文件,这些hooks有明确的输入输出,不会污染全局,也不会有命名冲突的问题,代码的可维护性和复用性都大大提高了。
新手用setup难不难?过来人给你吃颗定心丸
其实新手上手setup比想象中简单多了,甚至可能比先学Options API再转setup更快,因为你不需要先记一大堆分块的规则,只需要掌握几个核心的组合式API就行。 你不用一开始就把所有的组合式API都学完,入门只需要记住ref、reactive、computed、watch、onMounted、emit这六个就够了,日常开发80%的场景都能覆盖,ref用来定义基本类型的响应式数据,reactive用来定义对象或者数组类型的响应式数据,computed用来做计算属性,watch用来监听数据变化,onMounted是最常用的生命周期钩子,用来做页面加载后的初始化操作,emit用来触发自定义事件向父组件传值。 现在Vue的官方脚手架create-vue和Vite默认都是用setup语法糖的,setup语法糖比普通的setup写法更简洁,连return都不用写了,所有在script setup标签里定义的顶层变量和函数都会自动暴露给模板,比如普通的setup写法里你得return { count, addCount },但在setup语法糖里直接写let count = ref(0); const addCount = () => count.value++就行,代码看起来干净多了。 官方文档写得非常详细,而且有专门的新手教程,还有在线的代码编辑器可以直接试,看不懂就敲两行代码试试,比光看文字强10倍,除此之外,B站、知乎、掘金上也有很多新手友好的教程,跟着做一两个小项目,比如TodoList、天气查询、个人博客,很快就能上手了。
给新手的几个setup入门小建议
第一个建议是先学ref再学reactive,虽然reactive看起来更方便,不用加.value,但它的局限性也更大,比如不能直接赋值替换整个对象,否则会丢失响应性,而ref就没有这个问题,不管是基本类型还是引用类型都能用,虽然引用类型需要加.value才能访问内部属性,但新手刚开始可能更容易接受这种“必须加标记”的明确感。 第二个建议是尽量用setup语法糖,不要一开始就用普通的setup写法,语法糖能帮你省很多事,而且代码更简洁,看起来更舒服,等你熟悉了setup语法糖之后,再去了解普通的setup写法也不迟。 第三个建议是不要排斥老项目改造用的Options API和setup混用,虽然官方推荐新项目用setup,但老项目不可能一下子全改完,混合用的时候要注意:Options API里的this可以访问到setup返回的属性和方法,但setup里不能访问Options API里的东西;尽量把新功能的逻辑放在setup里,老功能的逻辑暂时不动,这样可以降低改造的风险。 第四个建议是多写hooks,哪怕是很小的逻辑,比如表单验证、防抖节流,都可以试着封装成hooks,这样不仅能锻炼你的逻辑抽象能力,还能积累自己的代码库,以后开发新项目的时候就能直接用了。
举个简单的例子,让你直观感受setup的写法
就拿刚才说的TodoList为例吧,我们用setup语法糖写一个添加、删除、标记完成/未完成的小TodoList。 我们用ref定义todos数组和inputValue输入框的值,todos数组里的每一项是一个对象,包含id、text、completed三个属性,id可以用Date.now()生成,text是输入框的值,completed默认是false。 我们定义添加Todo的方法addTodo,先判断inputValue有没有值,如果没有就return,如果有就往todos数组里push一个新的Todo对象,然后清空inputValue。 定义删除Todo的方法deleteTodo,接收一个id参数,用filter方法把todos数组里id不等于这个参数的项保留下来。 再定义切换Todo完成状态的方法toggleCompleted,接收一个id参数,用find方法找到对应的Todo对象,然后把它的completed属性取反。 我们写模板,用v-for循环渲染todos数组,用v-bind绑定input的value和class(比如完成的Todo加个删除线),用v-on绑定input的input事件、添加按钮的click事件、删除按钮的click事件、Todo文本的click事件。 整个代码看起来非常简洁,逻辑也很清晰,所有的代码都集中在script setup标签和template标签里,不用来回翻不同的块。
总结一下
setup是Vue3的核心特性之一,它是组件的统一入口和数据逻辑聚合地,和Options API比有逻辑关注点聚合、更好的TypeScript支持、更灵活的代码复用方式这三个优势,新手上手其实并不难,只需要掌握几个核心的组合式API,尽量用setup语法糖,多写多练,很快就能熟练掌握,如果你正在学习Vue3,或者准备从Vue2转Vue3,一定要好好学setup,它会让你的Vue开发效率和代码质量都提升一个档次。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网


