vue-i18n icon indicating copy to clipboard operation
vue-i18n copied to clipboard

Trouble using this package effectively

Open marr opened this issue 1 year ago • 6 comments

Reporting a bug?

Hi, I appreciate all the work on this plugin / problem. That being said, I'm having major difficulty understanding basic usage and all the version / api changes are not making it any easier.

I am using Vue 2.7, and trying out the vue-i18n-bridge with a vite builder. I have the build working, but there is no cohesion to the api. The $t api basically becomes pointless when you do as suggested

setup() {
    const { t, locale } = useI18n({
      messages: {
        ja: {
          message: {
            cheers: '乾杯'
          }
        }
      }
    })
    return { t, locale }
  }

The only thing possible in this component now is to use the t method. $t does not find any messages. Basically the useI18n function creates a local-only method. None of the messages defined there are available in any of the child components either. I would expect the messages and locale to cascade down to children.

I made a barebones repo trying to illustrate usage of this plugin: https://github.com/marr/vue2-i18n/. The best thing to experiment with is the "change locale" button on the app. That only changes the local locale. If you change the locale in i18n.js to en and try the button you will see different behavior.

Thanks for any help.

Expected behavior

Messages and locales should cascade to children. This is similar to the provider pattern used by the context api in react. The component would use its closest provider of messages/locale.

Maybe that's not the "Vue" way. I am very new to Vue, so I'm just going off what I know from React.

Reproduction

Download and install https://github.com/marr/vue2-i18n/ and notice that the messages from the root i18n.js instance do not apply.

System Info

System:
    OS: macOS 12.4
    CPU: (10) x64 Apple M1 Pro
    Memory: 18.56 MB / 16.00 GB
    Shell: 5.1.8 - /usr/local/bin/bash5
  Binaries:
    Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
    Yarn: 1.22.15 - ~/.nvm/versions/node/v16.15.1/bin/yarn
    npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
  Browsers:
    Chrome: 103.0.5060.114
    Edge: 103.0.1264.62
    Firefox: 102.0.1
    Safari: 15.5
  npmPackages:
    @vue/test-utils: ^1.3.0 => 1.3.0
    vite: ^3.0.2 => 3.0.2
    vite-plugin-vue2: ^2.0.2 => 2.0.2
    vitest: ^0.15.2 => 0.15.2
    vue: ^2.7.7 => 2.7.7
    vue-demi: ^0.13.5 => 0.13.5
    vue-i18n: ^8.27.2 => 8.27.2
    vue-i18n-bridge: ^9.2.0-beta.39 => 9.2.0-beta.39

Screenshot

No response

Additional context

No response

Validations

marr avatar Jul 18 '22 19:07 marr

Thank you for your reporting! This issue is bug with vue-i18n v8 + vue-i18n-bridge I’ll try to fix this issue.

kazupon avatar Jul 19 '22 10:07 kazupon

As a workaround, you can use useScope: true for useI18n. Along with this option, the messages option will override any global scope definitions.

kazupon avatar Jul 19 '22 10:07 kazupon

@kazupon Thank you for the suggestion. Unfortunately that still has scoping trouble.

For example the useI18n method returns new t and locale values. It becomes disconnected from the $i18n object on the component. Is there something else needed to ensure changing $i18n.locale updates the locale returned from useI18n?

Also, can you explain how the i18n property within a component works? Is that now considered the "legacy" approach?

Talking about that:

export default {
  components: {
    HelloWorld,
    HelloI18n
  },

  methods: {
    changeLocale: function () {
      this.$i18n.locale = this.$i18n.locale === 'en' ? 'ja' : 'en'
    }
  },

// here
i18n: {
     messages: {
       ja: {
         message: {
           cheers: '乾杯'
         }
       }
     },
 },

I was hoping it would allow me to set overrides on top of the globally registered messages.

marr avatar Jul 19 '22 13:07 marr

Ok, I used useScope: 'global' in the component, and things work much better.

  1. $t and t appear to be interchangable (good).
  2. locale returned from useI18n appears to be interchangable with this.$i18n.locale (good).
  3. messages set in useI18n override the global messages (great)!

marr avatar Jul 19 '22 13:07 marr

I noticed the vue-i18n-bridge package has a dependency on @vue/composition-api -- that means you can't install vue 2.7 which may be an issue.

marr avatar Jul 19 '22 19:07 marr

@vue/composition-api is optionaled in vue-i18n-bridge from v9.2.0-beta.39 https://github.com/intlify/vue-i18n-next/blame/master/packages/vue-i18n-bridge/package.json#L79-L83

if you need vue-i18n-bridge in Vue 2.7, it doesn't need the installation.

kazupon avatar Jul 20 '22 07:07 kazupon