jshmrtn / vue3-gettext

Translate Vue 3 applications with gettext.
https://jshmrtn.github.io/vue3-gettext/
MIT License
66 stars 23 forks source link

LanguageVmMixin option #32

Closed Wewill closed 1 year ago

Wewill commented 1 year ago

Hello,

I used for a long time vue-gettext for VUE2 ; I'm very glad to found your project.

But there is an option it can't provide :

...
 languageVmMixin: {
    computed: {
      currentKebabCase: function () {
        return this.current.toLowerCase().replace("_", "-");
      },
      currentLang: function () {
        return this.current.replace("_", "-");
      },
    },
    watch: {
      currentLang: function (n, o) {
        console.log("GetTextPlugin:: currentLang o > n ", o, n);
        // Then change html lang attr
        if (n) document.documentElement.setAttribute("lang", n);
      },
    },
  },

Regarding to VUE2 documentation :

languageVmMixin {Object} optional A mixin that will be passed to the main languageVminstance (exposed via $language) that can be used, for example, to add custom computed properties

Well this option was very useful in many cases ; can you help me on this ?

Best regards, Wilhem

lzurbriggen commented 1 year ago

hi @Wewill We decided to omit this feature because it's kinda problematic with typescript (e.g. regarding ComponentCustomProperties) and theres a simple alternative, namely just exporting your own computeds. That could look kinda like this:

const gettext = createGettext(...);

export const languageKebabCase = computed(() => gettext.current.toLowerCase().replace("_", "-"));

global property

If you need it very often in your templates, you can of course add a global property:

app.config.globalProperties.$languageKebabCase = languageKebabCase;

Using typescript, you should thenadd a type declaration somewhere:

declare module "vue" {
  interface ComponentCustomProperties {
    $languageKebabCase: MyType;
  }
}

i should add a migration guide but i'm kinda strapped for time at the moment.

hope that helps!

Wewill commented 1 year ago

Thanks a lot @lzurbriggen ! I'm not used to Vue 3 composition ; but I think it's better using provide/inject ? app.config.globalProperties seems not available in components.

import { ..., computed, watchEffect } from "vue";

...
app.use(gettext); // Project added gettext VUE3
app.provide("gettext", gettext);

const currentLang = computed(() => {
  return gettext.current.replace("_", "-");
});
app.provide("currentLang", currentLang); // Access value via currentLang.value

// Main Watcher 
watchEffect(() => {
  console.info(
    "MAIN.TS:: Vue gettext:: watchEffect:: ",
    gettext.current,
    currentLang,
  );
});
lzurbriggen commented 1 year ago

@Wewill

app.config.globalProperties seems not available in components.

app.config.globalProperties is specifically available in the <template>-Section of your components (maybe it's also accessible via getCurrentInstance(), but that is definitely not recommended). If you need your computed in <script>, you can deal with it like you usually would, it could be provide/inject or just an export. I usually create a composable function, kinda like this:

export const useCurrentLang = () => {
  const gettext = useGettext();
  return computed(() => {
    return gettext.current.replace("_", "-");
  });
};
Wewill commented 1 year ago

Thanks a lot @lzurbriggen