Vuelidate example

HTML

<script src="https://unpkg.com/vuelidate/dist/vuelidate.min.js"></script>
<script src="https://unpkg.com/vuelidate/dist/validators.min.js"></script>
<div id="app">
  <input v-model="$v.text.$model" :class="status($v.text)">

  <pre>{{ $v }}</pre>
</div>

CSS

input {
  border: 1px solid silver;
  border-radius: 4px;
  background: white;
  padding: 5px 10px;
}

.dirty {
  border-color: #5A5;
  background: #EFE;
}

.dirty:focus {
  outline-color: #8E8;
}

.error {
  border-color: red;
  background: #FDD;
}

.error:focus {
  outline-color: #F99;
}

Babel + JSX

Vue.use(window.vuelidate.default)
const { required, minLength } = window.validators

new Vue({
	el: "#app",
  data: {
  	text: ''
  },
  validations: {
    text: {
      isUnique(value) {
        if (value === '') return true
        return new Promise((resolve, reject) => {
          fetch(`https://jsonplaceholder.typicode.com/todos/${~~(Math.random()*9)}`)
            .then(response => response.json())
            /* .then(() => {
              throw new Error(false)
            }) */
            .then(json => resolve(json.completed))
            .catch((e) => reject(false))
        })
      }
    }
  },
  methods: {
  	status(validation) {
    	return {
      	error: validation.$error,
        dirty: validation.$dirty
      }
    }
  }
})