VueJSで多言語対応した話

VueJSで多言語対応した話

特にこだわり無ければ このライブラリを使えばおk https://github.com/kazupon/vue-i18n 今回はこれを使っていないです。

ライブラリを使わなかった理由

これ

を読んでライブラリいらなくね?と思ったから Vue, Vuexで自前実装した

設計

Jsonにメッセージを込めるようにした。

cat src/assets/message.json


{ "ja": { "calender": { "h4": "ぴよぴよ", "h6": "ほげふが" } }, "en": { "calender": { "h4": "piyopiyo", "h6": "hogehoge" } } }

Vuexの設計

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

import message from "./assets/message.json";

export default new Vuex.Store({
  state: {
    message: message["ja"]
  },
  mutations: {
    changeMessage: (state, lang) => {
      state.message = message[lang];
    }
  }
});

stateにjsonをそのまま持たして、mutationで、言語を変更できるようにした。

言語変更コンポーネント

cat src/components/langage_selecter.vue

<template>
    <div id="langage_selecter">
      <button v-if="select_lang != 'ja'" v-on:click="changeLang">en</button>
      <button v-if="select_lang != 'en'" v-on:click="changeLang">ja</button>
    </div>
</template>

<script>
const default_lang =
  (
    window.navigator.userLanguage ||
    window.navigator.language ||
    window.navigator.browserLanguage
  ).substr(0, 2) == "ja"
    ? "ja"
    : "en";

export default {
  name: "langageselecter",
  data() {
    return {
      select_lang: default_lang
    };
  },
  methods: {
    changeLang: function() {
      if (this.select_lang == "ja") {
        this.select_lang = "en";
      } else {
        this.select_lang ="ja";
      }

    }
  },
  watch: {
    select_lang: function(val) {
      this.$store.commit("changeMessage", val);
    }
  }
};
</script>
<style>
</style>

const default_lang =
  (
    window.navigator.userLanguage ||
    window.navigator.language ||
    window.navigator.browserLanguage
  ).substr(0, 2) == "ja"
    ? "ja"
    : "en";

これで、言語判定をしている。 今回作ったサイトで必要なのは日本語と英語だけだったので、jaで無ければenにするようにした。

参考

 

watch: {
    select_lang: function(val) {
      this.$store.commit("changeMessage", val);
    }
  }

select_langに変更があったときにmutationを使うようにした。

メッセージ表示

<template>
    <h4>{{message.calender.h4}}</h4>
    <h6>{{message.calender.h6}}</h6>
</template>
<script>
export default {
  name: "calender",
  props: {
  },
  computed: {
    message: function() {
      return this.$store.state.message;
    }
  }
};
</script>

のようにした。 これで完了

思うこと等

もしサイト内に時間表示や、地域表示など本格的なi18n対応が必要になったら大変そうだなと思います。 — fin —

追記 2018 12/23

nuxtjs等でSSRをしている時window is not definedと言ったエラーを起こすので以下のようにクライアントサイドのみで、デフォルトの言語設定が取得できるようにしてあげると良いです。

let default_lang = "ja"
if (process.client) {
  default_lang = (
    window.navigator.userLanguage ||
    window.navigator.language ||
    window.navigator.browserLanguage
  ).substr(0, 2) == "ja"
    ? "ja"
    : "en";
}

としてクライアントサイドのみで動くようにしてあげると良いです。