Skip to content

Carga perezosa

Cargar todos los archivos de localización a la vez es innecesario y excesivo.

La carga perezosa o la carga asíncrona de los archivos de localización es realmente fácil cuando se usa un empaquetador (bundler).

Supongamos que tenemos un directorio de proyecto similar al siguiente:

txt
├── dist
├── index.html
├── package.json
├── src
│   ├── App.vue
│   ├── components
│   ├── i18n.js
│   ├── index.css
│   ├── locales
│   │   ├── en.json
│   │   └── ja.json
│   ├── main.js
│   ├── pages
│   │   ├── About.vue
│   │   └── Home.vue
│   └── router.js

La carpeta pages es donde residen nuestros archivos de componentes Vue arbitrarios como About.vue, inicializaciones del router, inicializaciones del i18n y otros. La carpeta locales es donde se encuentran todos nuestros archivos de localización, y en i18n.js, las funciones para el proceso relacionado con el i18n están definidas como sigue:

js
import { nextTick } from 'vue'
import { createI18n } from 'vue-i18n'

export const SUPPORT_LOCALES = ['en', 'ja']

export function setupI18n(options = { locale: 'en' }) {
  const i18n = createI18n(options)
  setI18nLanguage(i18n, options.locale)
  return i18n
}

export function setI18nLanguage(i18n, locale) {
  if (i18n.mode === 'legacy') {
    i18n.global.locale = locale
  } else {
    i18n.global.locale.value = locale
  }
  /**
   * NOTA:
   * Si necesita especificar la configuración del idioma para encabezados, tales como la API `fetch`, configúrela aquí.
   * El siguiente es un ejemplo para axios.
   *
   * axios.defaults.headers.common['Accept-Language'] = locale
   */
  document.querySelector('html').setAttribute('lang', locale)
}

export async function loadLocaleMessages(i18n, locale) {
  // cargar mensajes de localización con importación dinámica
  const messages = await import(
    /* webpackChunkName: "locale-[request]" */ `./locales/${locale}.json`
  )

  // establecer localización y mensaje de localización
  i18n.global.setLocaleMessage(locale, messages.default)

  return nextTick()
}

Se exportan las siguientes tres funciones:

  • setupI18n
  • setI18nLanguage
  • loadLocaleMessages

TIP

Este ejemplo de código también muestra cómo manejarlo fuera del componente usando la propiedad global de la instancia i18n. Sobre la instancia i18n, consulte la Referencia de API

La función setupI18n toma las mismas opciones que createI18n, crea una instancia de i18n con esas opciones, ejecuta la función setI18nLanguage y devuelve la instancia i18n.

La función setI18nLanguage establece el idioma configurando la localización del parámetro i18n al valor del parámetro locale. Además, esta función tiene la utilidad de establecer el atributo lang del documento HTML al valor del parámetro locale. Como se indica en los comentarios, como cliente HTTP, también puede establecer el idioma.

La función loadLocaleMessages es lo que realmente usaremos para cambiar los idiomas. La carga de nuevos archivos se realiza mediante la función import, que es generosamente proporcionada por webpack y nos permite cargar archivos dinámicamente, y como utiliza promesas, podemos esperar fácilmente a que termine la carga.

Puede obtener más información sobre la función import en la documentación de webpack.

Usar la función loadLocaleMessages es sencillo. Un caso de uso común es dentro de un hook beforeEach de vue-router.

Aquí está el código para la parte del hook beforeEach de vue-router en router.js:

js
  // guardias de navegación
  router.beforeEach(async (to, from, next) => {
    const paramsLocale = to.params.locale

    // usar localización si paramsLocale no está en SUPPORT_LOCALES
    if (!SUPPORT_LOCALES.includes(paramsLocale)) {
      return next(`/${locale}`)
    }

    // cargar mensajes de localización
    if (!i18n.global.availableLocales.includes(paramsLocale)) {
      await loadLocaleMessages(i18n, paramsLocale)
    }

    // establecer idioma i18n
    setI18nLanguage(i18n, paramsLocale)

    return next()
  })