Closed thelinuxlich closed 8 years ago
@thelinuxlich
Hi
I released vue-i18n
new version.
You can change language the below code.
<p>{{ $t('message.hello', 'en') }}</p>
Please try it !!
I tested it and it is useful but I think that it would be better to somehow set lang parameter as observable and change globally based on it
I add Vue.config.lang
configuration.
This doesn't solve the issue unless Vue.config.lang is reactive
Sorry, I didn't understand your request.
I think that it would be better to somehow set lang parameter as observable and change globally based on it
You need reactive lang
params, don't you ?
yeah, I believe it's a common case for the user switching the language during interaction
OK. I'll try out. :)
How about this: http://jsfiddle.net/nkovacs/1zh3agxr/?
Any news on this one?
I'm interested in easy switching languages by user too.
+1 i tried making a language switcher widget, but it don't seem to update the translations after Vue.config.lang has been changed
+1
+1
+1 @martinlindhe Did you get it to work?
@kazupon This package https://github.com/Haixing-Hu/vue-i18n has support for this through jQuery AJAX calls(from what I can tell). Perhaps you can use some of it's logic to solve this issue. Just a thought!
@sagaio: nope, i'm currently working around it by doing a page reload when language was changed.
location.reload();
works, but ain't pretty!
+1
+1
+1
Was thinking of this issue again today and came up with this solution. It involves using a new tag and I'm not sure i gonna do this on my current vue project, but maybe for the next one.
First, we have someplace in our ui to change language.
to change language you do something like this
select(code) {
Vue.config.lang = code;
this.$broadcast('language');
}
to put translations in our templates, we now do <t t="user.new"></t>
and finally a T.vue component:
<template>
<span>
{{ translated }}
</span>
</template>
<script>
export default {
props: {
t: '',
},
data() {
return {
translated: '',
};
},
ready() {
this.translated = this.$t(this.t);
this.$on('language', function() {
this.translated = this.$t(this.t);
});
},
};
</script>
Now your language changes are reactive.
+1
@kazupon I would like to add this feature myself, but i can't afford it right now...but i would like to know do you plan to support this or should i switch to what @sagaio said?
@seemsindie I'll plan to support in vue-i18n v3. but the release of vue-i18n v3 is undecided.
@kazupon Ok thanks, all i needed to hear :)
+1
A global runtime this.$setLang()
method preferred
+1 count me in if you need an hand for the next release
Also, for those using vuex
I'm using the following workaround at the moment:
modules/i18n/mutation-types.js
export const SET_LANGUAGE = 'SET_LANGUAGE'
modules/i18n/index.js
import {
SET_LANGUAGE
} from './mutation-types'
const state = {
lang: 'en',
locales: [ 'en', 'fi' ]
}
const mutations = {
[SET_LANGUAGE] (state, lang) {
if (state.locales.indexOf(lang) !== -1) {
state.lang = lang
}
}
}
export default {
state,
mutations
}
store.js
import i18n from './modules/i18n'
// ... import other stuff
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
i18n
}
})
export default store
main.js
import Vue from 'vue'
import store from './store'
Vue.filter('translate', function (value, arg) {
return this.$t(value, this.$store.state.i18n.lang, arg)
})
and then just use it like this
<span>{{ 'message' | translate }}</span>
where
en.json
{
"message": "English message"
}
fi.json
{
"message": "Finnish message"
}
If you change the language like this:
vm.$store.dispatch('SET_LANGUAGE', 'fi')
everything will work like a charm.
NOTE: In my case I opt-out for create a filter, and it might not work perfectly, but gives an idea on how to get this to work.
+1
Hello @kazupon Do you have an example on how to change the Vue.config.lang from within a component?
thanks
+1 for some example
You can use the Component locale and $t
method with lang
params.
Oh, thanks, but as a matter of fact I was looking for some example to switch language dynamically in my app - should I just change global config option like Vue.config.lang = 'ja'
or Is threre any special method like 'setLanguage' ?
hmm, I cannot see the your use-case ...
I think you can resolve with component that was wrapped vuex
like state management (e.g. the above @ealves-pt comment.
@kazupon The use case is if a user navigates a websites in one language, then he clicks a button to switch to another language. Now the global vue.config.lang has to be the new language. How would you handle that switcher-button-component?
Exactly :)
In this use-case, I think you can handle data changing with watch
in the component.
the below example of implementation:
const navigation = {
template: `<nav>
<select v-model="lang">
<option selected value="en">EN</option>
<option> value="ja">JA</option>
</select>
</nav>`,
data () {
return { lang: 'en' }
},
watch: {
lang (val) {
Vue.config.lang = val
}
}
}
Ok thank you. At the moment, Vue is only imported in the main file, not in the components. So I have to import 'Vue' inside my component for this?
@francoisromain you could use the $lang
property:
new Vue({
// ...
methods: {
change () {
let current = this.$lang.lang
if (current === 'en') {
this.$lang.lang = 'el'
} else {
this.$lang.lang = 'en'
}
}
}
})
@pespantelis sweet!
@pespantelis Oh but $lang is undefined in the module scope…
@francoisromain Ohh you are right!
However, I have another approach to achieve this in the module scope.
You could add Vue instance methods by attaching them to Vue.prototype
.
Vue.prototype.$locale = {
change (lang) {
Vue.config.lang = lang
},
current () {
return Vue.config.lang
}
}
Vue.component('my-component', {
template: '...',
methods: {
change () {
let current = this.$locale.current()
if (current === 'en') {
this.$locale.change('el')
} else {
this.$locale.change('en')
}
}
}
})
@pespantelis thanks a lot : )
I solved it a different way, as I use vue-router:
in the main js file:
router.beforeEach((to, from, next) => {
Vue.config.lang = to.params.lang;
next();
});
and the lang-select component:
<template>
<div class="lang-select">
<button @click="change('en')">en</button>
<button @click="change('de')">de</button>
<button @click="change('fr')">fr</button>
</div>
</template>
<script>
export default {
methods: {
change (lang) {
const route = Object.assign({}, this.$route);
route.params.lang = lang;
this.$router.push(route);
}
}
};
</script>
What do you think about this solution?
@pespantelis' altering of the prototype is by far the most elegant solution. Really feels like it should be baked in.
With Vue i18n 6.0, you need to adapt the locale
property of VueI18n
to change the language. I solved it like this:
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'en',
fallbackLocale: 'en',
messages: { [...] }
});
Vue.prototype.$locale = {
change (language) {
i18n.locale = language;
},
current () {
return i18n.locale;
}
};
new Vue({
el: '#app',
i18n,
[...]
});
You can set the locale via $i18n
property of Vue instance. :)
https://kazupon.github.io/vue-i18n/en/api.html#injected-properties
Ha, @kazupon, your response fixed it. Been trying for 3 hours but we only had do to this haha;
The value en can be dynamic.
this.$i18n.locale = 'en'
If it does not work, make sure you can console log the right instance.
thanks for the information @nickkuijpers, worked great.
@nickkuijpers and @TheBroox the documentation says this property is readonly. That is a typo I guess?
@roelvan i think so because in my end it works. Have u tried it?
sorry, this plugin cannot change the language after the configuration.