Internationalization and multilingual support
Internationalization and Multi-language Support in uni-app
uni-app, as a cross-platform development framework, has internationalization and multi-language support as one of its key features. Developers can implement language switching in applications through built-in mechanisms or third-party libraries to meet the needs of users in different regions.
Built-in i18n Solution
uni-app provides a simple internationalization solution through the messages
object and the $t()
method for text translation. Configure language packs in pages.json
:
// pages.json
{
"pages": [
// Page configuration
],
"uni-app": {
"i18n": {
"locale": "zh-Hans",
"messages": {
"zh-Hans": {
"index": {
"title": "Home",
"welcome": "Welcome to uni-app"
}
},
"en": {
"index": {
"title": "Home",
"welcome": "Welcome to uni-app"
}
}
}
}
}
}
Use the $t()
method in pages to get translations:
<template>
<view>
<text>{{ $t('index.title') }}</text>
<button>{{ $t('index.welcome') }}</button>
</view>
</template>
Dynamically switch languages:
uni.setLocale('en') // Switch to English
Using vue-i18n for More Powerful Internationalization
For more complex internationalization needs, integrate vue-i18n:
- Install vue-i18n:
npm install vue-i18n
- Create an i18n instance:
// src/i18n.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const messages = {
en: {
greeting: 'Hello {name}',
date: {
long: 'MMMM Do, YYYY'
}
},
zh: {
greeting: 'Hello {name}',
date: {
long: 'YYYY年M月D日'
}
}
}
const i18n = new VueI18n({
locale: 'zh', // Default language
fallbackLocale: 'en', // Fallback language
messages
})
export default i18n
- Import in main.js:
import i18n from './i18n'
const app = new Vue({
i18n,
...App
})
app.$mount()
- Use in components:
<template>
<view>
<text>{{ $t('greeting', { name: 'John' }) }}</text>
<text>{{ $d(new Date(), 'date.long') }}</text>
</view>
</template>
Multi-language Resource Management
It is recommended to manage language resources by module:
src/
i18n/
├── index.js # Entry file
├── locales/
│ ├── en-US.js # English resources
│ ├── zh-CN.js # Chinese resources
│ └── ja-JP.js # Japanese resources
└── plugins/ # Plugins (e.g., date formatting)
Example language resource file:
// en-US.js
export default {
common: {
submit: 'Submit',
cancel: 'Cancel'
},
user: {
login: 'Login',
register: 'Register'
}
}
Dynamic Loading of Language Packs
To optimize performance, implement on-demand loading of language packs:
// i18n.js
export async function setI18nLanguage(i18n, lang) {
if (i18n.locale === lang) return lang
if (!i18n.availableLocales.includes(lang)) {
const messages = await import(`@/i18n/locales/${lang}.js`)
i18n.setLocaleMessage(lang, messages.default)
}
i18n.locale = lang
document.querySelector('html').setAttribute('lang', lang)
return lang
}
Handling Plural Forms and Gender
vue-i18n supports plural forms and gender handling:
// Language resources
{
en: {
apple: 'apple | apples',
friend: 'A friend | {count} friends',
message: '{gender, select, male {He} female {She} other {They}} will come soon'
}
}
Usage example:
<template>
<view>
<text>{{ $tc('apple', 5) }}</text> <!-- Output: apples -->
<text>{{ $tc('friend', 10, { count: 10 }) }}</text>
<text>{{ $t('message', { gender: 'female' }) }}</text>
</view>
</template>
Date and Number Formatting
Configure localized formats for dates and numbers:
// i18n.js
import dateTimeFormats from './dateTimeFormats'
import numberFormats from './numberFormats'
const i18n = new VueI18n({
// ...Other configurations
dateTimeFormats,
numberFormats
})
Example format configuration:
// dateTimeFormats.js
export default {
'en-US': {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
},
long: {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: 'numeric',
minute: 'numeric'
}
}
}
// numberFormats.js
export default {
'en-US': {
currency: {
style: 'currency',
currency: 'USD'
}
}
}
Usage example:
<template>
<view>
<text>{{ $d(new Date(), 'long') }}</text>
<text>{{ $n(1000, 'currency') }}</text>
</view>
</template>
RTL Language Support
For right-to-left (RTL) languages like Arabic, special handling is required:
- Add RTL language detection:
const rtlLanguages = ['ar', 'he', 'fa']
export function isRTL(lang) {
return rtlLanguages.includes(lang)
}
- Dynamically switch styles:
<template>
<view :class="{ 'rtl-direction': isRTL }">
<!-- Content -->
</view>
</template>
<script>
export default {
computed: {
isRTL() {
return isRTL(this.$i18n.locale)
}
}
}
</script>
<style>
.rtl-direction {
direction: rtl;
text-align: right;
}
</style>
Language Persistence
Use uni-app's storage mechanism to save user language preferences:
// Set language
async function setLanguage(lang) {
await setI18nLanguage(i18n, lang)
uni.setStorageSync('userLanguage', lang)
}
// Read during initialization
const savedLang = uni.getStorageSync('userLanguage')
if (savedLang) {
setLanguage(savedLang)
}
Server-Side Rendering (SSR) Considerations
If using uni-app's SSR feature, ensure i18n state synchronization:
// In entry-server.js
export default context => {
return new Promise((resolve, reject) => {
const { app, router } = createApp()
// Get language from request
const lang = detectLanguage(context.req)
setI18nLanguage(app.$i18n, lang)
router.push(context.url)
// ...Other SSR logic
})
}
Testing and Debugging
Write tests for multi-language applications:
// Test example
describe('i18n', () => {
it('should translate messages', () => {
const wrapper = mount(Component, {
i18n,
propsData: { /* ... */ }
})
expect(wrapper.text()).toContain('Hello')
})
it('should switch languages', async () => {
await setLanguage('zh')
expect(i18n.locale).toBe('zh')
})
})
Performance Optimization Tips
- Load language packs on demand
- Use language pack chunking
- Avoid complex expressions in templates
- Use compile-time extraction for static content
// Webpack configuration example
module.exports = {
chainWebpack: config => {
config.plugin('i18n').use(require('@kazupon/vue-i18n-loader'))
}
}
Common Issue Solutions
- Hot reload language packs:
// Hot reload in development environment
if (module.hot) {
module.hot.accept(['@/i18n/locales/en'], () => {
i18n.setLocaleMessage('en', require('@/i18n/locales/en').default)
})
}
- Handle missing translations:
const i18n = new VueI18n({
// ...Other configurations
missing: (locale, key) => {
console.warn(`Missing translation: ${key} for locale ${locale}`)
return key
}
})
- Dynamic key name handling:
<template>
<view>
<text>{{ $t(`user.${action}`) }}</text>
</view>
</template>
<script>
export default {
data() {
return {
action: 'login'
}
}
}
</script>
Advanced Application Scenarios
- Multi-language routing:
// Route configuration
const routes = [
{
path: '/:lang/home',
component: Home,
meta: {
i18n: {
title: 'pageTitles.home'
}
}
}
]
// Route guard
router.beforeEach((to, from, next) => {
const lang = to.params.lang || 'en'
setI18nLanguage(i18n, lang)
next()
})
- API response internationalization:
// Request interceptor
axios.interceptors.request.use(config => {
config.headers['Accept-Language'] = i18n.locale
return config
})
- Third-party service integration:
// For example, integrate Element UI internationalization
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'
Vue.use(ElementUI, {
i18n: (key, value) => i18n.t(key, value)
})
Multi-language Application Release Strategy
- Localize app store metadata
- Package and release by language
- Dynamic language pack update mechanism
// Check for language pack updates
async function checkI18nUpdate() {
const currentVersion = uni.getStorageSync('i18nVersion')
const { version, url } = await fetchLatestI18nVersion()
if (version !== currentVersion) {
const newMessages = await fetchI18nResources(url)
i18n.setLocaleMessage(i18n.locale, newMessages)
uni.setStorageSync('i18nVersion', version)
}
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:主题与样式的动态切换
下一篇:减少包体积的策略