Динамическое изменение локали в приложении Vue не обновляет переведенные значения на страницах - PullRequest
0 голосов
/ 20 марта 2020

У меня есть приложение big-i sh Vue (использующее Vuetify), и я недавно включил в него vue-i18n. У меня настроены и работают мои файлы перевода json, и мои звонки на $t() работают нормально в моих компонентах и ​​других .js файлах. Однако я не смог изменить локаль на лету, чтобы текст во всех моих переведенных полях отображал соответствующий язык. Если я изменяю определение new Vue18n({}) и сохраняю файл, он работает нормально, и все мои переведенные значения отображаются нормально.

В моем случае, у меня есть выбор в качестве пунктов меню,

    <v-icon color="primary" dark slot="activator">
        person
    </v-icon>
    <v-list dark class="primary">
      <v-list-tile>
        <v-list-tile-title>{{ getUser.userId }}</v-list-tile-title>
      </v-list-tile>

      <v-divider />

      <v-list-tile @click="passDialog = !passDialog">
        <v-list-tile-title>Password</v-list-tile-title>
      </v-list-tile>
      <v-list-tile @click="logoutClick">
        <v-list-tile-title>Logout</v-list-tile-title>
      </v-list-tile>
      <v-list-tile>
        <v-list-tile-title @click="setLocale('en')">English</v-list-tile-title>
      </v-list-tile>
      <v-list-tile>
        <v-list-tile-title @click="setLocale('es')">Spanish</v-list-tile-title>
      </v-list-tile>
    </v-list>

и обработчик кликов, который передает соответствующий языковой стандарт методу:

setLocale(locale) {
  this.$root.$i18n.locale = locale;
},

, где здесь определено VueI18n:

import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

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

export default new VueI18n({
  locale: 'en',
  localeDir: 'locales',
  fallbackLocale: 'en',
  messages: loadLocaleMessages(),
});

Я также пробовал варианты, такие как

this.$i18n.locale = locale;

и

i18n.locale = locale;

после выполнения также

import i18n from `@/i18n'; 

в компоненте. Тем не менее, почти никто из них не меняет все значения моего имени поля, которые имеют переводы. Это похоже на то, как если бы я изменил переведенные значения после изменения языка.

Есть ли что-то другое, что мне нужно сделать, чтобы все мои переведенные значения обновлялись, как только я Вы выбрали другой язык?

ОБНОВЛЕНИЕ: Основываясь на приведенном ниже комментарии Ромена Винсента, я понял, что пропустил важную часть своей настройки. Существует несколько атрибутов Vuetify для каждого поля, и они извлекаются в отдельный файл fields.js. Например, вот пара определений полей из шаблона:

<v-layout row>
  <v-flex xs6>
    <v-text-field 
      v-bind="fields.userId" 
      v-model="userModel.userId"
      :disabled="!canSave"
    />
  </v-flex>
  <v-flex xs6>
    <v-text-field v-bind="fields.id" v-model="userModel.id" disabled />
  </v-flex>
</v-layout>

...

import { fields, buttons, csvFields } from '@/components/config/users';

...

data: () => ({
    fields,
...
})

, а затем вот fields.js:

import RuleGenerator from '@/utils/RuleGenerator';
import i18n from '@/i18n';

const fields = {
  userId: {
    label: i18n.t('users.generalInfo.userId'),
    // Set label to 'Email' because the username is required to be an email address.
    rules: new RuleGenerator('Email')
      .setRequired()
      .setMin(1)
      .setMax(255)
      // eslint-disable-next-line no-useless-escape
      .setRegEx(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)
      .getRules(),
    hint: 'Must be a valid email address',
    counter: '255',
  },
  id: {
    label: i18n.t('users.generalInfo.id'),
  },
};

export default fields;

Именно эти поля не меняют локали. Однако, если я связываю label непосредственно в компоненте:

<v-text-field 
  v-bind="fields.userId" 
  v-model="userModel.userId"
  :disabled="!canSave"
  :label="$t('users.generalInfo.userId')"
/>

при изменении локали значение метки обновляется очень хорошо. Таким образом, наличие этого связанного файла, похоже, является проблемой, даже если он включает i18n.js, в котором установлено locale.

ОБНОВЛЕНИЕ 2: Кажется, другие люди столкнулись с эта проблема тоже ( см. эту проблему GitHub ).

...