kazupon / vue-i18n

:globe_with_meridians: Internationalization plugin for Vue.js
https://kazupon.github.io/vue-i18n/
MIT License
7.28k stars 861 forks source link

Dynamic multiple translations for a same component #830

Open rulrok opened 4 years ago

rulrok commented 4 years ago

I guess this could be sort of a bug or a feature request.

vue & vue-i18n version

Vue: 2.6.11 Vue-i18n: 8.15.5

Reproduction Link

JSFiddle: https://jsfiddle.net/9vo61gLh/20/

Steps to reproduce

Change the language switch back and forth and see the text not being updated properly.

What is Expected?

I'm trying to dynamically set the $options.i18n value so each instance of a same component can have its own translation.

For doing so, I'm using the beforeCreate hook, so I can also use this solution on SSR projects with no pain.

I pass a object as a prop to my component

<!-- I'm using i18n prop name just for the sake of it -->
<d-hi :i18n="dynamicMessages1"/>

IF I DON'T HAVE AN EMPTY i18n option on my component declaration, vue-i18n doesn't even fire off here. Try erasing the empty i18n: { messages: {} } so you can see what I'm saying.

Vue.component('d-hi', {
    name: 'd-hi',
  template: '<p>{{$t("hi")}}</p>',
  i18n: {
    messages: {}
  },
  props: {
    i18n: {
        type: Object,
      required: false,
      default: () => undefined
    }
  },
  beforeCreate(){
    if(this.$options.i18n === undefined)
        return;

    Object.assign(
      this.$options.i18n.messages,
      this.$options.propsData.i18n.messages
    );
  }
});

What is actually happening?

At the first render, everything SEEMS alright. You can notice that the 'dynamic 1' renders with the '1' text and 'dynamic 2' with '2'.

But once you change the language switch back and forth, all instances of the d-hi component get applied with the last occurrence of d-hi component as it seems that $options.i18n is used globally instead of individually.

My project has the following need:

I have a site builder with customizable components. And the components have dynamic texts which I need to support i18n for the client building the page. So I have to support the client having my component dropped/reused multiple times throughout the page but each one having a different text and being able to i18n each one of them.

I'd also expect the fallback translations to work just as expected if the component don't define them by default.

limeandcoconut commented 4 years ago

Not having this is causing some serious headaches for my team

ianlchapman commented 4 years ago

Has anyone got a workaround or a suggestion on how this can be done?