JSFiddle - React, Tailwind, and code Playground

by ken3desu

HTML

<script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.jsdelivr.net/vue/1.0.16/vue.js"></script>
<div id="app">
  <form-input
    label="ユーザ名"
    id="edit_username"
    name="username"></form-input>
  <form-input
    label="メールアドレス"
    id="edit_mail"
    name="mail"></form-input>
  <form-input
    label="番号"
    id="edit_number"
    name="number"></form-input>
  <form-input
    label="色"
    id="edit_color"
    name="colorr"></form-input>
</div>

<template id="form-input-template">
  <div class="row">
    <div class="col-md-12">
      <div class="form-group row">
        <label
          :for="id"
          class="col-md-3 col-form-label text-md-right">
          {{ label }}
        </label>
        <div class="col-md-9">
          <input
            :id="id"
            :name="name"
            v-model="vModelValue"
            type="text"
            class="form-control"
            @input="validation">
          <div
            v-show="isValidationErr"
            class="text-black-50">{{ localValidationErrMsg }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

JavaScript

Vue.component('form-input', {
  props: {
    label: {type: String, required: true},
    id: {type: String, required: true},
    name: {type: String, required: true},
  },
  data() {
    return {
      vModelValue: '',
      localValidationErrMsg: 'バリデーションエラー',
      isValidationErr: false,
      validationExcludePattern: null,
    };
  },
  methods: {
    validation() {
      if (this.validationExcludePattern == null || this.vModelValue == null) {
        return;
      }
      if (this.vModelValue.length > this.vModelValue.replace(this.validationExcludePattern, '').length) {
        this.vModelValue = this.vModelValue.replace(this.validationExcludePattern, '');
        this.isValidationErr = true;
      } else {
        this.isValidationErr = false;
      }
    },
  },
  template: '#form-input-template',
});


const vm = new Vue({
  el: '#app',
});