Vue3上手难不难?跟Vue2比我先学哪个更合适?
上手难度是很多刚接触前端框架或者从Vue2转过来的同学第一时间会问的问题,这个答案得拆成两种情况——完全零基础和有Vue2基础。
完全零基础的同学其实不用太慌,Vue3的基础语法比如模板语法、双向绑定、计算属性这些核心,和Vue2是一脉相承的,而且官方的Vue3官方文档现在优化得比之前友好太多,分了基础篇、进阶篇、生态篇,还有专门的新手引导,跟着走一遍搭建项目、写计数器、做简单的待办清单,两三天就能摸到Vue3的核心逻辑,后续慢慢深入组件、组合式API这些就行。
那有Vue2基础的同学呢?直接转Vue3完全没问题,甚至效率会很高,因为大部分旧知识都能用,只需要花时间掌握新增的、现在官方推荐的部分就好,不过这里要注意一点:不要抱着“Vue3只是Vue2的小补丁”的心态,组合式API(Composition API)是Vue3最大的升级之一,虽然它不是强制的,但学会之后能解决Vue2在处理复杂组件逻辑时代码分散、复用性差的痛点,这才是转Vue3的核心价值。
至于先学哪个,现在官方早就把Vue3定为默认版本了,不管是找工作还是做新项目,Vue3都是主流,完全没必要再从Vue2学起,如果以后碰到旧项目需要维护Vue2,你有了Vue3的基础再回头看Vue2的选项式API(Options API),会觉得特别简单,就像会用Photoshop再看美图秀秀一样。
Vue3的项目怎么搭建?为什么之前用的vue-cli现在很少提了?
搭建Vue3项目现在主要有两种主流方式:Vite和Vue CLI的新版(注意是支持Vue3的新版,不是老版的2.x),不过确实现在Vite更火,官方文档也是推荐新手用Vite起步的。
先说说Vite怎么搭吧,步骤超级简单,首先你得确保电脑上装了Node.js,而且版本最好是16.18+或者18.12+,太老的版本可能会出问题,然后打开你的终端,Windows用CMD或者PowerShell,Mac用Terminal,输入npm create vite@latest 项目名称,回车之后会让你选框架,选Vue就行,接着还会让你选是否使用TypeScript、JSX、Vue Router、Pinia这些,新手的话可以先不选TypeScript,等基础打牢了再加,其他的如果暂时用不上也可以先跳过,选完之后终端会提示你进入项目目录、安装依赖、启动开发服务器,跟着敲那三行命令就行,npm install,npm run dev,然后打开终端给的本地地址,就能看到Vue3的欢迎页面了。
那为什么之前用的Vue CLI现在很少提了呢?核心原因就是Vite的开发速度实在是太快了,Vue CLI是基于Webpack的,Webpack在启动开发服务器的时候,需要先把整个项目的依赖都打包一遍,哪怕你只改了一个小文件,可能也要等个几秒甚至十几秒(如果项目特别大的话);而Vite是基于浏览器原生的ES模块实现的,启动开发服务器的时候根本不需要打包,直接按需加载文件,所以启动速度是秒开的,热更新的速度也特别快,几乎是你改完代码保存,页面就立刻变了,开发体验提升了不止一个档次,如果你的项目需要兼容IE11这种老浏览器,或者有一些特殊的Webpack配置需求,Vue CLI的新版还是能用的,但这种情况现在已经很少见了。
组合式API到底是啥?跟选项式API比有什么好处?
组合式API是Vue3新增的一套编写组件逻辑的API,它是基于函数的,所以也叫函数式API,不过官方更喜欢叫组合式API,因为它的核心是“组合”——把相关的逻辑代码组合在一起,而不是像选项式API那样分散在data、methods、computed、watch这些选项里。
先给大家举个例子对比一下吧,比如我们要写一个带搜索功能的待办清单组件,既能添加待办,又能根据关键词搜索,还能统计未完成的数量。
如果用选项式API写的话,代码大概是这样的:待办的数据在data里,添加待办的方法在methods里,搜索的关键词在data里,过滤后的待办在computed里,未完成的数量也在computed里,点击删除待办的方法在methods里,看起来好像还行,但如果这个组件再复杂一点,比如加上待办的排序、提醒功能、分类功能,那相关的逻辑就会分散得越来越开——比如搜索功能的关键词在data,过滤逻辑在computed,清空搜索的方法在methods,三个地方离得老远,改代码的时候得来回翻,特别麻烦,而且如果想把这个搜索功能或者待办的基础功能复用给其他组件,选项式API的复用方式主要是mixin,但mixin有个很大的问题,就是容易命名冲突,你根本不知道你引入的mixin里有没有跟你组件里重名的data或者methods,用多了代码会变得很难维护。
那用组合式API写的话呢?我们可以把相关的逻辑抽成一个独立的函数,比如叫useTodoList,里面包含待办数据的定义、添加待办的方法、删除待办的方法、统计未完成数量的计算属性,然后把这些返回给组件用;再把搜索功能抽成另一个独立的函数,叫useSearch,里面包含搜索关键词的定义、过滤逻辑的计算属性、清空搜索的方法,同样返回给组件用,这样的话,相关的逻辑代码都在同一个函数里,一目了然,改代码的时候也不用来回翻;而且复用的时候直接引入这两个函数就行,不会有命名冲突的问题,因为每个函数里的变量都是局部的,你可以给返回值起别名,比如const { todos, addTodo, uncompletedCount } = useTodoList(); const { searchKeyword, filteredTodos, clearSearch } = useSearch(todos); 非常清晰。
除了逻辑组合和复用的好处,组合式API还有一个优势,就是对TypeScript的支持特别好,因为它是基于函数的,TypeScript可以很容易地推断出类型,而选项式API对TypeScript的支持就比较弱,需要写很多额外的类型注解。
ref和reactive都是用来定义响应式数据的,到底该怎么选?
ref和reactive是组合式API里最常用的两个定义响应式数据的API,很多新手刚学的时候都会搞混,其实它们的区别很简单,记住一个核心原则就行:ref用来定义基本类型数据(比如数字、字符串、布尔值、null、undefined),也可以用来定义引用类型数据(比如对象、数组);reactive只能用来定义引用类型数据,不能用来定义基本类型数据。
那为什么ref既能定义基本类型又能定义引用类型,还要用reactive呢?因为用ref定义引用类型数据的时候,访问和修改数据都要加.value,比如const user = ref({ name: '张三', age: 18 }); 访问user.name的时候要写成user.value.name,修改user.age的时候要写成user.value.age = 19,而用reactive定义的话,就不需要加.value,直接访问和修改就行,比如const user = reactive({ name: '张三', age: 18 }); 访问user.name、修改user.age = 19都很方便,看起来更自然。
不过这里要注意几个坑:第一个坑是reactive不能直接替换整个对象,比如const user = reactive({ name: '张三' }); 如果你想把user改成{ name: '李四', age: 18 },直接写user = { name: '李四', age: 18 }是不行的,因为这样会把reactive创建的响应式对象替换成普通对象,失去响应式;如果要替换的话,可以用Object.assign,比如Object.assign(user, { name: '李四', age: 18 }); 或者直接修改user的属性,user.name = '李四'; user.age = 18; 第二个坑是ref定义的引用类型数据,其实内部也是调用reactive来实现响应式的,所以你用ref.value访问到的其实是一个reactive对象,也可以直接修改它的属性,不需要替换整个对象;第三个坑是reactive对解构赋值不友好,比如const user = reactive({ name: '张三', age: 18 }); 如果你解构出const { name, age } = user; 那name和age就会变成普通变量,失去响应式;如果要让解构出来的变量保持响应式,可以用toRefs函数,比如const { name, age } = toRefs(user); 这样name和age就是ref类型的响应式变量了,访问和修改的时候还是要加.value。
那到底该怎么选呢?我的建议是:如果是单个基本类型数据,肯定用ref;如果是单个引用类型数据,而且不需要解构赋值或者替换整个对象,就用reactive;如果是多个数据,不管是基本类型还是引用类型,都可以放到一个对象里用reactive定义,或者分别用ref定义,看你自己的习惯;如果需要把reactive对象里的属性解构出来用,记得用toRefs。
Vue3的生命周期钩子有啥变化?在组合式API里怎么用?
Vue3的生命周期钩子和Vue2的相比,主要有两个变化:第一个是生命周期钩子的名称变了,前缀加了on,而且destroyed改成了unmounted,beforeDestroy改成了beforeUnmount;第二个是在组合式API里,生命周期钩子不能直接写在setup函数外面,也不能像选项式API那样作为组件的选项,而是要从vue里导入,然后在setup函数里调用。
先给大家列一下Vue2和Vue3生命周期钩子的对应关系吧:
- beforeCreate → 不需要了,因为setup函数的执行时机就是在beforeCreate和created之间的,所以你在setup函数里写的代码,相当于同时替代了beforeCreate和created这两个钩子
- created → 同上
- beforeMount → onBeforeMount
- mounted → onMounted
- beforeUpdate → onBeforeUpdate
- updated → onUpdated
- beforeDestroy → onBeforeUnmount
- destroyed → onUnmounted
- errorCaptured → onErrorCaptured(这个钩子变化不大,只是前缀加了on)
Vue3还新增了几个生命周期钩子,不过新手暂时用不上,比如onRenderTracked、onRenderTriggered,这两个是用来调试响应式数据的,onActivated、onDeactivated,这两个是配合keep-alive组件使用的,等你学到进阶篇的时候再了解也不迟。
那在组合式API里怎么用呢?举个简单的例子,比如我们要在组件挂载完成之后获取用户数据: 首先从vue里导入ref和onMounted:import { ref, onMounted } from 'vue'; 然后在setup函数里定义一个响应式的用户数据:const user = ref(null); 接着定义一个获取用户数据的函数:const fetchUser = async () => { // 这里写你的请求代码,比如用fetch或者axios const res = await fetch('/api/user'); user.value = await res.json(); }; 最后在setup函数里调用onMounted,把fetchUser传进去:onMounted(fetchUser); 这样就可以了,组件挂载完成之后会自动调用fetchUser函数获取用户数据。
这里要注意一点:在组合式API里,你可以多次调用同一个生命周期钩子,比如你可以在setup函数里调用两次onMounted,第一次用来获取用户数据,第二次用来初始化某个第三方库,这两个函数会按照调用的顺序依次执行,这是选项式API做不到的,选项式API里每个生命周期钩子只能写一次。
Vue3的生态怎么样?Vue Router和Vuex还能用吗?
Vue3的生态现在已经非常成熟了,不用担心找不到合适的插件或者库,之前的Vue Router和Vuex都推出了支持Vue3的版本,不过Vuex现在官方推荐用Pinia代替,因为Pinia更简单、更轻量,对TypeScript的支持也更好,而且已经被纳入Vue的官方生态了,相当于Vuex的升级版。
先说说Vue Router的新版本吧,现在叫Vue Router 4,它和Vue Router 3(支持Vue2的版本)的核心用法是一样的,比如路由的配置、跳转、嵌套路由、路由守卫这些,只是有一些小的变化,比如在组合式API里获取路由实例和当前路由信息,要从vue-router里导入useRouter和useRoute函数,比如import { useRouter, useRoute } from 'vue-router'; const router = useRouter(); const route = useRoute(); 然后用router.push()跳转,用route.params获取路由参数,用route.query获取查询参数,这些都很容易上手。
再说说Pinia,它是Vue3的官方状态管理库,替代了之前的Vuex,Pinia的核心概念比Vuex少,只有state、getters、actions三个,没有mutations了,因为在Pinia里,你可以直接在actions里修改state,不需要通过mutations,这样代码更简洁,而且Pinia的每个store都是一个独立的模块,你可以直接导入使用,不需要像Vuex那样先注册到根store里,对TypeScript的支持也特别好,不需要写很多额外的类型注解,新手学起来会比Vuex容易很多。
除了Vue Router和Pinia,其他常用的第三方库比如Element Plus(Element UI的Vue3版本)、Ant Design Vue、Axios、ECharts、Lodash等等,都已经推出了支持Vue3的版本,完全可以满足日常开发的需求。
新手学Vue3应该怎么规划学习路线?
新手学Vue3的学习路线可以分成三个阶段:基础篇、进阶篇、实战篇,每个阶段大概需要花1-2周的时间(具体时间要看你每天的学习时长)。
基础篇的主要目标是掌握Vue3的核心概念和基础语法,这个阶段可以跟着官方文档的基础篇走,重点学习以下内容:
- Vue3的项目搭建(用Vite)
- 模板语法(插值表达式、指令、事件绑定、class和style绑定)
- 响应式数据的定义(ref、reactive、toRefs、toRef)
- 计算属性和监听器(computed、watch、watchEffect)
- 组件的基础(组件的创建、注册、使用,props、emits、v-model)
- 插槽的基础(默认插槽、具名插槽、作用域插槽)
- 组合式API的基础用法(setup函数、生命周期钩子)
进阶篇的主要目标是掌握Vue3的高级特性和生态,这个阶段可以跟着官方文档的进阶篇和生态篇走,重点学习以下内容:
- 组合式API的高级用法(逻辑复用、自定义hooks)
- Vue Router 4的高级用法(嵌套路由、路由守卫、动态路由、路由懒加载)
- Pinia的高级用法(模块化、持久化、插件)
- TypeScript在Vue3中的使用
- Vue3的性能优化(虚拟列表、懒加载、缓存、Tree Shaking)
- 第三方库的集成(比如Element Plus、Axios、ECharts)
实战篇的主要目标是把之前学到的知识用到实际项目中,提升自己的动手能力和解决问题的能力,这个阶段可以选一个适合新手的实战项目,比如待办清单、个人博客、电商网站的前台或者后台管理系统,最好是跟着视频或者图文教程做,不过不要只是抄代码,要自己思考每一步为什么要这么做,遇到问题要自己先查资料解决,实在解决不了再看答案,做完之后可以把项目部署到GitHub Pages或者阿里云、腾讯云等平台上,放到自己的简历里,找工作的时候会很有帮助。
在学习的过程中,还要注意多写多练,不要只看不写,编程是一门实践性很强的学科,只有多写多练才能真正掌握;还要多查官方文档,官方文档是最权威、最全面的学习资料,遇到问题先看官方文档;还要多和其他开发者交流,比如加入Vue的官方社区或者一些技术群,遇到问题可以请教别人,也可以帮别人解决问题,这样能提升得更快。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网

