- 背景:
我有一个 SPA (Vuejs),我在前端和后端都实现了本地化。当我更改语言时,内容已成功更新,无需重新加载页面。 - 问题:
但某些内容(如所选语言的产品描述)来自一个 API,当我更改语言时该 API 不会自动更新。如果我刷新页面或再次调用 API,它就可以工作。 - 问题:
在不刷新页面并手动调用所有 API 的情况下更改来自 API 的语言相关内容的最佳实践是什么。
谢谢!
3 回答
我相信有很多方法可以做你想做的事。例如。我们有一些模型有一些可以本地化的字段,但是我们只支持三种语言并且字段相对较短。
在这种情况下,我们只需让后端 rest api 返回字符串的所有本地化版本,例如:
GET /products 可能返回:
[{
sku: '1',
name: {
en: 'Product name',
nl: 'Productnaam',
fr: 'Nom du produit'
}
}]
然后我们根据路由参数在 VueJs 中显示... {{product.name[$route.params.locale] || product.name[en]}} (我们有一个可组合的方法来代替,但你明白了。
但是,对于某些端点,您可能并不总是希望返回服务器的所有本地化版本,只是因为它太大(例如,您在支持 5 种语言时以多种语言发布的博文可能只会生成您不想要的有效负载到...)
在这种情况下,您可以在 vuejs 中观察您的语言环境的变化,并获取本地化版本。
第三种选择,我不喜欢自己,是让“语言切换”基本上重新加载整个页面......
无论哪种方式 - 有很多方法可以满足您的需求,这完全取决于您的用例和您的个人偏好。
When using the vue-i18n Plugin, instead of sending the localised Text from the backend you could just send variables like exampleText and have them translated in your vue code with {{$t(yourLangVar)}} and this.$t(yourLangVar)
我设法做到了,我不知道这是否是最佳实践,但它是一个可行的解决方案,对其他人有用:
应用程序.vue:
- 我有一个组件会在每次语言更改时
LocaleChanger发出。localChanged - 视图已加载,
router-view因此我将其添加rerenderKey到其键中。并且当它被改变时,所有的东西都会在当前视图中重新渲染(包括相应组件的API)。 - 而且由于我的所有 API 都在其中被调用,它们将被再次调用。
<template>
<LocaleChanger @localChanged="forceRerender"/>
<div id="nav">
<router-link :to="{ name: 'Home', params: {'lang':$i18n.locale}}">{{$t('pages.home')}}</router-link> |
</div>
<router-view :key="rerenderKey"></router-view>
</template>
<script>
data () {
return {
rerenderKey: 0
};
},
methods: {
async forceRerender(){
await this.$router.push({name: this.$route.name, params: { ...this.$route.params, lang: this.$i18n.locale }})
this.rerenderKey += 1;
},
}
</script>
And since my API-s need the Accept-language header, I added it in main.js to the axios.interceptors.request
axios.interceptors.request.use(
function (config) {
config.headers['Accept-Language'] = store.state.locale;
return config;
},
function (error) {
return Promise.reject(error);
}
);