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

问题描述 投票:0回答:5

我正在使用 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 */ },
    },
  },
};

商店/index.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 } };
  },
};

组件/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')

我尝试过的

我看到here getter 传递了四个参数:

state
getters
rootState
rootGetters

我已经尝试过:

  • 用于 Vuex 的 RTFM StateGettersNuxt i18n
  • 访问
    state.$i18n
  • $i18n: this.$i18n
    添加到根状态
javascript vue.js nuxt.js vuex nuxt-i18n
5个回答
2
投票

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

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

组件/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>

商店/index.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 } };
  },
};

1
投票

在深入研究文档、进行实验并与在此提供答案的人们进行讨论后,很明显,

i18n
不能在 Vuex getter 方法中直接访问,尽管 @nuxt/i18n 注册了一个Vuex 模块 称为
i18n
,我读过的有关 Vuex 模块 的所有内容都表明这应该是可能的。

不过,我确实遇到了 @nuxt/i18n 回调的文档,这让我创建了一个小型 插件,它使用

mutation
在全局状态中设置
locale
uiLocales 的值。

最终结果如下所示:

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));
  };
}

商店/index.js

export const state = () => ({
  locale: null,
  uiLocales: [],
});

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

组件/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>

0
投票

您可以通过以下方式访问 Vuex 操作中的语言环境:

this.app.i18n.locale

这不能在
state
getter
中访问(在我看来,吸气剂无论如何都不是它的位置)。

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


0
投票

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

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'),
});

返回teamsForSelector; }


0
投票

我知道已经晚了,但也许这对某人有用。

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

访问 $i18n
export const getters = {
  loginOpts() {
    const locale = window.$nuxt.$i18n.locale;
    ...
  },
};
© www.soinside.com 2019 - 2024. All rights reserved.