【Vue.js】デフォルト値による簡易な引数で呼び出せる柔軟なコンポーネント

  • 2019年2月28日
  • 2019年2月28日
  • Vue

 Vue.jsではしばしばカスタムHTMLタグとも言える程、小さな部品を作りたくなります。例えばform中の入力欄です。簡易に作るのであれば次の様にlabelとinputに必須属性とユーザ向けの多少の文言をつけるのみです。

<label for="login_username">ユーザ名</label>
<input
  id="login_username"
  type="text"
  name="username">

 実際にはこれにデザインが加わります。

<div class="row">
  <div class="col-md-12">
    <div class="form-group row">
      <label
        class="col-md-3 col-form-label text-md-right"
        for="login_username">ユーザ名</label>
      <input
        id="login_username"
        type="text"
        class="col-md-9 custom-control-input"
        name="username">
    </div>
  </div>
</div>

 Vue.jsを用いるならば、inputタグのvalueと何かしらの変数を同期させたくなるでしょう。動的なバリデーション、警告を追加もするでしょう。

<div class="row">
  <div class="col-md-12">
    <div class="form-group row">
      <label
        class="col-md-3 col-form-label text-md-right"
        for="login_username">ユーザ名</label>
      <div class="col-md-9">
        <input
          id="login_username"
          v-model="vModelValue"
          type="text"
          class="custom-control-input"
          name="username"
          @input="validation()">
       <div
          v-show="isValidationErr"
          class="text-black-50">{{ localValidationErrMsg }}</div>
      </div>
    </div>
  </div>
</div>

 シンプルなtype=”text”でこれです。inputタグの属性に凝ると更にvalue、placeholder、required、typeがnumberならばstep、max、minなどが増えます。これはたかだか一つの入力欄でありフォーム全体を考えた場合、inputタグセットが十個近く並んだりもします。素のHTMLコードのままその様なものを記述した場合、可読性が落ちてしまい開発も保守もやり難くなってしまいます。Vue.jsでコンポーネントとしてまとめることでとりあえずの解決を図ります。

 上のJSFiddleでコンポーネントを用いているHTMLコードは18行程です。実際はコンポーネント定義をHTMLコードと別の1ファイルにまとめるため、コンポーネント定義部はカウントしていません。上述した20行程のinputタグ周りを重ねて書くよりよっぽど楽になりました。
 コンポーネントを用いることで記述は楽になりましたが、全てtype=”text”で様々な属性が全くないinputタグセットでしかなく、柔軟性が犠牲になっています。属性を指定するための引数を増やすことによってもっと柔軟なコンポーネントにします。柔軟にするうえで気を付けることに、呼び出し側で不要なコードが増えない様することがあります。コンポーネントを呼び出すための引数にデフォルト値を与えることによってこれを実現します。

 inputタグの効果が多彩になりました。メールアドレスは\や日本語の様なメールアドレスに含まれることのない文字を打つと、その文字を消して警告を表示します。コードのHTMLを見て頂けばわかる通り引数がinputタグの属性の大部分をカバーする様になっています。それだけ大量の引数が用意されているにもかかわらず、コンポーネント呼び出しが短くまとまっているのがデフォルト値の効果です。

<input
 :value="value"
>
/** 省略 */
props:{
  value: {type: String, default: null},
}

の様に記述するとコンポーネント呼び出し時に引数valueを指定しない場合、value=nullとなりHTMLコード上でもvalue属性は指定されなかったことになります。これと同じ様ことを他の属性にも適用することで大量の引数を用意しつつも、呼び出しを簡単にしています。
 実際のコーディングではンポーネントの定義を1ファイルにまとめる単一ファイルコンポーネントの仕組みを用います。これにより、JSFiddleで表示しているなかなかリッチな画面を作るHTMLコードは次の様にまとまります。

<div id="app">
  <form-input
    label="ユーザ名"
    id="edit_username"
    name="username"
    placeholder="例:浜松 太郎"></form-input>
  <form-input
    label="メールアドレス"
    id="edit_mail"
    name="mail"
    type="mail"
    validation-template="mail"></form-input>
  <form-input
    label="番号"
    id="edit_number"
    name="number"
    type="number"
    value="0.53"
    max="1" min="0" step="0.01"></form-input>
  <form-input
    label="色"
    id="edit_color"
    name="color"
    type="color"
    value="#F0115F"></form-input>
</div>
>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG