[Vuejs]-A Custom vuejs form component

0👍

This is part of my working code. I’ve create component which may have (or not) several form fields. All that comes from JSON.
I’ve created a loop and iterate there 4 components for text, options, checkbox and stars(for a rating).

<div v-for="(elem, ind) in problem.problem_config.structure">
  <con-text v-if="elem.type === 'text'"
  :element="elem"
  v-on:edit="editField"
  :value="getFilledValue(elem.id)"
  :key="elem.id"></con-text>

  <con-option v-if="elem.type === 'option'"
  :element="elem"
  v-on:edit="editField"
  :value="getFilledValue(elem.id)"
  :key="elem.id"></con-option>

  <con-checkbox v-if="elem.type === 'checkbox'"
  :element="elem"
  v-on:edit="editField"
  :value="getFilledValue(elem.id)"
  :key="elem.id"></con-checkbox>

  <con-stars v-if="elem.type === 'stars'"
  :element="elem"
  v-on:edit="editField"
  :value="getFilledValue(elem.id)"
  :key="elem.id"></con-stars>
</div>

for example text input looks like this

<template>
  <div class="field" style="margin-bottom:14px">
    <label>{{element.name}}</label>
    <input
    type="text"
    :placeholder="element.description"
    :maxlength="element.filter.max_length"
    v-model="content"
    >
    <p class="description">{{element.description}}</p>
  </div>
</template>

<script>
export default {
  name: 'con-text',
  props: ['element', 'value'],
  data: function () {
    return {
      content: this.value ? this.value : ''
    }
  },

  watch: {
    content: function (val) {
      let obj = {
        id: this.element.id,
        name: this.element.name,
        type: this.element.type,
        value: val,
        description: this.element.description
      }
      this.$emit('edit', obj)
    }
  }
}
</script>

option form:

<template>
  <div class="field" style="margin-bottom:14px">
    <label>{{element.name}}</label>
    <select class="ui fluid dropdown" v-model="content">
      <option disabled value="">{{element.description}}</option>
      <option v-for="opt of element.value" :key="opt.value" :value="opt.value">
        {{opt.label}}
      </option>
    </select>
    <p class="description">{{element.description}}</p>
  </div>
</template>

<script>
/* global $ */

export default {
  name: 'con-option',
  props: ['element', 'value'],
  data: function () {
    return {
      content: this.value ? this.value.value : null
    }
  },

  watch: {
    content: function (val) {
      let selectedEl = this.element.value.find(o => o.value === val)
      let valObj = {value: val, label: selectedEl.label}
      let obj = {
        id: this.element.id,
        name: this.element.name,
        type: this.element.type,
        value: valObj,
        description: this.element.description
      }
      this.$emit('edit', obj)
    }
  },

  mounted: function () {
    $('select.dropdown').dropdown()
  }
}
</script>

Basically idea is to create each field as component and pass properties there. And you can make more custom form than you have now.

Leave a comment