阿里云主机折上折
  • 微信号
Current Site:Index > Internationalization and multilingual support

Internationalization and multilingual support

Author:Chuan Chen 阅读数:23719人阅读 分类: uni-app

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:

  1. Install vue-i18n:
npm install vue-i18n
  1. 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
  1. Import in main.js:
import i18n from './i18n'

const app = new Vue({
  i18n,
  ...App
})
app.$mount()
  1. 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:

  1. Add RTL language detection:
const rtlLanguages = ['ar', 'he', 'fa']

export function isRTL(lang) {
  return rtlLanguages.includes(lang)
}
  1. 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

  1. Load language packs on demand
  2. Use language pack chunking
  3. Avoid complex expressions in templates
  4. 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

  1. 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)
  })
}
  1. Handle missing translations:
const i18n = new VueI18n({
  // ...Other configurations
  missing: (locale, key) => {
    console.warn(`Missing translation: ${key} for locale ${locale}`)
    return key
  }
})
  1. Dynamic key name handling:
<template>
  <view>
    <text>{{ $t(`user.${action}`) }}</text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      action: 'login'
    }
  }
}
</script>

Advanced Application Scenarios

  1. 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()
})
  1. API response internationalization:
// Request interceptor
axios.interceptors.request.use(config => {
  config.headers['Accept-Language'] = i18n.locale
  return config
})
  1. 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

  1. Localize app store metadata
  2. Package and release by language
  3. 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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.