Handling forms in Vue.js

Vidya Ramakrishnan

Front-end developer at HasGeek

vidya-ram          vidya_ramki

 

Text

Text

<input name="name" v-model="name" type="text" placeholder="Full name">

Form binding in Vue

v-model is used to create

two-way data bindings on  form fields

<select v-model="choice" name="choice">
    <option>choice 1</option>
    <option>choice 2</option>
    <option>choice 3</option>
</select>
<textarea v-model="reason" name="reason" placeholder="Tell us why you like it"></textarea>
<input type="radio" name="frequency" v-model="frequency" value="daily" id="daily">
<label for="daily">Daily</label>

<input type="radio" name="frequency" v-model="frequency" value="weekends" id="weekends">
<label for="weekends">Weekends</label>
<template>
    <form @submit.prevent="handleSubmit">
      <input name="name" v-model="form.name" type="text" placeholder="Full name">
      <textarea v-model="form.reason" placeholder="Reason" ></textarea>
      <button class="button" type="submit">Submit</button>
    </form>
</template>


<script>
export default {
  name: 'Form',
  data () {
    return {
      form: {
        name: '',
        reason: '',
      },
    }
  },
  methods: {
    handleSubmit () {
      console.log('Form submitted');
    }
  }
}
</script>

Form in Vue

HasGeek TV app has many admin pages with forms.

Our python flask backend has the capability to generate HTML forms and render them.

General format that we follow when we require form for an application is as simple as defining the forms fields and backend takes care of providing the form HTML along with the required JavaScript.

 

Use backend generated HTML forms

in the client side

<template>
  <div>
    <Form v-if="showForm"></Form>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: 'EditChannel',
  data() {
    return {
      showForm: false,
      errors: [],
    };
  },
  components: {
    Form: () => import('./FormComponent')
  },
created() {
    axios.get(this.path)
    .then((response) => {
      this.formTemplate = response.data.form;
      this.showForm = true;
    })
    .catch((e) => {
      this.errors.push(e);
    });
  },
};
</script>

Async form component

Dynamic component

<template>
  <div class="main">
    <h2>Dynamic component</h2>
    <p>Select a component to load</p>
    <input type="radio" name="type" v-model="componentType" value="1" id="1" class="radio" 
           @change="handleSelect"><label for="1" class="radio-label">Component 1</label>
    <input type="radio" name="type" v-model="componentType" value="2" id="2" class="radio" 
           @change="handleSelect"><label for="2" class="radio-label">Component 2</label>
    <component :is="component" v-if="component" />
  </div>
</template>

<script>
export default {
  name: 'DynamicComponent',
  data () {
    return {
      component: '',
      componentType: ''
    }
  },
  components: {
    component1: () => import('./Swappablecomponent1.vue'),
    component2: () => import('./Swappablecomponent2.vue')
  },
  methods: {
    handleSelect () {
      if (this.componentType === '1') {
        this.component = 'component1'
      } else if (this.componentType === '2') {
        this.component = 'component2'
      }
    }
  }
}
</script>

Computed properties

<template>
  <div class="main">
    <p class="text">Computed Properties</p>
    <textarea v-model="message" class="message"></textarea>
    <p>Message: "{{ message }}"</p>
    <p>String length: {{ messageLen }}</p>
  </div>
</template>

<script>
export default {
  name: 'ComputedProperties',
  data () {
    return {
      message: ''
    }
  },
  computed: {
    // messageLen is a computed property 
    messageLen () {
      if (this.message) {
        return this.message.length
      }
    }
  }
}
</script>
<template>
  <div>
    <component :is="Form"></component>
  </div>
</template>
<script>
import axios from 'axios';
import Utils from '../assets/js/utils';

let vm = {};

export default {
  name: 'AddChannel',
  data() {
    return {
      path: this.$route.path,
      formTemplate: '',
      formId: '',
    };
  },
  computed: {
    Form() {
      const template = 
        this.formTemplate ? 
        this.formTemplate : 
        '<p>Loading..</p>';
      return {
        template,
        methods: {
          onFormSubmit() { 
            Utils.formSubmit(vm.formId); 
          },
        },
      };
    },
  },
  

Dynamic component &

Computed properties

 

<script>
created() {
    vm = this;
    axios.get(this.path)
    .then((response) => {
      /* Utils function adds onsubmit event handler
      for Vue to form
      Replace script with script2 
      (https://github.com/taoeffect/vue-script2) */
      this.formTemplate = 
        Utils.getVueFormTemplate(response.data.form);
      this.formId = 
        Utils.getElementId(this.formTemplate);
    })
    .catch((error) => {
      this.error = error;
    });
  },
};
</script>

Thank you.

 


HasGeek TV

codebase is open source and can found here:

https://github.com/hasgeek/hasgeek.tv

Handling forms in Vue.js

By vidya_ramki

Handling forms in Vue.js

My experience rewriting a legacy app to a PWA using Vue.js while reusing code.

  • 698