Vue3+Pinia+TS笔记
很久没有写文章分享笔记了,今天续更一下......
在当今前端开发中,Vue3 凭借其 Composition API 和性能优化,已成为构建现代 Web 应用的首选框架之一。而 Pinia 作为 Vue 官方推荐的状态管理库,以其简洁的 API 和 TypeScript 友好性,逐渐取代 Vuex 成为新项目的标配。再加上 TypeScript 提供的类型安全,这套技术栈能够显著提升代码的可维护性和开发体验。
一、Vue3+Pinia+TS整体流程和关键细节:
1. 项目启动与全局配置
入口文件:main.ts
创建 Vue 应用实例,注册 ElementPlus、全局组件、路由、Pinia 仓库。
应用挂载到 #app。
2. 路由系统
路由配置:
定义了所有静态路由
使用 vue-router 配置 hash 路由模式。
路由守卫:
全局前置守卫:每次路由跳转前执行,判断 token 和用户信息,决定是否放行或重定向到登录页。
逻辑:
有 token 且访问登录页,重定向到首页。
有 token 且有 username,直接放行。
有 token 但无 username,调用 userInfo 获取用户信息,成功放行,失败登出并跳转登录。
无 token,访问登录页放行,否则重定向到登录页。
3. 状态管理(Pinia)
仓库入口:store/index.ts
用户模块:store/modules/user.ts
state: 保存 token、菜单路由、用户名、头像。
actions:
userLogin:调用登录接口,保存 token。
userInfo:调用用户信息接口,保存用户名和头像。
userLogout:调用退出接口,清空 token 和用户信息。
token 的本地持久化通过 utils/token.ts 实现。
4. 接口管理
用户相关接口:api/user/index.ts
reqLogin、reqUserInfo、reqLogout 分别对应登录、获取用户信息、退出登录。
所有接口通过 request.ts 统一封装 axios 实例,自动携带 token。
请求拦截器:utils/request.ts
请求前自动从 Pinia 获取 token,放到请求头。
响应拦截器统一处理错误码,弹出消息。5. 视图与布局
主布局:layout/index.vue
左侧菜单、顶部 tabbar、右侧主内容区。
菜单和面包屑根据路由和用户权限动态生成。
登录页:views/login/index.vue
二、每个模块的作用
1. api(接口请求模块)
作用:统一管理所有后端接口请求(如登录、获取用户信息、商品管理等)。
通常每个业务有一个对应的 api 文件,如 api/user.ts、api/product.ts。
这里会用到接口参数和返回值的类型定义。
2. store(状态管理模块)
作用:用 Pinia 管理全局状态,如用户信息、菜单、权限等。
每个业务有一个小仓库模块,如 store/modules/user.ts。
这里会用到 state、actions、getters 的类型定义。
3. router(路由模块)
作用:定义页面路由结构,控制页面跳转和权限。
路由 meta 字段常用来定义类型(如菜单、权限等)。
4. views(页面视图模块)
作用:每个页面的具体实现。
页面组件会用到 props、emit、接口数据等类型。
5. utils(工具模块)
作用:封装通用工具函数,如 token 操作、请求封装等。
工具函数参数和返回值也可以定义类型。
6. types(类型定义模块,部分项目会单独建一个 types 文件夹)
作用:集中管理全局/通用的类型定义,避免重复和混乱。
比如:用户、商品、菜单、接口响应等通用类型。
三、TypeScript 类型文件的编写时机和放置原则
1. 什么时候写类型?
接口请求时:定义接口参数和返回值类型,保证请求和响应的数据结构安全。
Pinia 仓库 state 时:定义 state 的类型,保证状态管理的类型安全。
组件 props/emit 时:定义 props、emit 的类型,保证组件间通信安全。
工具函数参数/返回值时:定义工具函数的输入输出类型。2. 类型文件放在哪里?
业务相关类型:放在对应业务模块下的 types 文件夹或 type.ts 文件。
例如:type.ts、src/store/modules/user/type.ts
全局/通用类型:放在 src/types/ 目录下,供全局 import。
例如:src/types/global.d.ts、src/types/common.ts
小型项目:可以直接在 api 或 store 文件夹下建 type.ts。
大型项目:建议每个大模块单独建 types 文件夹,统一管理。
四、我的思路理解:
当你在某个模块(如 user、product、order 等)需要定义 TypeScript 类型时,可以在该模块下新建一个 type.ts 或 types 文件夹,专门存放类型定义。
在 type 文件中,定义接口、类型别名等(如接口参数、响应数据、state 结构等)。
在需要用到这些类型的文件(如 api、store、组件等)通过 import 导入并绑定类型。
五、关于ts类型的定义:
1. 定义 TypeScript 类型只需要新建一个 .ts 后缀的文件即可,在这个文件里可以编写接口(interface)、类型别名(type)、枚举(enum)等类型定义。
2. .ts 后缀的文件不仅可以编写类型(如 interface、type、enum),还可以编写普通的 TypeScript 代码,比如变量、函数、类、业务逻辑等。
3. .ts 文件可以编写与 Vue 组件相关的逻辑代码(如函数、类、状态管理、工具方法等),但不能直接写模板(template)和样式(style),也不能像 .vue 文件那样包含 <template>、<script>、<style> 三个部分。
具体说明:
.ts 文件适合写:
业务逻辑函数(如工具函数、接口请求、状态管理等)
类型定义(interface、type)
组合式 API 的逻辑封装(如自定义 hooks)
组件的 props、emit 类型等
.vue 文件适合写:
组件的模板(HTML)
组件的逻辑(JS/TS)
组件的样式(CSS/SCSS)
六、关于router和route的区别
route 和 router 都来自 vue-router,但它们的作用和使用场景不同:
1. router
含义:router 是路由实例对象,包含了整个路由系统的配置和方法。
常用功能:用于编程式导航(跳转页面)、添加/删除路由、获取路由实例等。
常用方法:
router.push() 跳转到某个路由
router.replace() 替换当前路由
router.back() 返回上一页
使用场景:当你需要在代码中主动跳转页面、返回、动态添加路由时,使用 router。
2. route
含义:route 是当前激活的路由对象,包含当前路由的路径、参数、query、meta 等信息。
常用属性:
route.path 当前路径
route.params 动态路由参数
route.query 查询参数
route.meta 路由元信息
使用场景:当你需要获取当前页面的路由信息(如参数、路径、meta),用 route。
总结
router:用于跳转、操作路由(“做事”)
route:用于获取当前路由信息(“拿数据”)
在 Vue 组件中,通常用 useRouter() 获取 router,用 useRoute() 获取 route。
这部分是自己在学习的时候摘抄并整理的 ,希望对你有帮助!