VueJS with Large Forms VueJS with Large Forms vue.js vue.js

VueJS with Large Forms


Completely Redone in Vue 2

Your approach is the reverse of the usual Vue approach, in that you want to lay out your data structure in the view and have Vue pick it up, rather than laying it out in the data and having Vue render it. I can see how that would be desirable if you have a customized layout you want to achieve.

Unconventional needs require unconventional solutions, so this approach is unconventional. In particular, it is not generally recommended that a child component modify data in a parent.

That said, the approach is to create a component that will accept the form inputs as a slot and the parent object as a prop. In mounted, it gets all the input fields with name attributes and

  1. Creates the member in the parent object, using $set
  2. Sets a watch on the newly-created member
  3. Adds an input event listener to complete the two-way binding

You would probably want to add more props to the component, to make the form itself more versatile, but this gives you the functionality you're looking for.

Vue.component('autoBindingForm', {  template: '<form><slot></slot></form>',  props: ['createIn'],  mounted() {    const inputs = this.$el.querySelectorAll('input[name]');    for (const i of inputs) {      this.$set(this.createIn, i.name, i.value);      this.$watch(`createIn.${i.name}`, (newVal, oldVal) => {        i.value = newVal;      });      i.addEventListener('input', (e) => {        this.createIn[i.name] = i.value;      });    }  }});const vm = new Vue({  el: '#app',  data: {    user: {}  }});// Testing that binding works both wayssetTimeout(() => {  vm.user.last_name = 'Set it';}, 800);
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script><div id="app">  <auto-binding-form :create-in="user">    <input name="first_name" value="hi">    <input name="last_name">    <input name="username">    <div>{{Object.keys(user)}}</div>    <div>{{Object.values(user)}}</div>  </auto-binding-form></div>


How about

data: {  fields: { name: {v:''}, surname: {v:''}, ... }}

and

<input v-for="(val, prop) in fields" :name="prop" v-model="val.v" />

?

https://jsfiddle.net/gurghet/dhdxqwjv/1/