跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScript大前端

Vue3 Pinia Token 全流程操作指南

梳理 Vue3 状态管理库 Pinia 下的 Token 操作逻辑,涵盖获取存储、请求携带、过期处理、主动登出及路由权限控制五大核心步骤。通过对比 Pinia 与 Vuex 区别,提供 Axios 封装及 Store 定义示例,强调无 mutations、actions 直接异步等特性,帮助开发者构建安全可靠的认证流程。

FrontendX发布于 2026/3/21更新于 2026/10/1598 浏览

Vue3 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'

export const useUserStore = defineStore('user', {
  // state:必须是函数返回对象(避免组件间共享状态)
  state: () => ({
    token: localStorage.getItem('token') || '' // 初始化时从本地存储读取
  }),
  // actions:直接处理异步,可直接修改 state
  actions: {
    async login(loginForm) {
      // 调用登录接口
      const res = await loginAPI(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()
const handleLogin = 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 中读取 Token
  const token = userStore.token
  if (token) {
    // 添加到请求头(具体字段看后端文档)
    config.headers['Authorization'] = `Bearer ${token}`
  }
  return config
}, (error) => Promise.reject(error))

export default 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)
export const useUserStore = defineStore('user', {
  state: () => ({
    token: localStorage.getItem('token') || ''
  }),
  actions: {
    async login(loginForm) {
      /* 登录逻辑 */
    },
    // 登出/清除 Token action
    logout() {
      // 直接修改 state
      this.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.js
import { 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')
  }
})

export default 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 刷新会清空。

目录

  1. Vue3 Pinia Token 全流程操作指南
  2. 前置说明:Pinia 与 Vuex 的核心区别(Token 操作相关)
  3. 一、第一步:登录成功获取并存储 Token
  4. 通用场景
  5. Pinia 通用方案
  6. 代码示例
  7. 注意事项
  8. 二、第二步:请求接口时自动携带 Token
  9. 通用场景
  10. Pinia 通用方案
  11. 代码示例
  12. 注意事项
  13. 三、第三步:处理 Token 过期
  14. 通用场景
  15. Pinia 通用方案
  16. 代码示例
  17. 注意事项
  18. 四、第四步:用户主动登出
  19. 通用场景
  20. Pinia 通用方案
  21. 代码示例
  22. 注意事项
  23. 五、第五步:路由权限控制(进阶但常用)
  24. 通用场景
  25. Pinia 通用方案
  26. 代码示例
  27. 注意事项
  28. 总结:Pinia Token 全流程核心逻辑
  29. Pinia 专属避坑指南

更多推荐文章

查看全部
  • 银河麒麟 V11-2503 安装教程:6.6 内核与 AI 特性详解
  • WebStorm 2025 版下载、安装及首次启动指南
  • 基于Java Web的驾校考试管理系统设计与实现
  • Java IO 流进阶:Buffer 与 Channel 核心概念及与传统 IO 区别
  • Shannon:基于白盒分析的 AI 自动化渗透测试平台
  • 通义万相 2.1 开源视频模型部署与性能解析
  • 渗透测试流程详细讲解
  • Git 安装与配置完整指南
  • Spring AI:Java 生态原生 AI 框架入门指南
  • 微调模型成本太高?用 RAG 技术实现低成本 AI 升级
  • OpenClaw 全能助手安装与配置指南
  • Ubuntu 22.04 下 libwebkit2gtk-4.1-0 安装避坑指南
  • JavaScript 基础语法与 jQuery 快速入门
  • Java Web 前端基础:HTML 核心知识点总结
  • AI 智能体应用工程师核心知识模拟试题与解析
  • Windows 下 uv 命令无法识别:Python 工具路径配置详解
  • MIT 电机模式控制原理及参数调试
  • Java JDBC 核心接口与防注入实战
  • 利用提示词优化 AI 生成内容以降低 AIGC 检测率
  • AI动漫制作全流程指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online