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

如何在Pinia Store中正确使用vue-i18n?

在Pinia Store中正确使用vue-i18n的方法

问题背景

你尝试在Pinia Store的actions中使用vue-i18n时遇到两种报错:

  • 使用this.$t时,报错TypeError: this.$t is not a function——因为Pinia的store实例未挂载$t方法。
  • 在action内部调用useI18n()时,报错Must be called at the top of a setup function——因为useI18n()只能在Vue组件或Pinia的setup写法顶层调用。

解决方案

方法一:直接导入已创建的i18n实例(适用于选项式Pinia Store)

你已经提前创建并导出了i18n实例,直接导入后通过i18n.global.t()即可在actions中使用翻译功能,无需依赖setup上下文。

修改后的代码示例:

// 导入你的i18n实例(替换为实际文件路径)
import { i18n } from '@/path/to/your/i18n-config-file'
import { useBanner } from '@/stores/banner'
import todoService from '@/services/todoService'

export const useTodos = defineStore("todos", {
    state: () => ({
        todos: [],
    }),
    actions: {
        async addTodo(todo) {
            const bannerStore = useBanner()
            try {
                const res = await todoService.addTodo(todo)
                if (res.status === 201) {
                    this.todos.push(todo)
                    // 使用i18n.global.t获取翻译文本
                    bannerStore.setBanner(i18n.global.t('successAddSticky'), 'success')
                }
            } catch (error) {
                // 用翻译键+插值参数优化错误提示
                const errorMsg = i18n.global.t('errorAddTodo', { 
                    todo: JSON.stringify(todo), 
                    error: error.message 
                })
                bannerStore.setBanner(errorMsg, 'error')
            }
        },
    }
})

方法二:使用Pinia的setup写法(推荐)

如果采用Pinia的setup风格定义store,可以在store的setup函数顶层调用useI18n(),之后在actions中直接使用返回的t函数。

代码示例:

import { defineStore, ref } from 'pinia'
import { useI18n } from 'vue-i18n'
import { useBanner } from '@/stores/banner'
import todoService from '@/services/todoService'

export const useTodos = defineStore("todos", () => {
    const todos = ref([])
    // 在setup顶层调用useI18n
    const { t } = useI18n()
    const bannerStore = useBanner()

    const addTodo = async (todo) => {
        try {
            const res = await todoService.addTodo(todo)
            if (res.status === 201) {
                todos.value.push(todo)
                bannerStore.setBanner(t('successAddSticky'), 'success')
            }
        } catch (error) {
            const errorMsg = t('errorAddTodo', { 
                todo: JSON.stringify(todo), 
                error: error.message 
            })
            bannerStore.setBanner(errorMsg, 'error')
        }
    }

    return { todos, addTodo }
})

说明

  • 方法一无需修改store的定义风格,适合已有选项式store的场景。
  • 方法二更贴合Vue 3的Composition API风格,逻辑更集中,推荐新项目使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:23:33