前端通用 Pinia Token 全流程操作指南(常见常用版)

前端通用 Pinia Token 全流程操作指南(常见常用版)

本文梳理 Vue3 官方推荐状态管理库 Pinia 下的 Token 操作逻辑,剥离具体项目细节,聚焦「获取→存储→使用→过期→清除」的核心生命周期,结合 Pinia 「无 mutations、actions 直接异步、模块化更简单」的特性,每个步骤均标注「通用场景+Pinia 通用方案+注意事项」,可直接作为开发速查表。


前置说明:Pinia 与 Vuex 的核心区别(Token 操作相关)

特性VuexPinia
修改状态的方式必须通过 commit 调用 mutationsactions 中可直接修改 state
异步处理actions 处理异步,mutations 同步actions 可直接写 async/await
模块化需开启 namespaced: true 隔离天然模块化,无需额外配置
TypeScript 支持配置复杂原生支持,类型推导友好

一、第一步:登录成功获取并存储 Token

通用场景

用户通过账号密码/验证码等方式登录,后端验证通过后返回 Token,需将 Token 存入 Pinia(全局共享)和本地存储(刷新不丢)。

Pinia 通用方案

  1. 定义 user 模块的 Pinia Store,包含 token 状态和 login 异步 action;
  2. login action 中调用登录接口,提取 Token;
  3. 直接修改 state(无需 commit),同时存入本地存储(推荐 localStorage)。

代码示例

// 1. 定义 Pinia Store(src/stores/user.js)import{ defineStore }from'pinia'import{ loginAPI }from'@/api/user'// 假设已封装好登录接口exportconst useUserStore =defineStore('user',{// state:必须是函数返回对象(避免组件间共享状态)state:()=>({token: localStorage.getItem('token')||''// 初始化时从本地存储读取}),// actions:直接处理异步,可直接修改 stateactions:{asynclogin(loginForm){// 调用登录接口const res =awaitloginAPI(loginForm)// 从接口返回中提取 Token(具体字段看后端文档)const token = res.data.token // 直接修改 state(无需 commit!Pinia 核心优势)this.token = token // 同时存入本地存储 localStorage.setItem('token', token)}}})// 2. 组件中调用(Vue3 组合式 API 示例)<script setup>import{ useUserStore }from'@/stores/user'const userStore =useUserStore()consthandleLogin=async()=>{try{await userStore.login({username:'admin',password:'123456'})alert('登录成功')// 跳转到首页(需结合路由)}catch(err){alert('登录失败:'+(err.response?.data?.msg ||'未知错误'))}}</script>

注意事项

  1. ❌ 不要忘记同时存 Pinia 和本地存储:Pinia 刷新页面会清空,本地存储保证刷新不丢;
  2. ❌ 不要用 Vuex 的思维写 Pinia:无需 commit,直接 this.token = token 即可;
  3. ❌ state 必须是函数返回对象:避免多个组件实例共享同一个 state 对象。

二、第二步:请求接口时自动携带 Token

通用场景

每次发起业务请求时,自动从 Pinia Store 中读取 Token 并添加到请求头。

Pinia 通用方案

  1. 在 Axios/Fetch 封装的请求拦截器中读取 Pinia Store;
  2. 注意:在 Vue 组件外使用 Pinia Store 时,需确保 app.use(pinia) 已执行(通常在 main.js 中先注册 Pinia)。

代码示例

// src/utils/request.js(Axios 封装)import axios from'axios'import{ createPinia }from'pinia'import{ useUserStore }from'@/stores/user'// 初始化 Pinia(组件外使用 Store 必须)const pinia =createPinia()const userStore =useUserStore(pinia)const service = axios.create({baseURL:'/api',timeout:10000})// 请求拦截器:自动带 Token service.interceptors.request.use((config)=>{// 从 Pinia Store 中读取 Tokenconst token = userStore.token if(token){// 添加到请求头(具体字段看后端文档) config.headers['Authorization']=`Bearer ${token}`}return config },(error)=> Promise.reject(error))exportdefault service 

注意事项

  1. ❌ 不要在组件外直接 useUserStore():必须先传入 pinia 实例,否则会报错;
  2. ❌ 不要在每个请求里手动加 Token:用请求拦截器统一处理;
  3. ❌ 不要写错请求头字段名:必须和后端约定一致。

三、第三步:处理 Token 过期

通用场景

Token 过期后,后端返回 401 状态码,需清除 Token 并跳转到登录页。

Pinia 通用方案

  1. 在 Axios/Fetch 封装的响应拦截器中判断 401 状态码;
  2. 调用 Pinia Store 的 logout action 清除 Token;
  3. 强制跳转到登录页。

代码示例

// 1. Pinia Store 补充 logout action(src/stores/user.js)exportconst useUserStore =defineStore('user',{state:()=>({token: localStorage.getItem('token')||''}),actions:{asynclogin(loginForm){/* 登录逻辑 */},// 登出/清除 Token actionlogout(){// 直接修改 statethis.token =''// 清除本地存储 localStorage.removeItem('token')}}})// 2. 响应拦截器补充(src/utils/request.js)import router from'@/router'// 需结合路由 service.interceptors.response.use((response)=> response.data,(error)=>{if(error.response && error.response.status ===401){alert('登录已过期,请重新登录')// 调用 Pinia Store 的 logout action userStore.logout()// 跳转到登录页 router.replace('/login')}else{alert('请求失败:'+(error.response?.data?.msg ||'网络错误'))}return Promise.reject(error)})

注意事项

  1. ❌ 不要只清除 Pinia 不清除本地存储:下次刷新页面旧 Token 又会被读出来;
  2. ❌ 不要忘记跳登录页:Token 过期后用户无法继续操作;
  3. ❌ 跳转登录页建议用 replace:避免用户点击“回退”回到过期页面。

四、第四步:用户主动登出

通用场景

用户点击“退出登录”按钮,需清除所有登录相关数据。

Pinia 通用方案

  1. 给用户二次确认;
  2. 调用 Pinia Store 的 logout action;
  3. 跳转到登录页。

代码示例

<script setup> import { useUserStore } from '@/stores/user' import { useRouter } from 'vue-router' const userStore = useUserStore() const router = useRouter() const handleLogout = () => { if (confirm('确定要退出登录吗?')) { // 调用 Pinia Store 的 logout action userStore.logout() alert('退出成功') router.replace('/login') } } </script> 

注意事项

  1. ❌ 不要省略二次确认:避免用户误触;
  2. ❌ 登出后要彻底清除:包括 Pinia state、本地存储、用户信息(如果有);
  3. ❌ 若后端有登出接口,建议先调用接口再清除前端数据。

五、第五步:路由权限控制(进阶但常用)

通用场景

未登录用户不能访问受保护页面(如首页、个人中心),已登录用户不能访问登录页。

Pinia 通用方案

  1. 在 Vue Router 的 beforeEach 全局前置守卫中读取 Pinia Store;
  2. 定义白名单,判断用户是否登录;
  3. 根据判断结果决定放行或跳转。

代码示例

// src/router/index.jsimport{ createRouter, createWebHistory }from'vue-router'import{ createPinia }from'pinia'import{ useUserStore }from'@/stores/user'const routes =[{path:'/login',component:()=>import('@/views/Login.vue')},{path:'/home',component:()=>import('@/views/Home.vue'),meta:{requiresAuth:true}}]const router =createRouter({history:createWebHistory(), routes })// 初始化 Pinia(路由守卫中使用 Store 必须)const pinia =createPinia()// 全局前置路由守卫 router.beforeEach((to, from, next)=>{const userStore =useUserStore(pinia)const token = userStore.token const whiteList =['/login','/404']if(token){ to.path ==='/login'?next('/home'):next()}else{ whiteList.includes(to.path)?next():next('/login')}})exportdefault router 

注意事项

  1. ❌ 不要在路由守卫中直接 useUserStore():必须先传入 pinia 实例;
  2. ❌ 不要忘记定义白名单:避免无限重定向;
  3. ❌ 前端权限控制仅做拦截:真正的权限校验必须在后端做。

总结:Pinia Token 全流程核心逻辑

  1. 获取+存储:登录接口返回 → Pinia action 直接修改 state + 存本地存储;
  2. 使用:请求拦截器从 Pinia Store 读 Token → 自动加请求头;
  3. 过期:响应拦截器处理 401 → 调用 Pinia logout action → 跳登录页;
  4. 登出:用户确认 → 调用 Pinia logout action → 跳登录页;
  5. 控制:路由守卫从 Pinia Store 读 Token → 白名单判断。

Pinia 专属避坑指南

  1. ❌ 不要用 Vuex 的 commit/mutations 思维:Pinia 直接在 actions 中修改 this.xxx
  2. ❌ 不要在 Vue 组件外直接 useStore():必须先传入 pinia 实例;
  3. ❌ state 不要写成对象:必须是函数返回对象(state: () => ({ token: '' }));
  4. ❌ 不要忘记同时存 Pinia 和本地存储:Pinia 刷新会清空。

Read more

零基础入门MC.JS WEBMC1.8:10分钟创建你的第一个方块世界

快速体验 1. 打开 InsCode(快马)平台 https://www.inscode.net 2. 输入框内输入如下内容: 生成一个极简的MC.JS WEBMC1.8入门教程项目。包含一个基础的3D场景,地面由绿色方块组成,玩家可以使用WASD移动,鼠标点击放置红色方块。代码要极度简化,每个关键部分都有详细注释说明。提供一个分步教程文档,解释如何修改代码来改变方块颜色、大小和移动速度等基本参数。界面要友好,有明确的操作指引。 1. 点击'项目生成'按钮,等待项目生成完整后预览效果 最近在学习3D游戏开发,发现用MC.JS WEBMC1.8创建简单的方块世界特别适合新手入门。今天就把我的学习过程记录下来,分享给同样想尝试的小伙伴们。 1. 环境准备 不需要安装任何软件,直接打开浏览器就能开始。MC.JS WEBMC1.8是基于Web的简化版Minecraft开发框架,特别适合快速搭建3D场景原型。

By Ne0inhk

基于.Net的Web API 控制器及方法相关注解属性

文章目录 * 1. 路由与 HTTP 方法 (`Microsoft.AspNetCore.Mvc` 命名空间) * 2. 参数绑定源 (`Microsoft.AspNetCore.Mvc` 命名空间) * 3. 响应类型与格式 (`Microsoft.AspNetCore.Mvc` 命名空间) * 4. 授权与认证 (`Microsoft.AspNetCore.Authorization` 命名空间) * 5. Swagger/OpenAPI 文档增强 (`Swashbuckle.AspNetCore.Annotations` 或 `Microsoft.AspNetCore.Mvc`) 这些属性主要用于定义 API 的路由、HTTP 方法、参数绑定、响应类型、授权、Swagger 文档等,通常位于控制器类或 Action

By Ne0inhk

B站PC端web自动开启字幕脚本(2025新版适配)

B站自动字幕用户脚本:快捷键开关 + 自动开启字幕(2026新版适配) 作者:Apixus 更新日期:2026年3月5日 项目地址:GitHub仓库 一、脚本介绍 你是否经常在B站看视频时反复手动开启字幕?是否希望切换视频时字幕能自动开启? 这个用户脚本就是为了解决这些问题而开发的。 B站自动字幕脚本 提供了以下功能: * 🎯 快捷键控制:按 C 键快速开启或关闭字幕 * 🔄 自动开启:切换分P、点击推荐视频时自动打开字幕 * 🆕  2026新版适配:专为B站最新版播放器优化 * ⚡ 性能优化:智能监听,告别卡顿轮询 * 🛡️ 防冲突:自动识别输入框,避免误触 二、适用页面 * 普通视频页:https://www.bilibili.com/video/* * 播放列表页:https://www.bilibili.com/list/* 支持普通视频页、番剧页、播放列表页等常见场景。 三、

By Ne0inhk