代码之家  ›  专栏  ›  技术社区  ›  Shaun Scovil

[Nuxt,i18n,Vuex]:如何访问它$i18n.storegetter中的区域设置

  •  0
  • Shaun Scovil  · 技术社区  · 3 年前

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

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

    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 */ },
        },
      },
    };
    

    store/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>
    

    我的期望

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

    实际发生了什么

    在吸气剂方法中, this 未定义。

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

    我尝试过的

    我明白了 here 向getter传递四个参数: state , getters , rootState rootGetters

    我尝试过:

    0 回复  |  直到 3 年前
        1
  •  1
  •   Simon K    3 年前

    上周我遇到了一个类似的问题,我绝对需要在vuexgetter中使用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>
    

    store/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 } };
      },
    };
    
        2
  •  1
  •   Shaun Scovil    3 年前

    经过对文档的挖掘、实验,并与那些好心在这里提供答案的人讨论,很明显 i18n 在Vuex getter方法中不能直接访问,尽管 @nuxt/i18n registers a Vuex module 调用 i18n 以及我读到的一切 Vuex modules 表明这应该是可能的。

    然而,我确实看到了 @nuxt/i18n callbacks ,这让我创建了一个 plugin 设置的值 locale uiLocales 在全局状态下使用 mutation

    最终结果如下:

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

    store/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>
    
        3
  •  0
  •   kissu    3 年前

    您可以通过以下方式访问Vuex操作中的区域设置: this.app.i18n.locale
    无法在 state getter (无论如何,国际海事组织都不适合吸气剂)。

    PS:上面的意思是,你可以在任何你可以访问的地方访问这个值 Nuxt context

        4
  •  0
  •   Kerim Balayev    2 年前

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

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

    和状态中的getter

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

    return teamsForSelector; }

    推荐文章