Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register $t globally #69

Closed
tvld opened this issue Oct 18, 2016 · 19 comments
Closed

Register $t globally #69

tvld opened this issue Oct 18, 2016 · 19 comments

Comments

@tvld
Copy link

tvld commented Oct 18, 2016

Please register $t globally per default. Now we need each time:

import Vue from 'vue'
const $t = Vue.t
// before we can use:
var title = $t("header.title")
@kazupon
Copy link
Owner

kazupon commented Oct 19, 2016

Thank you for your feedback!
I cannot understand $t globally in Vue enviroment.
Can you provide the use-cases please?

@tvld
Copy link
Author

tvld commented Oct 19, 2016

Thanks for quick response! Having $t in every module, simply means we can translate every piece of text we handle within javascript:

  • Some simple logging for international testers: console.log($t("stage.first")
  • Passing props: <my-component :title='$t("mycomp.title")'></my-component>
  • Webhooks where we call API's and must provide formatted text strings http.post('/ ...
  • head: { title: { complement: $t("site.title") } , using vue-header

@callumacrae
Copy link

callumacrae commented Oct 19, 2016

If I'm understanding correctly, you're asking for this:

global.$t = Vue.t;

No, please don't do this! Global variables are very much an anti-pattern. The function is available in components, and it's available under Vue.t(), having it globally available in JavaScript would defeat the point of using CommonJS or ES6 modules.

Also, this entire exercise only saves three characters?

@tvld
Copy link
Author

tvld commented Oct 19, 2016

ok..... I understand.... but is it not the same as you are already doing in each <template> ? Bit confused now. So you are saying the correct way to code is:

<template>
  <div>
    <h1>{{ $("title") }}</h1>
    <fancy title='$t{"title"}'></fancy>
  </div>
</template>
<script>
  import Vue from 'vue'
  const myTitle = Vue.t("title")  // here I would suggest myTitle= $t("title")
</script>

I mean, if there is any reason for a const scattered all over, it is translation... is it not?

@tvld
Copy link
Author

tvld commented Oct 19, 2016

@callumacrae yes... 3 characters..used 1000 times... ;)

@kazupon
Copy link
Owner

kazupon commented Oct 19, 2016

Global variables are very much an anti-pattern.

I think so, too
If you want to decrease typing, you can define globally arias (e.g. global.$t = Vue.t;).

The following is a supplement:

  • Vue.t
    • extracts: This is translate function for global locale only.
  • $t
    • extracts: Translate in preferentially component locale than global locale.

@tvld
Copy link
Author

tvld commented Oct 19, 2016

ok, thanks :)

@janein
Copy link

janein commented Aug 7, 2017

How is this done in the latest version?
Let's say I defined some global messages like so:

const i18n = new VueI18n({
  locale: 'de',
  messages: { 
    de: {
      welcome: 'Willkommen'
    },
    // ...
 },
});

How would I get this value in a child component's script?
I know how to use it in a template, but how do I get it in i.e. a data-object?

export default {
  components: {},
  name: 'my-component',
  data () {
    return {
      header:  'WANT MY TRANSLATION HERE'
    }
  }
}

I saw something like i18n.getLocaleMessage('de').welcome or app.$i18n.getLocaleMessage('de').welcome in the docs, but at this point there is no variable i18n or app available.

Any chance to get the value there?

EDIT:
Got it working with this.$t('welcome') :)

@thedamon
Copy link

I am running into this issue while trying to set a default string variable.

props: {
  deleteButtonLabel: {type: String, default: this.$t('defaultDeleteButtonLabel')}
}
//...
<i18n>
{"en":{
 "defaultDeleteButtonLabel": "Delete"
}}
</i8n>

results in Cannot read property '$t' of undefined

Yet wanting to have a translated default of a string prop seems somewhat normal to me...
All over our code we have computed properties with strange names and ppl implementing i18n themselves essentially to use something set in the component as a prop default 😐. I don't know of a better way, though 😔

@callumacrae
Copy link

replace:

props: {
  deleteButtonLabel: {type: String, default: this.$t('defaultDeleteButtonLabel')}
}

with:

props() {
  return {
    deleteButtonLabel: {type: String, default: this.$t('defaultDeleteButtonLabel')}
  };
}

this was the module, not the vue instance, previously.

Or just use Vue.t()

@thedamon
Copy link

thedamon commented Jan 22, 2019

Hmm. I haven't got any of your suggestions to work. For now I am just setting the default in the template as a fallback {{ deleteButtonLabel || $t('defaultDeleteButtonLabel) }} and falling back to a computed property if necessary: _deleteButtonLabel() return this.deleteButtonLabel || this.$t('defaultDeleteButtonLabel)

I don't see mentioned anywhere in the guide or API docs that props can be a function.. nor does it work when I try. (property or method deleteButtonLabel is not defined on the instance but referenced during render). That would be cool, though....

I'm trying in general not to import Vue into SFCs, and when I just use Vue.t()/new Vue().$t et,c I get _vue2.default.t is not a function. When I use various combinations of instantiating a new vue instance inside my component with the same options as when i instantiated vue for my app... I always get some variation of t is not a function. Curious exactly what setup inside my component is necessary to do that. (and concerned that once I do it won't have access to the local i18n blocks created through vue-i18n-loader because I still haven't figured out how those are figured into things)

@tvld
Copy link
Author

tvld commented Jan 22, 2019

I am not sure if this is helpful, but I use something like this successfully:

export default {
  data: function () {
    return {
      // just some example of an array with translated labels
      pricesHeader: this.$i18n.t('prices.header'),
      fields: [
        { key: 'label', label: this.$i18n.t('prices.label') },
        { key: 'service', label: this.$i18n.t('prices.info') },
        { key: 'tokens', label: this.$i18n.t('prices.tokens') }
      ]
    }
  }
}

@callumacrae
Copy link

Oh sorry, I was thinking of data, not props! You're right, that can't be a function - you'd have to call Vue.t() there.

@gkatsanos
Copy link

gkatsanos commented Sep 3, 2019

I am unable to use this.$t or Vue.t in a prop default.

export default {
  name: 'custom-dialog',
  props: {
    dialogCloseButton: {
      type: String,
      default() {
        this.$t('close');
      },
    },
    width: {
      type: String,
      default: 'medium',
    },
  },
  data() {
    return {};
  },
export default {
  name: 'custom-dialog',
  props: {
    dialogCloseButton: {
      type: String,
      default: this.$t('close'), // this undefined tried also Vue.t, also doesn't work
    },
    width: {
      type: String,
      default: 'medium',
    },
  },
  data() {
    return {};
  },

is there a way to do this ?

@exoego
Copy link
Collaborator

exoego commented Sep 3, 2019

@gkatsanos
Your issues seems unrelated to this wont-fix feature request.
Please open a new issue with how to reproduce;

@gkatsanos
Copy link

It seems unrelated, but it's not. it's actually the exact same issue.

@exoego
Copy link
Collaborator

exoego commented Sep 3, 2019

Did you try add return keyword in factory function?

default() {
  return this.$t('close');
},

@TouchChan
Copy link

Yes, i think the answer may help:

Did you try add return keyword in factory function?

default() {
  return this.$t('close');
},

@rytis-simplex
Copy link

This doesn't work in Vue.js 3, as default props factories no longer have an access to this.
ESLint error:
ESLint: Props default value factory functions no longer have access to this.(vue/no-deprecated-props-default-this)

Yes, i think the answer may help:

Did you try add return keyword in factory function?

default() {
  return this.$t('close');
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants