Skip to main content

Vue i18n: Hướng dẫn thiết lập quốc tế hóa hoàn chỉnh với vue-i18n

Từ cài đặt đến đưa vào vận hành: cấu hình vue-i18n bằng Composition API, xử lý dạng số nhiều theo quy tắc CLDR, sử dụng nội suy thành phần và thêm chuỗi dự phòng bản địa thông minh.

1

Cài đặt vue-i18n

vue-i18n là plugin quốc tế hóa chính thức cho Vue.js. Plugin này cung cấp bản dịch có tính phản ứng, dạng số nhiều kiểu ICU, nội suy thành phần, định dạng ngày giờ và số đồng thời hỗ trợ cả Options API lẫn Composition API.

Terminal
npm install vue-i18n@9
2

Cấu hình vue-i18n

Tạo một thực thể i18n bằng createI18n() và đăng ký thực thể đó làm plugin Vue. Khai báo thông báo bản địa, đặt bản địa mặc định và cấu hình bản địa dự phòng. vue-i18n hỗ trợ cả chế độ cũ (Options API) lẫn chế độ composition (Composition API).

src/i18n.ts
// src/i18n.ts
import { createI18n } from 'vue-i18n'
import en from './locales/en.json'
import de from './locales/de.json'

const i18n = createI18n({
  legacy: false,           // Use Composition API mode
  locale: 'en',            // Default locale
  fallbackLocale: 'en',   // Fallback locale
  messages: { en, de },
})

export default i18n
src/main.ts
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'

const app = createApp(App)
app.use(i18n)
app.mount('#app')
Nếu gặp lỗi 'Not available in legacy mode', bạn đang dùng lẫn lệnh gọi i18n của Composition API (useI18n()) với cấu hình chế độ cũ. Hãy đặt legacy: false trong createI18n() để dùng chế độ Composition API hoặc nhất quán sử dụng cú pháp $t() của Options API.
3

Dùng bản dịch trong mẫu

vue-i18n cung cấp hàm $t() trong mẫu (Options API) và hàm t() từ useI18n() (Composition API). Cả hai đều nhận khóa bản dịch và tham số có tên/danh sách tùy chọn để nội suy.

src/locales/en.json
// src/locales/en.json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "greeting": "Hello, {name}!",
  "cart": {
    "itemCount": "no items | one item | {count} items"
  }
}

// src/locales/de.json
{
  "nav": {
    "home": "Startseite",
    "about": "Über uns",
    "settings": "Einstellungen"
  },
  "greeting": "Hallo, {name}!",
  "cart": {
    "itemCount": "keine Artikel | ein Artikel | {count} Artikel"
  }
}
4

Xử lý dạng số nhiều

vue-i18n hỗ trợ dạng số nhiều qua các dạng phân tách bằng dấu gạch đứng và hàm $tc() (chế độ cũ) hoặc t() với tham số số lượng (Composition API). Khai báo các dạng số nhiều trong thông báo bản địa bằng dấu phân cách gạch đứng: 'no items | one item | {count} items'.

MyComponent.vue
<template>
  <div>
    <!-- Simple translation -->
    <h1>{{ $t('nav.home') }}</h1>

    <!-- With variables -->
    <p>{{ $t('greeting', { name: userName }) }}</p>

    <!-- In attributes -->
    <input :placeholder="$t('nav.settings')" />

    <!-- Composition API -->
    <p>{{ greeting }}</p>
  </div>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { t } = useI18n()
const userName = 'Alice'
const greeting = t('greeting', { name: userName })
</script>
Cú pháp số nhiều phân tách bằng dấu gạch đứng chỉ hỗ trợ số đếm với tối đa ba dạng (zero | one | other). Với ngôn ngữ có quy tắc số nhiều CLDR phức tạp (tiếng Ả Rập, tiếng Nga, tiếng Ba Lan), hãy dùng cú pháp ICU MessageFormat hoặc bộ sửa đổi @.plural kèm ánh xạ danh mục CLDR tường minh.
5

Thêm chuỗi dự phòng bản địa

fallbackLocale tích hợp sẵn của vue-i18n chỉ hỗ trợ danh sách bản địa dự phòng phẳng, không hỗ trợ chuỗi riêng cho từng bản địa. Khi thiếu khóa, người dùng pt-BR sẽ nhận bản tiếng Anh thay vì pt-PT. vue-i18n-locale-chain bổ sung chuỗi hợp nhất sâu có thể cấu hình để người dùng từng khu vực luôn thấy bản dịch gần nhất hiện có.

Plurals.vue
<template>
  <div>
    <!-- Pipe-separated plurals -->
    <p>{{ $t('cart.itemCount', count) }}</p>

    <!-- Named plurals (recommended for complex languages) -->
    <p>{{ $t('orders', { n: orderCount }) }}</p>
  </div>
</template>

<!-- In your locale file: -->
<!-- "orders": "{n} order | {n} orders" -->
vue-i18n-locale-chain hợp nhất sâu thông báo khi tải. Hệ thống phản ứng của vue-i18n lưu vào bộ nhớ đệm tập thông báo đã hợp nhất nên việc tra cứu dự phòng không làm giảm hiệu năng khi chạy.
6

Tự động hóa bản dịch

Sau khi cấu hình vue-i18n, hãy dùng AI để dịch các tệp JSON bản địa. Trong IDE, yêu cầu trợ lý AI dịch tệp nguồn hoặc tích hợp việc dịch vào quy trình CI/CD để tự động hóa hoàn toàn quá trình bản địa hóa.

LanguageSwitcher.vue
<template>
  <select v-model="locale">
    <option v-for="lang in availableLocales" :key="lang" :value="lang">
      {{ lang }}
    </option>
  </select>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { locale, availableLocales } = useI18n()
</script>
src/i18n.ts (lazy loading)
// src/i18n.ts
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  locale: 'en',
  fallbackLocale: 'en',
  messages: {},
})

export async function loadLocale(locale: string) {
  const messages = await import(`./locales/${locale}.json`)
  i18n.global.setLocaleMessage(locale, messages.default)
  i18n.global.locale.value = locale
}

export default i18n
7

Cấu hình chuỗi dự phòng bản địa

Cấu hình chuỗi dự phòng riêng cho từng bản địa để người dùng từng khu vực thấy bản dịch gần nhất hiện có thay vì chuyển thẳng sang tiếng Anh. vue-i18n hỗ trợ fallbackLocale kiểu đối tượng để khai báo chuỗi cho từng bản địa.

src/i18n.ts
// src/i18n.ts
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  locale: 'pt-BR',
  fallbackLocale: {
    'pt-BR': ['pt', 'en'],
    'zh-Hant-TW': ['zh-Hant', 'zh', 'en'],
    'es-419': ['es', 'en'],
    default: ['en'],
  },
  messages: {
    en: { /* ... */ },
    pt: { /* ... */ },
    'pt-BR': { /* ... */ },
  },
})
Đối tượng fallbackLocale cho phép bạn khai báo chuỗi khác nhau cho từng bản địa. Người dùng pt-BR chuyển dự phòng sang pt rồi en, còn người dùng zh-Hant-TW chuyển sang zh-Hant, zh rồi en.

Lỗi thường gặp

Dùng lẫn chế độ cũ và Composition API

Dùng useI18n() với legacy: true (giá trị mặc định) sẽ gây lỗi. Hãy đặt legacy: false trong createI18n() nếu bạn dùng Composition API hoặc chỉ dùng $t() trong mẫu với Options API. Không dùng lẫn hai chế độ trong cùng một ứng dụng.

Dùng v-html cho chuỗi đã dịch

Dùng v-html để kết xuất bản dịch chứa HTML sẽ gây rủi ro XSS nếu có giá trị nội suy đến từ dữ liệu người dùng nhập. Hãy dùng thành phần &lt;i18n-t&gt; cho bản dịch nhúng HTML hoặc thành phần Vue — thành phần này an toàn theo mặc định và hỗ trợ nhúng thành phần có tính phản ứng.

Người dùng khu vực thấy tiếng Anh thay vì bản địa cha

fallbackLocale của vue-i18n là danh sách phẳng, không phải chuỗi riêng cho từng bản địa. pt-BR chuyển dự phòng sang giá trị có trong danh sách (thường là 'en') và bỏ qua hoàn toàn pt-PT. Hãy dùng vue-i18n-locale-chain để thêm cơ chế dự phòng khu vực phù hợp bằng tính năng hợp nhất sâu.

Dùng thử i18n Agent ngay

Thả tệp bản dịch của bạn vào đây

JSON, YAML, PO, XML, CSV, Markdown, Properties

hoặc nhấp để duyệt

Ngôn ngữ đích

Không cần đăng kýBáo giá tức thì

Câu hỏi thường gặp về Vue i18n