Vue 2.6.14集成vue-i18n 6.1.3刷新后报TypeError: _vm.$t is not a function
解决Vue SSR(Genesis框架)中vue-i18n刷新后$t不存在的问题
问题原因
在SSR场景下,直接导出单例的vue-i18n实例会引发两个核心问题:
- 服务端渲染时实例被复用,存在请求间的状态污染风险
- 客户端刷新页面后,无法正确承接服务端传递的i18n状态,导致Vue实例未挂载i18n,最终出现
_vm.$t is not a function错误
解决方案
1. 将i18n初始化改为工厂函数模式
修改langurage/index.ts,用工厂函数创建i18n实例,避免单例带来的状态污染:
// langurage/index.ts import Vue from 'vue'; import VueI18n from 'vue-i18n'; // 必须先安装VueI18n插件,否则Vue不会挂载$t方法 Vue.use(VueI18n); /** * 创建i18n实例的工厂函数 * @param options 初始化参数(locale、messages等) */ export function createI18n(options = {}) { return new VueI18n({ locale: options.locale || 'zh-CN', fallbackLocale: 'zh-CN', messages: options.messages || { 'zh-CN': require('./zh-CN.json'), 'en-US': require('./en-US.json') } }); }
2. 客户端入口复用服务端状态
在entry-client.ts中,读取服务端注入的初始状态,基于该状态创建i18n实例:
// entry-client.ts import { ClientOptions } from '@fmfe/genesis-core'; import { createClientApp } from '@fmfe/genesis-app'; import { createI18n } from './langurage'; import Vue from 'vue'; import App from './app.vue'; export default async (clientOptions: ClientOptions): Promise<Vue> => { // 读取Genesis框架注入的服务端初始状态 const initialState = window.__INITIAL_STATE__ || {}; // 基于服务端状态创建i18n实例,保证前后端状态一致 const i18n = createI18n({ locale: initialState.locale || 'zh-CN', messages: initialState.messages || { 'zh-CN': require('./zh-CN.json'), 'en-US': require('./en-US.json') } }); return createClientApp({ App, clientOptions, vueOptions: { i18n } }); };
3. 服务端入口注入i18n状态
在entry-server.ts中,根据请求生成对应i18n实例,并将状态注入到客户端:
// entry-server.ts import { ServerOptions } from '@fmfe/genesis-core'; import { createServerApp } from '@fmfe/genesis-app'; import { createI18n } from './langurage'; import Vue from 'vue'; import App from './app.vue'; export default async (serverOptions: ServerOptions): Promise<Vue> => { // 从请求头获取用户偏好语言,兼容默认值 const reqLocale = serverOptions.req.headers['accept-language']?.split(',')[0] || 'zh-CN'; const locale = ['zh-CN', 'en-US'].includes(reqLocale) ? reqLocale : 'zh-CN'; // 加载对应语言包 const messages = { 'zh-CN': require('./zh-CN.json'), 'en-US': require('./en-US.json') }; // 创建服务端专属的i18n实例 const i18n = createI18n({ locale, messages }); // 将i18n状态注入到初始状态,供客户端复用 serverOptions.setInitialState({ locale, messages }); return createServerApp({ App, serverOptions, vueOptions: { i18n } }); };
关键注意事项
Vue.use(VueI18n)必须在创建i18n实例前执行,否则Vue不会挂载$t等国际化方法- SSR场景下禁止使用单例i18n实例,必须通过工厂函数每次创建新实例,避免请求间的状态污染
- 客户端必须复用服务端传递的i18n状态,既保证前后端渲染结果一致,也避免刷新后i18n未正确初始化
内容的提问来源于stack exchange,提问作者z_ning
相关产品推荐
相关产品推荐

