Laravel+Vue项目中laravel-translatable在Vue组件返回全量翻译问题求助
Laravel + Vue 架构下 laravel-translatable 多语言适配失效解决方案
核心故障原因
你遇到的问题本质是纯Laravel时代的多语言机制,完全适配不了SPA前后端分离的运行逻辑,两个核心矛盾点没解决:
- 原来靠路由Prefix给应用设locale的逻辑,只对渲染Blade页面的Web请求生效,对前后端分离后的API请求根本没有传导性。Laravel端根本不知道前端现在切到了阿拉伯语还是英语,
App::setLocale()永远卡在配置里的默认语言值。 laravel-translatable本身的序列化逻辑就是这样:你在Blade里写$post->title取内容,它会根据当前应用的locale自动返回对应语言的字符串;但你直接把模型扔到接口里序列化返回,它就会把数据库里存的整个JSON翻译对象原封不动吐出来,也就是你看到的{en: "Hello", ar: "مرحبا"}结构,根本不会主动帮你提当前locale的单值。
落地解决步骤
第一步:把前后端的语言环境打通
- 别再想着靠路由Prefix给API传语言了,直接在前端的axios封装里加个请求拦截器,把当前vue-i18n的激活语言值,塞到自定义请求头(比如
X-App-Locale)里,每个发去Laravel的API请求都带上这个值。 - 在Laravel写个专门给API用的中间件,替代原来Web端的locale逻辑:读请求头里传过来的语言值,先校验下是不是你系统支持的语言列表里的项,是就执行
App::setLocale($locale)把当前应用语言设对,不是就回退到默认语言。记得把这个中间件挂到api中间件组上,别挂错地方,不然接口请求跑的时候根本触发不了。
第二步:解决模型序列化透传全量翻译的问题
这步是解决全量翻译透传的关键,两种选法,根据项目规模挑:
- 项目规模大、接口结构复杂的话,直接用Laravel自带的API资源类做转换。别直接把
Post::find(1)这种模型实例当响应返回,给每个接口写对应的Resource类,在类里直接写'title' => $this->title就行——这时候前面中间件已经把当前locale设对了,trait会自动返回对应语言的单值字符串,根本不会把全量翻译对象吐出去。 - 项目规模小、嫌写Resource麻烦的话,就在用了
Translatabletrait的模型里重写下toArray()方法,遍历所有翻译字段,把当前locale对应的单值替换掉原来的嵌套全量对象,序列化出来的结构就是前端要的单值字符串。
别踩这些坑
- 最不可取的做法就是拿到后端传的全量翻译对象,在前端自己根据i18n的当前语言取值。这种做法会直接丢掉后端的翻译fallback逻辑:比如某个字段在阿拉伯语里没写翻译,后端本来会自动回退返回英语的内容,你前端自己拆的话就会拿到空值,甚至把未翻译的JSON结构直接露给用户。
- 注意中间件的执行顺序,设locale的逻辑必须在所有模型查询、数据处理之前跑,要是先查了数据再设locale,整个适配逻辑直接失效。
- 不用把原来Web端的路由Prefix多语言逻辑删干净,新的API中间件和老逻辑做个兼容,原来的非SPA页面正常跑就行,不用重构老代码。
内容的提问来源于stack exchange,提问作者Jad es
相关产品推荐
相关产品推荐

