刚学完Vue3基础,要开发项目该怎么选全家桶工具和上手?
现在说的Vue3全家桶,到底包含哪些“标配”工具?
很多刚入门转实战的同学对“全家桶”的定义有点模糊,要么觉得就是官方那几个,要么会加一堆杂七杂八的库,其实现在主流的Vue3实战项目,官方核心三件套是绕不开的:Pinia做状态管理、Vue Router处理路由跳转、Vite当构建工具(注意哦,Webpack虽然也能用,但官方现在主推Vite,性能和开发体验差得不是一点),如果做的是移动端或者PC端组件复用率高的项目,还可以加一套UI组件库,比如Element Plus(PC端首选)、Vant4(移动端)、Nuxt UI(全栈型UI库,搭配Nuxt3用),要是有复杂的网络请求,Axios肯定得上,虽然Vue本身没有内置HTTP客户端,但Axios和Vue的生态兼容性最好,官方文档里也有推荐的封装方式。
很多同学可能会问:之前学的Vue2全家桶是Vuex+Vue Router3+Webpack,要不要改?我的建议是,只要不是接手Vue2的老项目维护,新开发的直接用Vue3的新三件套就对了,Pinia比Vuex4简洁太多,没有Mutation这种冗余的中间层,支持TypeScript的类型提示更丝滑;Vue Router4完全适配Vue3的Composition API,路由守卫的写法也更灵活;Vite的开发热更新速度,Webpack根本比不了——改个组件Webpack可能要等3-5秒,Vite基本是毫秒级刷新,写代码的流畅度会提升一大截。
选好工具后,第一步该做什么?创建项目框架时要注意哪些坑?
创建Vue3实战项目,用Vite官方脚手架是最快的,别再自己手动搭了,除非你对构建工具的配置特别熟,具体步骤很简单:打开终端,输入npm create vite@latest,然后按提示选Vue、选TypeScript或者JavaScript(这里强烈建议选TypeScript,现在中大型Vue3项目90%以上都用TS,不仅能提前发现代码错误,还能提升代码可维护性和团队协作效率)、选是否安装Pinia/Vue Router(新手直接选“是”,自动配置好基础框架,不用自己手动装依赖改配置)。
接下来是项目创建后的小调整和避坑指南,很多新手这里容易踩雷: 第一,端口号问题,Vite默认的端口号是5173,有时候和其他本地服务冲突,你可以在vite.config.ts里加个server.port的配置,改成自己想要的端口,比如3000或者8080。 第二,别名配置,写代码时import组件或者工具函数,用相对路径../../../太麻烦,也容易出错,你可以在vite.config.ts的resolve.alias里加个@符号,指向src目录,这样以后导入src里的东西直接用@/就行,不过选TypeScript的话,还得在tsconfig.json的compilerOptions里加paths和baseUrl的配置,不然TypeScript会报错找不到路径。 第三,环境变量配置,项目开发时用的接口地址和上线时肯定不一样,你可以在项目根目录下建.env.development(开发环境)、.env.production(生产环境)、.env.staging(测试环境,可选)三个文件,变量名必须以VITE_开头,不然Vite不会暴露给前端代码,比如VITE_API_BASE_URL=http://localhost:3000/api,然后在代码里用import.meta.env.VITE_API_BASE_URL来获取。
Pinia状态管理怎么用才不混乱?有没有适合新手的项目结构建议?
很多新手刚用Pinia时,会把所有状态都放在一个store里,最后那个store文件几千行,根本没法维护,其实按功能模块拆分store是最基本的原则,比如用户模块建个user.ts,购物车模块建个cart.ts,商品列表模块建个product.ts,每个模块只负责自己的状态、getters(计算属性)和actions(异步/同步操作)。
给新手推荐一个简单清晰的Pinia项目结构:在src目录下建个stores文件夹,每个功能模块一个单独的ts文件,stores里再建个index.ts统一导出所有store,这样以后导入store时,直接从@/stores导入就行,不用一个个文件找,举个user.ts的例子:先定义一个useUserStore的函数,用defineStore包裹,第一个参数是store的唯一标识(建议和文件名一致),第二个参数可以是对象写法(Options API风格),也可以是函数写法(Composition API风格),新手推荐先练对象写法,熟悉后再转函数写法——函数写法和Vue3的Composition API写法一样,代码更灵活,复用性更强,而且TypeScript类型提示完全自动生成,不用额外定义interface。
Pinia的持久化存储也是新手经常需要的功能,比如用户登录后的token、用户信息,刷新页面后不能丢,你可以直接用pinia-plugin-persistedstate这个第三方插件,不用自己手动写localStorage/sessionStorage的逻辑,安装依赖后,在main.ts里引入并注册插件,然后在需要持久化的store里加个persist属性就行,比如persist: { key: 'user-store', storage: localStorage },这样这个store里的所有状态都会自动存到localStorage里,刷新页面后自动恢复,你还可以配置只持久化某些状态,或者用加密插件对敏感信息加密,非常方便。
Vue Router4的路由守卫怎么用?什么时候用全局守卫、路由独享守卫、组件内守卫?
路由守卫的作用,简单来说就是在路由跳转前、跳转中、跳转后做一些拦截或者处理,比如登录验证、权限控制、页面标题修改、路由跳转进度条加载等,很多新手容易把三个守卫搞混,其实记住它们的作用范围和执行顺序就行。
先说说执行顺序:全局前置守卫 beforeEach → 路由独享守卫 beforeEnter → 组件内前置守卫 beforeRouteEnter → 全局解析守卫 beforeResolve → 全局后置守卫 afterEach。 然后是作用场景: 全局前置守卫beforeEach,作用范围是所有路由跳转,最常用的场景就是登录验证——比如判断用户有没有token,没有的话跳转到登录页,有的话判断有没有访问当前路由的权限,没有的话跳转到403页,这里要注意一个无限循环的坑:如果跳转到登录页时没有加判断条件,会一直触发beforeEach,导致页面卡死,所以一定要给登录页、404页这些不需要权限的路由加个白名单。 路由独享守卫beforeEnter,作用范围是单个路由或者一组路由,适合做单个路由的特殊权限验证或者参数校验,比如某个详情页必须带id参数才能进入,没有的话跳转到列表页。 组件内守卫有三个:beforeRouteEnter(进入组件前,此时组件实例还没创建,不能用this)、beforeRouteUpdate(组件复用前,比如从详情页1跳转到详情页2,组件没有销毁只是更新了参数)、beforeRouteLeave(离开组件前,此时组件实例还存在,可以用this,常用场景是提醒用户保存未提交的表单),beforeRouteEnter虽然不能用this,但可以通过回调函数获取组件实例,比如next(vm => { vm.initData() })。
Vue Router4还支持路由懒加载,也就是只有当用户访问某个路由时,才会加载对应的组件,这样可以减少首屏加载时间,提升用户体验,路由懒加载的写法很简单,把原来的import Home from '@/views/Home.vue'改成() => import('@/views/Home.vue')就行,选TypeScript的话,还可以加个类型注解,比如defineAsyncComponent<typeof import('@/views/Home.vue').default>(() => import('@/views/Home.vue')),不过其实不加也没关系,Vue Router4会自动识别。
Axios在Vue3项目里怎么封装才好用?有没有必要加请求拦截和响应拦截?
Axios的封装非常有必要,如果每个组件里都直接写axios.get/post,代码会非常冗余,而且后期如果接口地址变了或者需要统一加token、统一处理错误,改起来会非常麻烦。
给新手推荐一个通用的Axios封装思路:在src目录下建个utils文件夹,里面建个request.ts文件,先引入Axios,然后创建一个Axios实例,配置baseURL(从环境变量里获取)、timeout(比如10秒,超时自动取消请求)、headers(比如Content-Type: application/json),然后给这个实例加请求拦截和响应拦截: 请求拦截:主要做两件事,一是统一给请求头加token(比如从Pinia的user store里获取),二是可以加个请求进度条的开始(比如用nprogress这个第三方插件)。 响应拦截:主要做三件事,一是关闭请求进度条,二是统一处理响应错误(比如401未授权,跳转到登录页并清除token;403禁止访问,跳转到403页;500服务器错误,提示用户稍后再试),三是统一处理响应数据(比如后端返回的数据格式是{ code: 200, data: {}, message: 'success' },可以直接返回data,这样组件里用的时候就不用每次都写res.data了)。
封装好之后,再在src目录下建个api文件夹,按功能模块拆分接口,比如用户模块建个user.ts,商品模块建个product.ts,每个模块里只写具体的接口请求函数,比如login(data: LoginParams) { return request.post('/user/login', data) },然后组件里用的时候直接从api里导入对应的函数就行,非常清晰。
开发完项目后,该怎么优化和部署?
开发完项目后,先做性能优化,再部署,不然上线后首屏加载慢,用户体验会很差,常见的Vue3项目性能优化方法有: 第一,路由懒加载,这个刚才说过了,一定要加。 第二,组件懒加载,和路由懒加载类似,适合用在弹窗、折叠面板这些不是一开始就显示的组件上,比如用defineAsyncComponent包裹。 第三,图片懒加载,可以用vue-lazyload这个第三方插件,或者用原生的loading="lazy"属性(不过原生属性的兼容性不如插件好,建议用插件)。 第四,代码压缩和分包,Vite打包时默认会做代码压缩,但你可以在vite.config.ts里加一些配置,比如开启gzip压缩(需要后端配合)、拆分包(把第三方库比如Vue、Pinia、Element Plus拆成单独的包,这样用户刷新页面时,只要第三方库没有更新,就不用重新下载)。 第五,减少不必要的响应式数据,比如用ref包裹的常量,可以改成普通变量,或者用shallowRef/shallowReactive包裹不需要深层响应式的对象。
性能优化完后,部署其实很简单,因为Vite打包出来的是静态文件(html、css、js、图片等),可以直接部署到任何静态文件服务器上,比如Nginx、Apache、GitHub Pages、Gitee Pages、阿里云OSS+CDN等,新手推荐先试试GitHub Pages或者Gitee Pages,免费而且不用自己搭服务器,具体步骤是:在vite.config.ts里加个base配置(GitHub Pages的话是仓库名,比如仓库名是vue3-project,base就写成'/vue3-project/';Gitee Pages类似),然后运行npm run build打包,打包出来的dist文件夹就是静态文件,把dist文件夹里的内容上传到GitHub Pages或者Gitee Pages的分支上就行。
要是部署到Nginx的话,需要注意一个路由刷新404的坑:因为Vue Router4默认用的是history模式,URL里没有#号,看起来更美观,但刷新页面时,Nginx会去服务器上找对应的文件,找不到就会返回404,解决方法很简单,在Nginx的配置文件里加个try_files配置,比如location / { try_files $uri $uri/ /index.html; },这样刷新页面时,Nginx会先找对应的文件,找不到就返回index.html,然后让Vue Router自己处理路由跳转。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网


