从0搭建一个Vue3+Ts+Pinia+Vue-Router+Eslint+Prettier项目
前言
感觉许久没发帖子了,最近使用了 Vue3 + Ts
来写公司的一个项目
正好记录一下这个过程,方便以后没搞懂可以回过头来查看,毕竟我这记忆力,离老年痴呆应该是不远了😂
正文
最先开始,我们直接使用 Vite
脚手架创建一个 Vue3 + Ts
的项目
然后我们在这个项目上进行添砖加瓦
创建 Vue3 + Ts 项目
Vite
文档地址 Scaffolding Your First Vite Project
这里由于我们使用的是 pnpm
包管理工具,所以执行 pnpm create vite
输入项目名,选择 vue
和 vue-ts
即可,然后我们就成功创建了一个最简单的 Vue3 + Ts
的项目
然后我们进入项目执行 pnpm i
安装依赖
到这一步还是相当简单的,我们可以查看下项目的结构
引入 Pinia 和 Vue-Router
Pinia
作为 Vue3
官方的全局状态管理库,使用上更加方便,对比 Vuex
来说拥有更好的类型推断,以及简单的 Api
导出
Vue-Router 4
是 Vue3
官方的路由库,相对于 React
的许许多多的路由实现,Vue
的选择就只有 Vue-Router
,毕竟是官方的,遇到问题也容易找到解决办法
安装 Vue-Router
很简单,直接执行 pnpm add vue-router
即可, 安装 Pinia
只需执行 pnpm add pinia
然后我们需要把它安装到 Vue
上
默认情况下的 main.ts
长下面这样
这时候我们需要先修改下目录结构,增加 router
和 store
两个文件夹
并且分别在这两个文件夹下面建一个 index.ts
之后我们来编写 store
下面的 index.ts
接着我们编写 router
下面的 index.ts
然后我们修改下 main.ts
的代码
然后我们可以执行 pnpm run dev
看一下
这时候我们发现 Vue-Router
报了一个警告,意思就是没有设置 /
对应的路由
我们可以把默认的 HelloWorld
组件作为路由映射出去
先修改 App.vue
,使用 RouterView
来定义一个路由入口
然后我们添加一个路由
这样子这个警告就会消失了,当然,这只是为了演示如何设置路由而已,实际情况下可能会比较复杂
Vue-Router
使用起来和在 Vue2
其实差不多,基本上是一模一样
这里写下 Pinia
的使用
对于很多的网站,我们都是要记录登录状态和当前登录用户的信息的,这个就可以用中心状态管理来做
我们新建一个 useLoginStore.ts
(这里写的代码有点长,就不截图了…
1 | import { defineStore } from "pinia"; |
虽然 Pinia
也可以写成和 Vuex
一样,但是我觉得还是不够优雅,我还是更喜欢这种 setup
写法,没有 this
干扰
然后我们可以写个简答的登录页,新建一个 Login.vue
1 | <script setup lang="ts"> |
注册到路由中
打开 http://localhost:5173/login
就可以看到效果
当然这里不写账号密码是没问题的,只是用来做个例子,随便输入然后点击登录,isLogin
为 true
了
我们可以用 dev-tools
来查看 Pinia
的状态
引入 Naive-UI 组件库
一般而言做一些 ToB
的系统,基本上都不会有 UI
图的,要求的就是一个成型快,所以需要一个组件库来帮助我们开发
我个人还是比较喜欢 Naive-UI
这个组件库的,Ant-Design
和 Element-UI
其实也不错,看个人喜好吧
这里我们直接使用 pnpm add naive-ui
安装
Naive-UI
默认就支持 tree-shaking
,所以我们只需要在需要用到的时候引入相应组件即可
这里我们引入一个 Button
组件,刷新页面就可以看到效果了
引入 unplugin-auto-import 和 unplugin-vue-components
每次我们写页面很多时候都需要引入 reactive
, ref
, watchEffect
等函数,一旦还引用了其他的资源
那么 <script setup>
部分看起来就会比较乱,一坨的 import { } from vue
为了解决这个问题,大神 antfd
开发了 unplugin-auto-import
的插件,支持 vite
, rollup
, webpack
,非常的牛逼
使用这个插件,我们就不用写重复的 import
语句了
使用 pnpm add unplugin-auto-import -D
安装
然后修改 vite.config.ts
文件
注意,这里我们主要配置两个属性,一个是 imports
,一个是 dts
imports
用来表明我们需要全局注册的 import
语句
我们可以点进去看 imports
的类型,支持的自动导入是非常多的
1 | declare const presets: { |
这样子我们使用相关的 api
了
导出的 api
列表我们可以查看 src/auto-import.d.ts
当然,由于我们使用的是 TypeScript
,所以不报错的功劳是这个 src/auto-import.d.ts
文件
默认情况下是有生成 d.ts
文件的,但是不是在 src
目录下,这会导致一个问题
因为 tsconfig.json
并没有识别这个 d.ts
当然你也可以不设置 dts
属性,然后把 auto-import.d.ts
加入到 tsconfig.json
的 includes
属性中
1 | { |
这样也可以顺利识别了
同样,由于我们使用组件库,每个页面也需要引入很多的组件库组件,一旦引入很多代码看起来也会很杂
所以大神又开发了 unplugin-vue-components
插件,它能够全局导出组件库组件,而且是支持 tree-shaking 的
使用 pnpm add unplugin-vue-components -D
安装
然后继续修改 vite.config.ts
文件
这里配置了 resolvers
和 dts
,dts
的作用和上个插件一样
resolvers
配置了需要自动导入的组件库,这里我们使用了 Naive-UI
,所以使用 NaiveUiResolver
,主流的 UI
都能支持,比如 Ant Design
, Element-UI
等
默认情况下啊,他还会把 src/components
下的组件也设为自动导入
可以打开 src/components.d.ts
文件查看,发现 HelloWorld
和 NButton
已经被注册了
tips:如果你使用的是 pnpm
,那么此时会出现一个问题,虽然已经有 d.ts
文件了,但是 vue
文件并没有类型提示
这是由于生成的 d.ts
是在 @vue/runtime-core
模块下的,但是 pnpm
并不会存在幻影依赖,在 node_modules
下不会扁平依赖
所以该 d.ts
就无效了,可以把 @vue/runtime-core
改成 vue
这时候你会发现提示就有了
但是由于这个文件是自动生成的,如果有新的组件需要生成定义,那么又会被插件改成 @vue/runtime-core
这时候我们就要用 .npmrc
来告诉 pnpm
把 @vue/runtime-core
提升到 node_modules
目录下
我们在项目根目录下建一个 .npmrc
文件
1 | # 修复 pnpm 安装无法获得提示问题 |
然后我们重新运行 pnpm i
,这时候 @vue/runtime-core
就在 node_modules
下了
这时候就可以正确的识别类型了
引入 Axios
基本上创建项目都需要 Axios
来作为 http
请求库
当然,如果是单纯的引入其实不难,这里主要是写一下我的封装
这里的 baseURL
参数主要看后端接口,像我司不搞跨域配置的,就需要我在 Vite
中开启一个 proxy
来代理接口,然后对 api
进行转发
拦截器主要是返回实体数据,不然每次都要 res.data.data
来取数据还是比较麻烦的,以及处理错误请求等
这个要根据具体情况来配置,当然,对于 TypeScript
,我们自然希望能够有完整的类型提示
所以我们可以封装下四个方法,这里以 get
举例
然后我们可以写对应的 api
,比如获取用户列表
这样子引入 getUserListApi
这个 api
执行就能有完整的类型提示了
请求参数
返回结果
引入 Eslint 和 Prettier 和 EditorConfig
前面的配置基本上都是功能类的,现在我们需要配置 Eslint
和 Prettier
来保证代码格式和代码质量
代码格式和代码质量是相当重要的,因为我看过公司之前的项目,那个代码看的我真的是头皮发麻,感到不适
但是没办法,该往上加功能还是要加的…
执行 pnpm add eslint prettier -D
安装这两个库
prettier
使用默认配置即可,这里主要是配置 eslint
创建 .eslintrc.json
和 .eslintignore
两个文件
其中 .eslintignore
要排除 node_modules
以及 src/auto-import.d.ts
和 src/component.d.ts
因为 prettier
默认情况下使用双引号的,而这两个 d.ts
都是用单引号的,所以我们避免去格式化这几个文件
在官方文档中,提示我们可以使用 eslint-plugin-vue
这个插件,所以我们安装上它,然后配置 .eslintrc.json
接着我们可以执行 eslint src/App.vue
可以看到 eslint
正确地提示了问题
我们用 prettier
格式化 App.vue
,但是问题并没有消失,这是因为 eslint
的规则和 prettier
冲突了
所以我们需要解决 eslint
和 prettier
的冲突
安装 eslint-config-prettier
,这个配置能够让关掉 eslint
中和 prettier
冲突的规则,修改配置文件如下:
这时候我们执行 eslint src/App.vue
就不会提示错误了
冲突解决之后,还有一个问题,就是 eslint
它不报 prettier
的错误
这里我们使用了单引号,但是 eslint
没报错,接下来,我们就需要让 eslint
在格式不符合 prettier
的情况下报相关的错误
安装 eslint-plugin-prettier
,修改配置文件如下
现在 eslint
就能正确地报错了
当然,我们可以直接把配置修改为如下,等价于上边配置的 eslint-plugin-prettier
和 eslint-config-prettier
当然,eslint-plugin-prettier
使用了 vue-eslint-parser
来解析 vue
文件,对于其他文件,会使用默认的 espree
解析器来解析
如果想替换其他解析器,必须在 parserOptions
下设置 parser
,而不能在根下设置,不然 vue-eslint-parser
会失效,这里官方的文档也有说明
VSCode
安装 Eslint
, Prettier
插件
然后我们打开 settings.json
,配置保存的时候自动使用 eslint
格式化
最后我们通过 .editorconfig
文件来设置一些编辑器的规则
主要是为了防止不同的 ide
会有不同的设置,比如换行符号,从而影响编码
引入 husky 和 lint-staged
虽然设置了代码格式化,但是很多时候项目并不是一个人在开发,是很多人协同合作
你不能要求别人每次提交代码之前都执行一次 eslint
,同时这对于自己来说也很麻烦
所以我们需要使用 git
的 pre-commit
钩子配合 lint-staged
来对暂存区的文件进行自动格式化
执行 pnpm add husky lint-staged -D
安装这两个依赖
husky
需要该项目为 git
仓库,所以需要 git init
初始化,然后执行 pnpx husky install
开启钩子功能
然后执行 pnpx husky add .husky/pre-commit "pnpm run lint-staged"
添加 pre-commit
钩子
这里记得要在 package.json
中添加相应的 script
然后我们在 package.json
中添加 lint-staged
的配置
然后我们可以测试一下,我们修改下 main.ts
代码
git add
之后提交,可以看到自动格式化了
后记
到此我们基本上就搭建了一个功能比较完备的项目了,当然,可操作的地方还有很多
比如 git commit
规范,打包前 eslint
检查,代码分割等
这些以后在慢慢写吧,不急,慢慢来,细水长流嘛
相关的仓库已经上传到我的 git
上了,有需要的直接拉下来删除 .git
,再初始化 git
即可作为一个不错的模板项目