Vue.js Dynamic Form

by Antoine

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.0/es6-promise.auto.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vee-validate/2.0.0-rc.3/vee-validate.min.js"></script>
<div class="container">
  <div class="page">
    <h2><span>Dynamic Web Form</span></h2>
    <form id="dynform" method="POST" class="panel-body form-horizontal" v-on:submit.prevent="displayForm">
      <div class="row">
        <div class="col-md-12 ">
          <form-question v-for="question in questions" :question="question" :key="question.id"></form-question>
        </div>
      </div>
      <button type="submit" class="btn btn-primary">Submit</button>
    </form>
  </div>
</div>

JavaScript

Vue.component('form-input', {
  props: ['question'],
  template: '<div class="form-group" :class="{\'input\': true, \'has-error\': errors.has(question.label) }">' +
    '<input type="text" v-validate="question.validate" :id="question.id" :name="question.label"'+
           'class="form-control" v-model="question.answer":placeholder="question.placeholder"/>' +
    '    <span v-show="errors.has(question.label)" class="help-block">{{ errors.first(question.label) }}</span>' +
    '</div>'
});

Vue.component('form-select', {
    props: ['question'],
    created: function () {
        this.$options.template = '<div class="form-group" :class="{\'input\': true, \'has-error\': errors.has(question.label) }">' +
        '<select v-validate="question.validate" :id="question.id" :name="question.label" v-model="question.answer" class="form-control" >' +
        '<option v-for="option in question.options" >{{option}}</option>' +
        '</select>' +
        '<span v-show="errors.has(question.label)" class="help-block">{{ errors.first(question.label) }}</span>' +
        '</div>'
    }
});

Vue.component('form-radio', {
  props: ['question'],
  created: function() {
    this.$options.template = '<div class="col-sm-9"> ' +
      '<label  v-for="option in question.options" :for="option" class="radio-inline" >' +
      '<input :id="option" :name="question.label" type="radio" v-model="question.answer"' +
      '       :value="option"/> {{option}}' +
      '</label>' +
      '</div>';
  }
});

Vue.component('form-textarea', {
  props: ['question'],
  template: '<textarea v-validate="question.validate" class="form-control" placeholder="" v-model="question.answer"  :placeholder="question.placeholder"/>'
});

Vue.component('form-question', {
  props: ['question'],
  created: function() {
    this.$options.template = '<div class="form-group"> ' +
      '<label for="" class="col-sm-3 col-lg-2 control-label">' +
      '{{question.label}}';
    if ((this.question.validate !== undefined) &&...