intlify / vue-cli-plugin-i18n

:globe_with_meridians: Vue CLI plugin to add vue-i18n to your Vue Project
MIT License
195 stars 41 forks source link

TypeError: _ctx.$tc is not a function #214

Closed coddo closed 3 years ago

coddo commented 3 years ago

Module versions

To Reproduce

This error is encountered when upgrading the plugin from v1.x to v2.x. In my case, I went from v1.0.1 to v2.1.1.

I am using Vue 3 with composition API and single-file components.

Steps to reproduce the behavior:

  1. Create new application and add the vue 18n plugin version 1.0.1
  2. Create a translation json file in locales containing a message with key test_message and value Apple | Apples
  3. Add in the template the following 2 elements: <p>{{ $tc('test_message', 1) }}</p> and <p>{{ $tc('test_message', 2) }}</p>
  4. The texts are displayed correctly
  5. Update vue-cli-plugin-i18n to the latest version (v2.1.1)
  6. After the update, when calling createI18n({}), the following options are now also needed: globalInjection: true and legacy: false
  7. The page fails to render and the following error can be seen in the javascript console: TypeError: _ctx.$tc is not a function

Expected behavior

Everything should work normally as with the previous version and I should see the difference in pluralization on the 2 elements.

I get the same issue when trying to call the tc function in Typescript:

import { createI18n, LocaleMessageDictionary, VueMessageType } from 'vue-i18n';
import requireContext from 'require-context.macro';

function loadLocaleMessages(): Record<string, LocaleMessageDictionary<VueMessageType>> {
    const locales = requireContext('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i);
    const messages: Record<string, LocaleMessageDictionary<VueMessageType>> = {};

    locales.keys().forEach((key) => {
        const locale = key.split('/')[1];

        messages[locale] = { ...messages[locale], ...locales(key).default };
    });

    return messages;
}

const i18nModule = createI18n({
    locale: process.env.VUE_APP_I18N_LOCALE || 'en',
    fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
    silentTranslationWarn: true,
    globalInjection: true,
    legacy: false,
    messages: loadLocaleMessages(),
});

const i18n = i18nModule.global;

i18n.tc('test_message', 1)

Additional context

To be noted that the $t() function still works normally, just the $tc() one gets broken. I haven't tested other functions.

GeekyMonkey commented 3 years ago

Having the same problem in Quasar with vue-i18n-next

kazupon commented 3 years ago

legacy: false,

If you specify lategy: false options in createI18n, tc is no longer supported in composition API mode, since it has been merged into t.

See the API docs: https://vue-i18n.intlify.dev/api/composition.html

Thanks!