You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt.js 实现axios插件访问store存储token的方法

Nuxt 自定义axios插件读取Store Token的正确实现

此前方案失效的核心原因

  • 直接从store文件导入静态state的思路完全不匹配Nuxt的运行逻辑:Nuxt的store是运行时在服务端、客户端分别独立实例化的,静态导入拿到的不是实际运行的状态实例,自然读不到正确的值
  • 插件入参解构store报错,本质是没有按照Nuxt插件的规范注册、执行:如果插件没有在nuxt.config.js的plugins数组里正确登记,Nuxt不会在执行时传入包含store的上下文对象,自然会出现解构undefined的报错
  • 在axios实例创建时硬编码Authorization请求头是逻辑错误:插件初始化的执行时机早于用户登录、Store持久化数据从本地恢复的时机,这时候拿到的token大概率是null;就算后续Store里的token更新,已经固化在实例初始化配置里的请求头也不会同步更新
  • 在mutation中调用this.$axios.setHeader不生效,是因为没有把自定义的axios实例正确挂载到Nuxt全局上下文,此时的this.$axios要么不存在,要么不是你创建的目标实例,调用自然没有实际效果

正确实现步骤

1. 重写axios插件逻辑

核心调整点:

  • 从Nuxt上下文解构获取store实例
  • 通过请求拦截器在每次请求发出前动态读取最新的store token,而非硬编码在初始化配置里
  • 将创建好的axios实例挂载到Nuxt全局上下文,方便组件内调用

示例代码:

// /plugins/axios.js
import axios from 'axios'

// 插件第二个入参是Nuxt提供的inject方法,用来挂载全局属性
export default ({ store }, inject) => {
  // 仅创建基础axios实例,不提前绑定固定的Authorization头
  const api = axios.create({
    baseURL: process.env.BASE_URL
  })

  // 添加请求拦截器:每个请求发出前执行一次
  api.interceptors.request.use(config => {
    // 读取当前最新的store token,存在则动态填充请求头
    const token = store.state.token
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  })

  // 将实例挂载到全局,后续可通过this.$api直接调用
  inject('api', api)
}

为什么必须用请求拦截器?因为插件初始化时机非常早:

  • 客户端场景下,插件执行时持久化插件可能还没把本地存储里的token恢复到store里,这时候硬编码的请求头会是空的
  • 后续用户登录、store更新token后,已经创建好的实例的静态配置不会自动同步
    用拦截器的话,每次发请求才去读最新的store状态,永远能拿到当前最新的token值,不会出现状态不同步的问题

2. 调整nuxt.config.js的插件执行顺序

Nuxt会严格按照plugins数组的顺序从上到下执行插件,因为你用了客户端侧的store持久化插件,必须保证持久化插件的执行顺序在axios插件之前——不然axios拦截器执行时,store里的持久化token还没从本地恢复,会出现第一次请求拿不到token的问题。

正确配置:

// nuxt.config.js
export default {
  plugins: [
    // 先执行持久化插件,等store的本地数据恢复完成
    '~/plugins/persistedState.client.js',
    // 再执行axios插件
    '~/plugins/axios'
  ]
}

3. 修正mutation中的请求头设置逻辑

因为现在已经把自定义的axios实例挂载到了全局上下文,你之前在mutation里写的setHeader逻辑只要调整下指向的实例,就可以正常生效:

// store/index.js
export const state = () => ({
  token: null,
  user: null,
  isUserLoggedIn: false
})

export const mutations = {
  setToken(state, token) {
    state.token = token
    state.isUserLoggedIn = !!token
    // 这里的this.$api就是之前插件挂载的自定义axios实例
    if (token) {
      this.$api.setHeader('Authorization', `Bearer ${token}`)
    } else {
      // 用户登出时主动清除请求头
      this.$api.setHeader('Authorization', '')
    }
  }
}

这部分逻辑属于双保险:因为有请求拦截器的动态读取,就算不写mutation里的setHeader,也能正常给每个请求带上最新的token,补上这段逻辑只是为了让实例的默认配置和store状态保持同步。

解构store报错的通用排查方向

如果写了解构逻辑还是报Cannot destructure property 'store' of 'undefined' as it is undefined,按以下顺序排查:

  • 检查插件是否在nuxt.config.js的plugins数组里正确登记,有没有写错文件路径
  • 检查插件的导出格式是否符合Nuxt的规范:有没有把插件写成了普通业务组件的导出逻辑,没有按照插件的签名传入上下文
  • 如果是Nuxt 3项目,需要匹配对应的插件写法:Nuxt 3不再支持直接通过插件入参解构store,需要通过defineNuxtPlugin获取nuxtApp上下文,再从中取到对应的store实例

内容的提问来源于stack exchange,提问作者paddyfields

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 12:54:04