Vue3+vite+ts搭建项目
新公司待了差不多三个月了,公司前端一直使用基于Vue2封装的一个基础前端框架进行开发,主要是框架集成了一些公司封装的后台管理功能,年后尤大宣布将Vue3作为默认版本,恰好年后一直没什么项目做,就学习一下Vue3顺便把公司的框架拿Vue3重写一下吧。
因为选择了Vue3+Ts+Vite,所以基础配置的搭建跟之前的Vue-cli是有些不同的,所以还是记录一下搭建整个项目基础的过程。
初始化项目
查看Vite的官方文档,我们可以使用yarn create vite来创建项目,然后根据提示完成项目的初始化即可。
当然也可以直接输入自己要用的模板来创建项目,比如我们要创建一个vue+ts的项目,也可以直接通过yarn create vite --template vue-ts生成项目。
关于eslint的配置不在此过多描述,根据部门要求创建即可。
配置vite.config.ts
vite.config.ts与之前的vue.config.js是比较相似的,但也有一些不同之处,只介绍一些常用功能的配置。
配置基础路径
在vue.config.js中我们可以配置publicPath来配置基础路径,在vite中我们通过配置base来实现。
假设我们在开发环境中基础路径配置为’/‘,但是在生产环境中配置为相对路径,可以如下配置:
1 | import { defineConfig } from 'vite' |
上面我们还引入了defineConfig和vue,前者是为了有良好的代码提示,后者则必须要配置
如果配置了base路径,那么要注意你的路由是否能正常匹配
路由创建的时候也可以在createWebHistory(base)中传入一个base路径
路径配置别名
大家使用vue开发都喜欢给src目录配置别名为@,一般都是定义一个resolve方法,用来返回路径。
在vite中我们也可以直接从path模块中引入resolve,不过在这个时候代码编辑器可能会给你一个错误提示。
所以我们需要先安装@types/node供我们正常使用node的模块
1 | yarn add @types/node |
现在我们就可以引入resolve方法了
1 | import { resolve } from 'path' |
按照之前的套路,现在应该就已经完成了,但是现在并不可以,我们还需要在tsconfig.json中进行对应的配置
1 | { |
到此我们就可以使用配置的别名进行引入了。
配置proxy代理
代理的配置跟之前相比是差不多的,不过proxy不再允许直接配置为字符串了,必须配置为一个对象。
1 | server: { |
配置CSS预处理器
我们在开发过程中一般不会直接使用css,而是使用预处理器如scss/sass/less等等,虽然vite对他们有原生支持,但是必须要手动安装依赖,以scss为例:
1 | yarn add dart-sass --dev |
配置全局css样式文件
配置好样式的预处理器之后,我们可以对全局样式进行配置。
将这个全局样式文件注入到项目中,在任何组件中都可以直接使用而不需要任何引入。
假设我们将样式文件目录为 /src/style/main.scss,可以在vite中进行如下配置将样式注入全局
1 | css: { |
配置路由
路由需要我们手动进行添加,目前对vue-router@4版本对ts有不错的支持。
1 | yarn add vue-router@4 // 可以自行指定版本号,版本不低于4即可 |
在src目录下新建一个router目录,创建index.ts对路由进行配置
1 | import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' |
之前对scrollBehavior配置使用的x,y在新版本中对应为left,top,其他的配置应该都能看懂
动态路由
现在大家在做路由权限的时候大多会将路由信息存储在后台,在用户登录后返回用户对应的路由信息,然后动态的生成路由,所以之前可能会有这个操作:
1 | let routers = userMenus.map( item => { |
但是在vite中是不允许你这样动态引入路由组件的,需要使用vite提供的import.meta.glob来实现
例如:
1 | const modules = import.meta.glob('../views/*.vue') |
modules就能读取到views下的所有vue文件,Object.keys(modules)就是所有vue文件的路径
所以我们在动态引入组件的时候可以这样:
1 | component: modules['../views/' + item.component + '.vue'] |
import.meta.*
前边在配置动态路由的时候我们看到了import.meta.glob,与之相对还有一个import.meta.globEager也是用来引入文件的。
还有一些别的方式也是常用的:
环境变量
Vite 在一个特殊的
import.meta.env对象上暴露环境变量。
.env文件也有多种,我们可以查看一下官方文档。
.env # 所有情况下都会加载
.env.local # 所有情况下都会加载,但会被 git 忽略
.env.[mode] # 只在指定模式下加载
.env.[mode].local # 只在指定模式下加载,但会被 git 忽略
我们可以基于此在不同的环境中配置不同的变量
比如创建.env.development文件配置开发环境变量
1 | // 开发环境变量 - .env.development |
创建.env.production文件配置生产环境变量
1 | // .env.production |
然后我们可以在任何地方通过import.meta.env.baseURL来读取这个变量,并且会根据你当前所处环境的不同读取不同的文件。
静态资源
在之前我们想在页面上加载一张本地图片可能会有这种操作
1 | <template> |
但是现在vite也不在允许这种操作了,而是提供了新的方案
我们可以定义如下函数,然后传入图片的名称就可以得到图片的URL了
1 | /** |
然后在页面中使用:
1 | <template> |
状态管理
在vue3项目中我们一般不会使用vuex来作为状态管理工具了,而是使用pinia来完成这个功能
在此不过多介绍pinia的使用,可以查看一下文档,用起来比较简单。
我们可以在store目录下新建index.ts生成store实例:
1 | import { createPinia } from 'pinia'; |
然后我们可以创建某一模块功能的store:
1 | // loginStore.ts |
正如你所见,pinia是没有mutation的。
我们可以在组件中使用它:
1 | <script setup lang='ts'> |
大家可能已经发现了在loginStore.ts文件中我们还定义了一个函数useLoginStoreWithOut,这是因为如果在组件外使用pinia,需要手动传入store实例,具体细节可以查看文档。
事件通信
Vue3官方推荐使用mitt等来实现事件通信,以mitt为例:
创建一个工具方法EventBus.ts:
1 | import mitt from 'mitt' |
在组件中就可以引入emitter来实现通信
1 | <script setup lang='ts'> |
1 | <script setup lang='ts'> |
Mock数据
前后端分离项目,Mock数据总是不能少的,基于Mockjs进行简单实现一下即可。
1 | // main.ts |
在/mock/index下进行Mock拦截
1 | // /mock/index.ts |
在/mock目录下其他文件配置相关mock接口及返回数据
1 | // /mock/mock数据 |
如果在/mock目录下需要配置一些工具函数等不是mock数据等内容,命名以_开头,比如_util.ts
Vue3+vite+ts搭建项目