refactor(i18n): improve language handling and UI updates
All checks were successful
Deploy to production / deploy (push) Successful in 2m49s

- Enhanced language setting logic in App.vue and AppHeader.vue to support reactive updates without page reloads.
- Updated language options in AppHeader.vue to use native labels for improved clarity.
- Introduced a utility function in i18n/index.js to streamline locale updates, ensuring consistent language handling across the application.
This commit is contained in:
Torsten Schulz (local)
2026-04-07 15:52:16 +02:00
parent c5b8860605
commit ae635b9c16
3 changed files with 38 additions and 8 deletions

View File

@@ -65,7 +65,13 @@ export default {
MultiChatDialog, MultiChatDialog,
}, },
created() { created() {
this.$i18n.locale = this.$store.getters.language; const code = this.$store.getters.language;
const loc = this.$i18n.locale;
if (loc && typeof loc === 'object' && 'value' in loc) {
loc.value = code;
} else {
this.$i18n.locale = code;
}
}, },
}; };
</script> </script>

View File

@@ -20,7 +20,7 @@
@change="onUiLanguageChange($event.target.value)" @change="onUiLanguageChange($event.target.value)"
> >
<option v-for="opt in uiLocaleOptions" :key="opt.value" :value="opt.value"> <option v-for="opt in uiLocaleOptions" :key="opt.value" :value="opt.value">
{{ $t(opt.labelTr) }} {{ opt.nativeLabel }}
</option> </option>
</select> </select>
</label> </label>
@@ -48,11 +48,12 @@ export default {
name: 'AppHeader', name: 'AppHeader',
data() { data() {
return { return {
/** Endonyme: jede Sprache bezeichnet sich in ihrer eigenen Sprache. */
uiLocaleOptions: [ uiLocaleOptions: [
{ value: 'de', labelTr: 'settings.personal.language.de' }, { value: 'de', nativeLabel: 'Deutsch' },
{ value: 'en', labelTr: 'settings.personal.language.en' }, { value: 'en', nativeLabel: 'English' },
{ value: 'ceb', labelTr: 'settings.personal.language.ceb' }, { value: 'ceb', nativeLabel: 'Sinugboanon' },
{ value: 'es', labelTr: 'settings.personal.language.es' }, { value: 'es', nativeLabel: 'Español' },
], ],
}; };
}, },
@@ -82,6 +83,7 @@ export default {
return; return;
} }
await this.$store.dispatch('setLanguage', code); await this.$store.dispatch('setLanguage', code);
this.applyI18nLocale(code);
if (!this.isLoggedIn || !this.user?.id) { if (!this.isLoggedIn || !this.user?.id) {
return; return;
} }
@@ -107,6 +109,19 @@ export default {
console.warn('AppHeader: profile language could not be synced', err); console.warn('AppHeader: profile language could not be synced', err);
} }
}, },
/** UI sofort auf neue Sprache umstellen, ohne Seiten-Reload (nur reaktives i18n). */
applyI18nLocale(code) {
const g = this.$i18n;
if (!g) {
return;
}
const loc = g.locale;
if (loc && typeof loc === 'object' && 'value' in loc) {
loc.value = code;
} else {
g.locale = code;
}
},
}, },
}; };
</script> </script>

View File

@@ -195,11 +195,20 @@ const i18n = createI18n({
messages messages
}); });
// Überwache Änderungen der Sprache im Store und aktualisiere i18n entsprechend function setGlobalLocale(next) {
const loc = i18n.global.locale;
if (loc && typeof loc === 'object' && 'value' in loc) {
loc.value = next;
} else {
i18n.global.locale = next;
}
}
// Überwache Änderungen der Sprache im Store und aktualisiere i18n (ohne Seiten-Reload)
store.watch( store.watch(
(state) => state.language, (state) => state.language,
(newLanguage) => { (newLanguage) => {
i18n.global.locale.value = newLanguage; setGlobalLocale(newLanguage);
} }
); );