✏️

Nuxt 3でFormKitを日本語で使いたい

2023/02/08に公開

Vue 3/Nuxt 3でFormKitを使う

自分でHTMLをコツコツ書くのも面倒なので、FormKitというツールを使うと幸せになれます。
https://formkit.com/

例えばこんなフォームを簡単な記述で作成できます。

どんな記述になるか

上記のフォームはこんな風に記載したものです。

<FormKit type="text"
     label="ユーザー名"
     name="username"
     help="名前を選んでください"
     value="@myusername"
     prefix-icon="avatarMan"
     inner-class="username-inner"
     validation="required|matches:/^@[a-zA-Z]+$/|length:5"
>
</FormKit>
<FormKit type="select"
     name="typepreference"
     label="タイプを選択してください"
/>
<FormKit type="textarea"
     name="comment"
     label="コメント欄"
/>

使用しているフォームの属性

  • prefix-icon 用意されているアイコンから選べます。
  • inner-class フォームの要素に自分でclassを設定できます。
  • validation いくつかのルールを指定すると勝手にフォームの入力チェックをしてくれます。|で仕切っています。
    • required 必須項目を指定できます
    • matches 正規表現を指定できます
    • length 最低文字数を指定できます
      などバリデーションの種類は豊富にあります。
      https://formkit.com/essentials/validation

使用する際のハードル

ドキュメントも機能も充実しているFormKitですが、そのまま使うにはちょっとした問題がありました。

日本語化の問題

上記のバリデーションを勝手にやってくれるのはありがたいのですが、一つ問題があります。チェックに引っかかった時に表示される文章は固定なのですが(設定ファイルで上書きできますが)、そのまま使うとこんな風に英語で出てくることです。

そこで日本語化が必要です。幸いなことにFormKitは国際化にも対応しています。
https://formkit.com/essentials/internationalization

Nuxt 3で使いたい

ドキュメントに出てくるコードサンプルはVue単体で使用する場合のサンプルでした。やがてもっと詳しく書かれるかもしれませんが、執筆時点ではNuxt 3での設定方法について詳しくは書いてませんでした。

FormKitモジュールのインストール

セットアップは簡単で、npm, pnpmなどで設定できます。

pnpm install @formkit/nuxt

そしてnuxt.config.tsに記載します。

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
      '@formkit/nuxt'
  ],
});

そしてもう一つファイルが必要です。formkit.config.tsです。これもプロジェクトのルート(nuxt.config.tsと同じディレクトリ)に置きます。

formkit.config.ts
import { DefaultConfigOptions } from "@formkit/vue";
import { ja, en } from '@formkit/i18n'

const config: DefaultConfigOptions = {
    theme: "genesis",
    locales: { ja, en },
    // アクティブなロケールを指定
    locale: 'ja',
};

export default config;

@formkit/i18nで指定可能なロケールは先のページに載っています。

ここまで設定すると、適当なvueファイルにtemplate部分を記載するだけで先ほどのサンプルのようなフォームが表示されます。<script>タグとか無しで使えます。

index.vue
<template>
  <div>
    <FormKit type="text"
             label="ユーザー名"
	     name="username"
	     help="名前を選んでください"
             value="@myusername"
             prefix-icon="avatarMan"
             inner-class="username-inner"
             validation="required|matches:/^@[a-zA-Z]+$/|length:5"
    >
    </FormKit>
    <FormKit type="select"
	     name="typepreference"
             label="タイプを選択してください"
    />
    <FormKit type="textarea"
	     name="comment"
             label="コメント欄"
    />
  </div>
</template>

日本語化の確認

ちゃんとエラーメッセージが日本語で表示されているか確認してみましょう。

矢印で示した通り、バリデーションに引っかかった場合のエラーメッセージが日本語化しています。

フォームの送信

フォーム全体を一つの<FormKit type="form">タグで囲むと、submitのイベントからフォームの中身を取得できます。また<FormKit type="form">のフォームは自動的にSubmitボタンがフォームの最後に表示されます。それでsubmitのイベントを取得して関数をトリガーするには、

<FormKit type="form" @submit="コールバック関数">

のように記載します。

<script setup>
const getInput = ((event) => {
  console.dir(event)
})
</script>

<template>
  <div>
    <FormKit type="form" @submit="getInput" >
      <FormKit type="text"
               label="ユーザー名"
               name="username"
               help="名前を選んでください"
               value="@myusername"
               prefix-icon="avatarMan"
               inner-class="username-inner"
               validation="required|matches:/^@[a-zA-Z]+$/|length:5"
      >
        <template #label="context">
          {{ context.label }} 
          ※
          <span class="help">{{ context.help }}</span>
        </template>
      </FormKit>
      <FormKit type="select"
               name="typepreference"
               label="タイプを選択してください"
      />
      <FormKit type="textarea"
               name="comment"
               label="コメント欄"
      />
    </FormKit>

  </div>
</template>
<style scoped>
.help {
  font-size: 0.7rem;
}
</style>

このフォームを送信するとどうなるでしょうか。例えばこのように入力値を入れた状態で送信を押してみましょう。

するとコンソールにはこのように表示されます。

name=で指定したまま、入力値が取得できているのがわかりますね。
https://formkit.com/getting-started/your-first-form#creating-the-form

おまけ:contextでフォーム要素の属性を取得

ヘルプテキストなどの位置を変えることもできます。FormKitタグをそのまま閉じずに、間に<template>を挟むこともできます。

<FormKit type="text"
     label="ユーザー名"
     name="username"
     help="名前を選んでください"
     value="@myusername"
     prefix-icon="avatarMan"
     inner-class="username-inner"
     validation="required|matches:/^@[a-zA-Z]+$/|length:5"
>
	<template #label="context">
	{{ context.label }}
	※
	<span class="help">{{ context.help }}</span>
	</template>
</FormKit>


{{ context.label }} {{ context.help }}などcontextからそのフォームの属性情報を拾えますので、好きなところに表示するように書き換えることもできます。{{ context.type }}で「text」という文字を拾えるということです。

Discussion