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

Vue3选项API下如何在Pinia Store中调用$toast?

问题:Pinia Store中调用@meforma/vue-toaster报错Can not read properties of undefined (reading 'success')

我正在使用Vue3选项API、Pinia以及@meforma/vue-toaster,已按文档要求在main.js中导入toaster,组件中使用完全正常。现需在Pinia Store的store.js中按如下代码调用$toast:

actions: {
    async login(data) {
      try {
        const res = await authService.login(data);
      
        if (res.data.msg == "success") {
        this.$toast.success("loged in successfully", {
              position: "bottom-right",
              duration: 3000,
              type: 'success',
            });
      }
        
      } catch (error) {
                  
        this.$toast.error(error.res.data.error, {
        position: "bottom-right",
         duration: 5000,
         type: 'error',
         });
         }
      }
    },
  }

但运行后报错:Can not read properties of undefined (reading 'success'),请问问题出在哪里?


问题原因

Pinia的Store实例和Vue组件实例是相互独立的。你在main.js里把toaster挂载到Vue全局属性$toast后,只有Vue组件实例能继承这个属性,而Store里的this指向的是Store自身,并没有$toast这个属性,所以会报undefined的错误。

另外你代码里还有个小问题:catch块里的error.res应该是error.response(Axios错误对象的响应属性是response),不然也会拿不到错误信息。

解决办法

方法1:直接导入全局toaster实例

在main.js里把全局的toaster实例导出,然后在Store里导入使用:

  1. 修改main.js:
import { createApp } from 'vue'
import App from './App.vue'
import Toaster from '@meforma/vue-toaster'
import { createPinia } from 'pinia'

const app = createApp(App)
const pinia = createPinia()

// 挂载toaster
app.use(Toaster)
app.use(pinia)

// 导出全局的toaster实例
export const toast = app.config.globalProperties.$toast

app.mount('#app')
  1. 在store.js里导入并使用:
import { defineStore } from 'pinia'
import { toast } from '../main'
import authService from './your-auth-service-path'

export const useAuthStore = defineStore('auth', {
  actions: {
    async login(data) {
      try {
        const res = await authService.login(data);
      
        if (res.data.msg == "success") {
          toast.success("logged in successfully", {
            position: "bottom-right",
            duration: 3000,
            type: 'success',
          });
        }
      } catch (error) {
        toast.error(error.response?.data?.error || '登录失败', {
          position: "bottom-right",
          duration: 5000,
          type: 'error',
        });
      }
    }
  }
})

方法2:通过Pinia插件全局注入toaster

如果项目里多个Store都需要用到toaster,可以封装成Pinia插件来全局注入:

  1. 创建pinia插件文件plugins/toaster.js:
import { toast } from '../main'

export function toasterPlugin({ store }) {
  store.$toast = toast
}
  1. 在main.js里注册插件:
import { createPinia } from 'pinia'
import { toasterPlugin } from './plugins/toaster'

const pinia = createPinia()
pinia.use(toasterPlugin)

app.use(pinia)
  1. 之后就能在Store的action里直接用this.$toast了,和你原来的代码写法一致,不用修改调用逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:24:20