[Nuxt, i18n, Vuex]:如何从商店getter访问this.$i 18n.locales



我正在使用Nuxt v2.15和@nuxtjs/i18n v7.2构建一个Web应用程序。我正在使用 Vuex 进行状态管理。在我的全局状态下,我想创建一个基于this.$i18n.locale返回值的 getter 。

在我的 Vuex getter 方法中访问当前附加了$i18n的应用程序上下文的最佳方式是什么?

nuxt.config.js

export default {
modules: [
"@nuxtjs/i18n", // https://i18n.nuxtjs.org/
],
i18n: {
locales: { /* configuration */ },
defaultLocale: "en",
detectBrowserLanguage: {
fallbackLocale: "en",
redirectOn: "root",
},
langDir: "~/locales/",
vueI18n: {
fallbackLocale: "en",
messages: { /* translation data */ },
},
},
};

存储/索引.js

export const state = () => ({
// Root module for Vuex store: https://nuxtjs.org/docs/directory-structure/store/
});
export const getters = {
loginOpts() {
const locale = this.$i18n.locale;
const uiLocales = [locale];
if (locale === "zh") {
uiLocales.push("zh-CN");
}
return { params: { ui_locales: uiLocales } };
},
};

components/login.vue

<template>
<div>
<v-btn v-if="$auth.loggedIn" @click="$auth.logout()">Sign Out</v-btn>
<v-btn v-else @click="$auth.loginWith('auth0', $store.getters.loginOpts)">Sign In</v-btn>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "Login",
data() {
return {};
},
computed: {
...mapGetters(["loginOpts"]),
},
};
</script>

我的期望

我希望能够从 Vuex getter 访问this.$i18n,或者有一些这样做的方法。

实际发生的情况

在 getter 方法中,this是未定义的。

TypeError: Cannot read properties of undefined (reading '$i18n')

我尝试过什么

我在这里看到一个getter被传递了四个参数:stategettersrootStaterootGetters

我试过:

  • RTFM for Vuex State, Getters, and Nuxt i18n
  • 访问state.$i18n
  • $i18n: this.$i18n添加到根状态

上周我遇到了类似的问题,我绝对需要在 vuex getter 中使用 i18n。

我不推荐这样做,因为它可能不是世界上性能最好的东西,但它对我有用,并在我处理政府应用程序时解决了一个巨大的问题。

components/login.vue

<template>
<div>
<v-btn v-if="$auth.loggedIn" @click="$auth.logout()">Sign Out</v-btn>
<v-btn v-else @click="$auth.loginWith('auth0', theLoginOpts)">Sign In</v-btn>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "Login",
data() {
return {
theLoginOpts: $store.getters.loginOpts(this) // The secret sauce
};
},
computed: {
...mapGetters(["loginOpts"]),
},
};
</script>

存储/索引.js

export const state = () => ({
// Root module for Vuex store: https://nuxtjs.org/docs/directory-structure/store/
});
export const getters = {
loginOpts: (state) => (app) => { // App is the secret sauce from earlier
const locale = app.$i18n.locale;
const uiLocales = [locale];
if (locale === "zh") {
uiLocales.push("zh-CN");
}
return { params: { ui_locales: uiLocales } };
},
};

在挖掘文档、实验并与那些好心地在这里提供答案的人讨论之后,很明显i18n不能在 Vuex getter 方法中直接访问,尽管 @nuxt/i18n 注册了一个名为i18n的 Vuex 模块,而且我读到的关于 Vuex 模块的所有内容都表明这应该是可能的。

然而,我确实遇到了 @nuxt/i18n 回调的文档,这导致我创建了一个小插件,该插件使用突变在全局状态下设置localeuiLocales的值。

最终结果如下所示:

nuxt.config.js

export default {
modules: [
"@nuxtjs/i18n", // https://i18n.nuxtjs.org/
],
plugins: [
"~/plugins/i18n.js",
],
i18n: {
locales: { /* configuration */ },
defaultLocale: "en",
detectBrowserLanguage: {
fallbackLocale: "en",
redirectOn: "root",
},
langDir: "~/locales/",
vueI18n: {
fallbackLocale: "en",
messages: { /* translation data */ },
},
},
};

插件/i18n.js

export function findLocaleConfig (i18n, locale) {
return (
i18n.locales.find(({ iso, code }) => [iso, code].includes(locale)) || {}
);
}
export default function ({ app }) {
app.store.commit("localeChange", findLocaleConfig(app.i18n, app.i18n.locale));
app.i18n.onLanguageSwitched = (oldLocale, newLocale) => {
app.store.commit("localeChange", findLocaleConfig(app.i18n, newLocale));
};
}

存储/索引.js

export const state = () => ({
locale: null,
uiLocales: [],
});
export const mutations = {
localeChange(state, locale) {
state.locale = locale.code;
state.uiLocales = [locale.code, locale.iso];
},
};

components/login.vue

<template>
<div>
<v-btn v-if="$auth.loggedIn" @click="$auth.logout()">Sign Out</v-btn>
<v-btn v-else @click="$auth.loginWith('auth0', loginOpts)">Sign In</v-btn>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {};
},
computed: {
loginOpts() {
const uiLocales = this.$store.state.uiLocales;
return { params: { ui_locales: uiLocales } };
},
},
};
</script>

你可以通过以下方式访问 Vuex 操作中的语言环境:this.app.i18n.locale.
这不能在stategetter中访问(无论如何,getter 都不是它的地方 IMO)。

PS:以上意味着您可以在任何可以访问Nuxt上下文的地方访问此值。

我们在项目中所做的简单方法如下: 在组件计算道具中

teamsForSelector() {
return this.$store.getters['company/teamsForSelector'](this.$i18n);
}

和状态获取者

teamsForSelector: (state) => ($i18n) => {
const teamsForSelector = state.teams.map((team) => {
return {
id: team.teamUid,
label: team.teamName,
};
});
teamsForSelector.unshift({
id: 'all-teams',
label: $i18n.t('key'),
});

返回团队选择器; }

在Nuxt 2中,如果您的页面在前端呈现,您可以尝试使用window.$nuxt或简单地$nuxt访问$i18n

export const getters = {
loginOpts() {
const locale = window.$nuxt.$i18n.locale;
...
},
};

最新更新