Help us understand the problem. What is going on with this article?

Nuxt.js + nuxt-i18n + VeeValidate する

More than 1 year has passed since last update.

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

やりたかったこと

  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%は出来ました。

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした