@D_K_D
Junior

Как поменять язык в vue-i18n?

С помощью vue add i18n добавил в только что созданный проект i18n. Файлы i18n.js и main.js не трогал. В компоненте пытаюсь изменить язык как в видео YouTube , но выдаёт ошибку. Причём если руками в i18n.js меняю locale то всё работает.

Ошибка:
runtime-core.esm-bundler.js?5c40:218 Uncaught TypeError: Cannot read properties of undefined (reading '$i18n')
at Proxy.changeLocal (Header.vue?0418:14:1)
at Object.onClick._cache.._cache. (Header.vue?0418:2:1)
at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:155:1)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:164:1)
at HTMLDivElement.invoker (runtime-dom.esm-bundler.js?830f:366:1)


i18n.js
import { createI18n } from 'vue-i18n';

function loadLocaleMessages() {
    const locales = require.context(
        './locales',
        true,
        /[A-Za-z0-9-_,\s]+\.json$/i
    );
    const messages = {};
    locales.keys().forEach((key) => {
        const matched = key.match(/([A-Za-z0-9-_]+)\./i);
        if (matched && matched.length > 1) {
            const locale = matched[1];
            messages[locale] = locales(key).default;
        }
    });
    return messages;
}

export default createI18n({
    sync: true,
    locale: 'ru',
    fallbackLocale: 'en',
    messages: loadLocaleMessages(),
});


main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import i18n from './i18n'

createApp(App).use(i18n).use(store).use(router).mount('#app')


Компонент , где хочу поменять язык
<template>
    <div class="header" @click="changeLocal()">
        {{ $t('message') }}
    </div>
</template>

<script>
export default {
    name: 'Header',
    setup() {
        const changeLocal = () => {
            this.$i18n.locale = 'en';
        };
        return { changeLocal };
    },
};
</script>
  • Вопрос задан
  • 827 просмотров
Решения вопроса 1
chincharovpc
@chincharovpc
Вот работающий пример смены языка, думаю, разберешься сам

Компонент Locale.vue
<template>
  <div>
    <v-select
        v-model="locale"
        :items="locales"
        item-text="locale"
        item-value="locale"
        append-icon=""
        class="locale"
    >
    </v-select>
  </div>
</template>

<script>
import {loadLanguageAsync} from "@/locales/i18n";
import config from "@/config";

export default {
  name: "Locale",
  data: function () {
    return {
      locales: config.locales
    }
  },
  computed: {
    locale: {
      get: function () {
        return {locale: this.$i18n.locale}
      },
      set: function (locale) {
        loadLanguageAsync(locale)
      }
    },
  },
  created() {
    loadLanguageAsync(localStorage.getItem('lang'))
  }
}
</script>


Скрипт i18n.js
Доступные языки беру из config.js
JS файлы с языками находятся в @/locales/lang/(en.js, ru.js)
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import axios from 'axios'
import config from "@/config";
import messages from "@/locales/lang/en.js"

Vue.use(VueI18n)

export const i18n = new VueI18n({
    locale: "en",
    fallbackLocale: "en",
    messages: {
        "en": messages
    }
    })
const loadedLanguages = ["en"]

function setLanguage(lang) {
    i18n.locale = lang
    document.querySelector('html').setAttribute('lang', lang)
    return lang
}

export function loadLanguageAsync(lang) {
    let language = lang
    if (config.locales.findIndex(locale => locale.locale === lang) === -1) {
        language = config.defaultLocale
    }

    localStorage.setItem('lang', language)

    // If the same language
    if (i18n.locale === language) {
        return Promise.resolve(setLanguage(language))
    }

    // If the language was already loaded
    if (loadedLanguages.includes(language)) {
        return Promise.resolve(setLanguage(language))
    }

    // If the language hasn't been loaded yet
    return import(`@/locales/lang/${language}.js`).then(
        messages => {
            i18n.setLocaleMessage(language, messages.default)
            loadedLanguages.push(language)
            return setLanguage(language)
        }
    )
}


Скрипт main.js
import Vue from 'vue'
import App from '@/App.vue'
import {i18n} from "@/locales/i18n";


new Vue({
    render: h => h(App),
    i18n,
}).$mount('#app')
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы