LoginSignup
8
7

More than 3 years have passed since last update.

Nuxt.js + nuxt-i18n + VeeValidate する

Posted at

表題の環境を作るのに意外とハマったので備忘録的に書いておく。

やりたかったこと

  1. nuxt-i18nで多言語化したい
  2. この仕組を(多分)活かしつつ、VeeValidateのメッセージも多言語に対応させておきたい
  3. 上記2で翻訳したメッセージ内に、フィールドの name がそのままの表示されてしまうのをなんとかしたい

この記事で書かないこと

VeeValidatorそのもののHTML内での使い方。

こちら をみていただくほうが詳しいので。

前提

yarn とかで vee-validate は入れておく。

1. nuxt-i18nでのi18n

・・・についてはここに書いたので省略。
https://qiita.com/keiichi-hikita/items/b3cd955a35260b399097

2. VeeValidateの多言語化

プラグインを作ります。

ちなみに読み込み方はこう。

nuxt.config.js

  plugins: [{ src: '~plugins/vee-validate/i18n.js' }],

Nuxt.jsの世界では ~ はプロジェクトトップを意味しますが、

~/plugins の下に、こういう構造を作ってあります。

plugins/
└── vee-validate
    ├── attributes.js
    └── i18n.js <-- プラグインとして直接読み込むのはこれ

ファイルが2つありますね。

まず i18n.js についてだけ内容を書きます。
(もう1つのファイルについては後述します)

i18n.js

import Vue from 'vue'

import messageEn from 'vee-validate/dist/locale/en'
import messageJa from 'vee-validate/dist/locale/ja'

import attributes from './attributes' // --- (*)

import VeeValidate, { Validator } from 'vee-validate'

export default function({ app }) {
  Vue.use(VeeValidate)

  Validator.localize('en', messageEn)

  Validator.localize('ja', messageJa)
  Validator.localize(attributes)  // --- (*)

  Validator.localize('en') // -- (1)
  if (['en', 'ja'].includes(app.i18n.loadedLanguages[0])) {
    Validator.localize(app.i18n.loadedLanguages[0])
  }
}

この中の(*) の部分は一旦無視。(これはやりたいことの3に関係するので)

この状態にしておくとブラウザの言語設定に連動してバリデーションメッセージが en , ja で切り替わります。
(日英のみ対応にしてます)

(1) の部分は nuxt-i18n のフォールバック言語に設定を合わせればよいかと思います。

メッセージの翻訳の元ファイルに相当するのは以下の2点。

import messageEn from 'vee-validate/dist/locale/en'
import messageJa from 'vee-validate/dist/locale/ja'

これはVeeValidateの中に入っているのでそのまま使わせてもらいました。

で、ここで問題が

このままだと日本語にした時に、

nameは必須項目です

これは、name=nameな(わかりますよね?)フィールドに v-validate="'required'" した時のものです。

なんとも突っ込みたくなるメッセージになってしまいます。
そこで最後にやりたいことです。

3. 翻訳したメッセージ内に、フィールドの name がそのままの表示されてしまうのをなんとかしたい

このために必要なのが、前述の (*) の部分です。

再掲します。

import Vue from 'vue'

import messageEn from 'vee-validate/dist/locale/en'
import messageJa from 'vee-validate/dist/locale/ja'

import attributes from './attributes' // --- (ここと)

import VeeValidate, { Validator } from 'vee-validate'

export default function({ app }) {
  Vue.use(VeeValidate)

  Validator.localize('en', messageEn)

  Validator.localize('ja', messageJa)
  Validator.localize(attributes)  // --- (ここ)

  Validator.localize('en')
  if (['en', 'ja'].includes(app.i18n.loadedLanguages[0])) {
    Validator.localize(app.i18n.loadedLanguages[0])
  }
}

先ほど紹介しませんでしたが、上記で参照している attributes.js はこうなっています。

export default {
  ja: {
    attributes: {
      name: '名前',
      description: '説明',
    },
  },
  en: {
    attributes: {
      name: 'Name',
      description: 'Description',
    },
  },
}

ここで バリデーションメッセージに name=name なものを出すときは、 "名前" と読み替えてね ということを書いてます。
他にも少々書いてますが、意図は伝わると信じますw

この設定が入ると、先程のバリデーションメッセージが、

名前は必須項目です

のように変わります。

とりあえずこれでやりたいことの80%は出来ました。

最後にカスタムルールを足して、そのメッセージをブラウザ言語設定に合わせて切り替える方法を今調べてます。

初めてまともに使う分野は進むとすぐに壁にぶち当たりますねぇ。
そこが楽しいところなんですけどね。

8
7
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
8
7