LoginSignup
1
1

More than 1 year has passed since last update.

[vue/Nuxt]マルチ言語対応(plugin/custom directive)

Posted at

はじめに

ログインユーザーにより、日本語・英語に表示を切り替える。
日本語・英語のテキストはjsonファイルに定義する。

前提条件

windows 10
npm 6.9.0
node v12.17.0
nuxt 2.15.7

Nuxtインストール

各バージョンを確認

C:\pj\ml-project>npm -v
6.9.0

C:\pj\ml-project>node -v
v12.17.0

※node13系以降はエラーになる可能性があるため、12系に変更。

nuxtプロジェクトをインストール

npx create-nuxt-app ml-project

※初期設定でプロジェクト作成

ディレクトリ変更

cd ml-project

nodeサーバ実行

npm run dev

http://localhost:3000/
にアクセスし表示されればOK。
無題.png

ログインユーザーstoreを準備

ml-project\store\loginUser.js
export default {
  state: {
    lang: 'ja' // 「jp」 or 「en」
  },
  mutations: {
    setLang(state, text){
      state.lang = text;
    }
  }
};

多言語ファイルを準備

ml-project\assets\lang\jp.json
{
    "MSG0001": "Nuxtアプリケーションへようこそ"
}
ml-project\assets\lang\en.json
{
    "MSG0001": "Welcome to your Nuxt Application"
}

多言語メッセージプラグイン

多言語プラグインを追加

ml-project\nuxt.config.js
  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    // 多言語共通処理
    '~/plugins/ml', // 追加
  ],
ml-project\plugins\ml.js
/**
 * 多言語プラグイン
 */
import { mlService } from '../services/mlService'

export default ({store} ,inject) => {
  const lang = store.state.loginUser.lang;
  const ml = new mlService(lang);
  inject('ml', ml);
}
ml-project\services\mlService.js
/**
 * 多言語サービス
 */
import jp from '../assets/lang/jp.json'
import en from '../assets/lang/en.json'

export class mlService {
  lang = 'jp';    // 言語モード
  messages = jp;  // 言語リスト

  constructor(lang = 'jp'){
    this.lang = lang ? lang : 'jp';
    this.setLangList();
  }

  /**
   * テキスト取得
   */
  get(id, params = null){
    if(!this.messages[id]){
      throw new TypeError(`id not found: ${id}`);
    }
    let text = this.messages[id];
    if(Array.isArray(params)){
      for(let i=0; i < params.length; i++){
        text = text.replace(`{${i}}`, params[i]);
      }
    }
    return text;
  }
  /**
   * 言語設定
   */
   setLang(lang = 'jp'){
    this.lang = lang ? lang : 'jp';
    this.setLangList();
  } 
  /**
   * 言語リスト設定
   */
  setLangList(){
    switch(this.lang){
      case 'jp':
        this.messages = jp;
        break;
      case 'en':
        this.messages = en;
        break;
    }
  }
}
ml-project\components\Tutorial.vue
        <h2 class="text-2xl leading-7 font-semibold">
          Welcome to your Nuxt Application
        </h2>
    ↓
        <h2 class="text-2xl leading-7 font-semibold">
          {{this.$ml.get('MSG0001')}}
        </h2>

無題2.png

loginUser.jsの『lang:'ja'』のため、日本語化されています。

言語を変更したい場合は、create時にstoreの値を変更する。

ml-project\pages\index.vue
export default {
     created: function(){
         // 多言語:英語
         this.$store.commit('loginUser/setLang', 'en');
     },
}

無題3.png

英語化されます。

[応用]多言語custom directive

ml-project\nuxt.config.js
  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    // 多言語共通処理
    '~/plugins/ml',
    // custom directive
    '~/plugins/customDirective', // 追加
  ],
ml-project\plugins\customDirective.js
import Vue from 'vue'
import { mlService } from '../services/mlService'
/**
 * 多言語一括ディレクティブ
 */
Vue.directive('ml',{
  bind(el, binding, vnode){
    const ml = new mlService(vnode.context.$store.state.loginUser.lang);
    [].forEach.call(el.querySelectorAll('[data-label]'), function(e,i){
      try {
        // json形式の場合
        let label = JSON.parse(e.dataset.label);
        e.innerText = ml.get(label.id, label.params);
      } catch(exception) {
        // idの場合
        let label = e.dataset.label;
        e.innerText = ml.get(label);
      }
    });
  }
})
ml-project\components\Tutorial.vue
  <div v-ml class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0">
(省略)
        <h2 class="text-2xl leading-7 font-semibold" data-label='MSG0001'>
          data-labelを設定すれば自動置換
        </h2>

※『v-ml』を追加。v-ml内のタグに、『data-label='MSG0001'』を追加することで中の文字列が言語に合わせ自動で置換されます。

無題3.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1