1051 字
5 分钟
Pinia的使用
一、为什么选择 Pinia?
Pinia 是 Vue.js 官方推荐的状态管理库,它基于 Composition API 设计,具有以下核心优势:
- 模块化:支持多个 Store 模块独立管理不同业务状态
- 响应式:基于 Vue3 的响应式系统实现状态自动更新
- 轻量:体积仅有 ~1KB(gzip 后),性能优异
- 类型安全:完美支持 TypeScript,提供完整类型推导
在电商应用中,我们常需要跨组件共享购物车、用户登录态等数据,Pinia 可以优雅解决这类问题。
二、快速入门
1. 安装依赖
npm install pinia
2. 初始化 Pinia
import { createApp } from 'vue'import { createPinia } from 'pinia'import App from './App.vue'
const app = createApp(App)app.use(createPinia()) // 全局注册 Piniaapp.mount('#app')
3. 解决 TypeScript 类型问题
如果出现类型错误,需确保 tsconfig.json
包含以下配置:
{ "compilerOptions": { "moduleResolution": "Node", "esModuleInterop": true, "skipLibCheck": true }}
三、Store 模块开发
这里我就拿用户管理
来说明了
1. 用户状态管理模块
import { defineStore } from 'pinia'import { loginApi, getUserInfoApi } from '@/api/user'import type { LoginParams, UserInfo } from '@/types'
export const useUserStore = defineStore('user', { state: () => ({ token: localStorage.getItem('token') || '', userInfo: null as UserInfo | null }),
actions: { // 用户登录流程 async login(params: LoginParams) { try { // 1. 调用登录接口 const { data } = await loginApi(params)
// 2. 持久化存储 token this.setToken(data.token)
// 3. 获取用户信息 await this.fetchUserInfo()
return data } catch (error) { // 登录失败处理 this.clearToken() throw new Error('登录失败:' + error.message) } },
// token 管理 setToken(token: string) { this.token = token localStorage.setItem('token', token) },
clearToken() { this.token = '' this.userInfo = null localStorage.removeItem('token') },
// 获取用户信息 async fetchUserInfo() { const { data } = await getUserInfoApi() this.userInfo = data } }})
2. Store 入口文件
import { createPinia } from 'pinia'
export const pinia = createPinia()export * from './userStore'
四、与 API 层集成
1. 请求拦截器自动注入 Token
import axios, { type AxiosInstance, type InternalAxiosRequestConfig, type AxiosResponse, type AxiosError,} from 'axios';import { useUserStore } from '@/store/modules/user';
type RequestConfig<T = any> = InternalAxiosRequestConfig<T>;type ResponseData<T = any> = T;
const http: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_APP_BASE_API, timeout: 10000,});
// 增强的请求拦截器http.interceptors.request.use( (config: RequestConfig): RequestConfig => { const userStore = useUserStore(); if (userStore.token) { config.headers = { ...config.headers, Authorization: `Bearer ${userStore.token}`, // 拿到token } as typeof config.headers; } return config; }, (error: AxiosError) => Promise.reject(error));
// 其他省略...
五、组件使用示例
登录组件调用
<script setup lang="ts">import { ref, reactive } from 'vue'import message from '@/components/message'
// 登录验证import { useUserStore } from '@/store/modules/user'import router from '@/router'
const userStore = useUserStore()
// 表单引用const loginFormRef = ref()
// 表单数据const loginForm = reactive({ username: '', password: ''})
// 登录操作const handleLogin = async () => { try { // 表单验证 const valid = await loginFormRef.value.validate(); if (!valid) return;
loading.value = true;
// 调用 Pinia Store 的登录方法 await userStore.login({ username: loginForm.username, password: loginForm.password });
// 登录成功提示 message.success('登录成功!');
// 跳转到首页 router.push('/home');
} catch (error) { // 登录失败提示 message.error('登录失败,请检查用户名和密码!'); } finally { loading.value = false; }};</script>
六、项目结构规范
src/├── api/ # API 接口封装│ └── user.ts # 用户相关接口├── store/ # 状态管理│ ├── userStore.ts # 用户状态模块│ └── index.ts # Pinia 入口├── types/ # 类型定义│ └── user.ts # 用户相关类型├── utils/ # 工具函数│ └── request.ts # 封装的 axios 实例└── views/ # 页面组件 └── Login.vue # 登录页面
七、完整数据流
sequenceDiagram participant 组件 participant Store participant API participant 后端
组件->>Store: 调用 login() Store->>API: 执行 loginApi() API->>后端: POST /user/login 后端-->>API: 返回 token API-->>Store: 处理响应 Store->>API: 调用 getUserInfoApi() API->>后端: GET /user/info 后端-->>API: 返回用户信息 API-->>Store: 更新状态 Store-->>组件: 状态更新
- 用户输入:在登录表单填写用户名密码
- 发起请求:点击登录时调用
userStore
的login
方法,将参数传递给 loginApi - 保存 Token:登录成功后通过
userStore.setToken()
保存到 Pinia 和 localStorage - 自动注入 Token:后续请求拦截器会自动携带 Token
补充
这里只是简单介绍了一下 pinia 的基础使用(貌似也没有讲) 我是边看 pinia看这一篇就够了 - 掘金 边自己查阅资料写的,以后用到再补充吧
还有就是上面数据流图的实现,我还要写一篇来记录一下,因为我对这个规范还不是很熟练。
阅读量:
评论数: