Thực hiện đa ngôn ngữ hiệu quả  dụng Vue-i18n

VueJS Aug 13, 2020

Giới thiệu

  • Vue I18n là một plugin hỗ trợ đa ngôn ngữ cho Vue base trên thư viên I18n. Tham khảo :

      + Github i18n

  • Cài đặt Vue-i18n khá đơn giản như sau
yarn add vue-i18n
  • Trong app.js hoặc main.js khai báo sử dụng plugin như dưới đây
import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)
  • Sử dụng

     - Định nghĩa message  

const messages = {
  en: {
    message: {
      hello: '{msg} world'
    }
  }
}

   - Tạo đối tượng đa ngôn ngữ trong đó messages được lấy từ định nghĩa ở trên

const i18n = new VueI18n({
    locale: 'en', // set locale
    fallbackLocale: 'en', // set fallback locale
    messages, // set locale messages
});

   - Và cuối cùng đăng ký nó với Vue :

new Vue({
    i18n,
    render: h => h(App),
}).$mount('#app');

Tăng hiệu quả

Nêu vấn đề

  • Cách làm như ở trên khá tốt với hệ thống đối ứng 1 số ít ngôn ngữ. Nhưng nếu chúng ta phải đối ứng nhiều loại ngôn ngữ, mỗi loại ngôn ngữ lại có nhiều text thì việc khai báo message tập trung như vậy rất không hiệu quả và khó quản lý
  • Việc dồn tất cả khai báo và khởi tạo vào main.js/app.js khiến file trở nên phình to và khó quản lý

Đề án cách giải pháp

  • Tạo plugin i18n trong thư mục plugins
"use strict";

import Vue from 'vue';
import VueI18n from 'vue-i18n';

const messages = {}
const options =
{
    locale: 'en', // set locale
    fallbackLocale: 'en', // set fallback locale
    messages, // set locale messages
}

const _i18n = VueI18n.install(Vue, options)

Plugin.install = function() {
    Vue.i18n = _i18n;
    Vue.prototype.$i18n = _i18n;
    Object.defineProperties(Vue.prototype, {
        i18n: {
            get() {
                return _i18n;
            }
        },
        $i18n: {
            get() {
                return _i18n;
            }
        },
    });
};

Vue.use(Plugin)

export default Plugin;

- Mới nhìn việc làm này có vẻ hơi thừa thãi nhưng sẽ giúp việc quản lý plugin gọn gàng hơn. Trong file app.js lúc này ta chỉ cần :

import ./plugins/i18n
  • Để ý là messages hiện giờ là đối tượng rỗng và ta muốn messages được chia thành nhiều file trong các thư mục locale tương ứng như sau

   – Để làm được thì trước tiên ta chia message vào từng file trong thư mục locale. Mỗi file tương ứng chẳng hạn với 1 màn hình và ở dạng JSON:

{
	"title": "Login",
	"form": {
		"lbl_title" : "Login using your account",
		"lbl_user_name"  : "Company email",
		"lbl_password" : "Password",
		"btn_login" : "Login",
		"lnk_forgot" : "Password Reset",
		"lbl_register" : "Does not have an account!",
		"txt_description" : "Please contact our administrator for account creation.",
		"txt_logging_in" : "Logging in!"
	},
	"messages": {
		"lbl_title" : "Could not login",
		"txt_error": "Your provided credential is not correct.",
		"txt_successful": "Login successfully."
	}
}

     – File index.js sẽ giúp ta load các json này một cách tự động như bạn thấy dưới đây tôi sẽ lặp qua thư mục lang và sẽ tạo ra đối tượng message theo format yêu cầu bởi VueI18n:

// http://kazupon.github.io/vue-i18n/en/messages.html

const requireLang = require.context(
    '../lang',
    true,
    /\.json$/
)

const messages = {}

for (const file of requireLang.keys()) {
    if (file === './index.js') continue

    const path = file.replace(/(\.\/|\.json$)/g, '').split('/')
    path.reduce((o, s, i) => {
        if (o[s]) return o[s]
        o[s] = i + 1 === path.length
            ? requireLang(file)
            : {}

        return o[s]
    }, messages)
}

export default messages

     — Hoàn thành bước này thì ta có thể thay đoạn messages đang là đối tượng rỗng bằng câu lệnh import như sau :

import messages from '../lang'


const options =
{
    locale: 'en', // set locale
    fallbackLocale: 'en', // set fallback locale
    messages, // set locale messages
}

Kết luận

  • Bằng cách này các message sẽ được group theo locale và các unit tuỳ cách chia của bạn
  • Việc load các message sẽ đơn giản và tự động

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.