JSFiddle - React, Tailwind, and code Playground

by darkylmnx

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuelidate.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/validators.min.js"></script>
<div id="app">
  <my-form-1 url="https://jsonplaceholder.typicode.com/posts"></my-form-1>
</div>

Vue

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

// on crée le comportement générique
const FormMixin = {
	props: {
  	url: {
    	type: String,
      required: true,
    },
  },
	data: () => ({ isSending: false }),
	methods: {
  	handle(successCallback, errorCallback) {
    	// on vérifie que c'est pas déjà en train d'envoyer
    	if (this.isSending) {
      	return;
      }
      
      // on vérifie que vuelidate est là
      if (this.$v) {
      	this.$v.$touch();

        if (this.$v.$error) {
       		alert('une erreur');
        	return;
        }
      }
      
      this.isSending = true;
      axios.post(this.url)
      	.then(res => {
        	// là tu fais ce que tu veux
          // tu peux avoir un traitement généric
          // tu peux attende un callback...
          alert('réussi');

          if (successCallback) {
          	successCallback();
          }
        })
        .catch(error => {
        	// là tu gère tes erreurs
          alert('erreur serveur');
          if (errorCallback) {
          	errorCallback();
          }
        })
        .finally(() => {
        	// là quand la req est fini, erreur ou succès
          // on stop le isSending
          this.isSending = false;
        });
    }
  },
};

const MyForm1 = {
	// on import le comportement
	mixins: [FormMixin], 
	data: () => ({
  	form: {
    	name: '',
      age: null,
    },
  }),
	// je défini mes validations
	validations: {
  	form: {
    	name: { required },
      age: { required, minValue: minValue(18) }
    }
  },
  methods: {
  	onSuccess() {
    	alert('je suis le callback');
      this.form.name = '';
      this.form.age = null;
    },
  },
	template: `
  	<form @submit.prevent="handle(onSuccess)">
    	<p>Il faut être majeur !</p>
      <p><input type="text" v-model="form.name" /></p>
      <p><input type="number" v-model="form.age" /></p>
      <p v-show="isSending">Traitement...</p>
      <p><button...