<div id="app" class="m-3">
  <form :class="formClass">
    <div class="form-group">
      <label for="email">Email address</label>
      <input type="email" class="form-control" id="email">
    </div>
  </form>
  <x-button
    text="Submit"
    v-on:submit-form="changeFormState"></x-button>
</div>
form {
  position: relative;
}

form.loading ::before {
  position: absolute;
  width: 100%;
  height: 100%;
  content: 'Loading...';
  background: rgba(25, 25, 25, 0.5);
  color: white;
  padding: 20px;
}
Vue.component('x-button', {
  props: ['text'],
  template: `
    <button
      type="submit"
      class="btn btn-primary"
      v-on:click="$emit('submit-form', 'loading')">
      {{ text }}
    </button>
  `
});

var vue = new Vue({
  el: "#app",
  data: {
    formClass: ''
  },
  methods: {
    changeFormState: function(className) {
      this.formClass = className;
    }
  }
})

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css

External JavaScript

  1. https://cdn.jsdelivr.net/npm/vue/dist/vue.js