2016-08-25 1 views
3

私は20以上のフィールドを持つ巨大なフォームを持っています。私は今書いているコードに冗長性を感じています。最善の方法は何ですか?大きなフォームのVueJS

<script> 
new Vue({ 
    data : { 
     user : { 
      first_name : "", 
      last_name : "", 
      username : "", 
      and 20+......... 
     } 
    } 
}); 
</script> 

<form> 
    <input name="first_name" v-model="first_name"> 
    <input name="last_name" v-model="last_name"> 
    <input name="username" v-model="username"> 
    and 20+......... input fields 
</form> 

このような感じがします。ユーザーオブジェクトは動的に作成されます。これは可能ですか?

<script> 
new Vue({ 
    data : { 
     user : Object 
    } 
}); 
</script> 

<form v-model="user"> 
    <input name="first_name"> 
    <input name="last_name"> 
    <input name="username"> 
    and 20+......... input fields 
</form> 

事前に

+0

カスタムディレクティブを作ることができるが、すべての入力に対して 'V-model'をバインドできるようにする必要があるだろう、とVueがを提供していないようですプログラムでディレクティブをバインドする方法 –

+0

私のモジュールvue-formationを使うことができます:) – vbranden

+0

古い質問ですが、私はVue 2の答えを更新しました。 –

答えて

-1

どの程度

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

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

をいただき、ありがとうございますか!

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

+0

これはポスターが求めていたものの逆です。 DOMを作成するデータの代わりに、彼はDOMにデータを作成させたいと考えています。 –

+0

少なくとも、どちらも可能であり、優れたエンジニアリングです – gurghet

-1

は、Vueの中で完全にやり直し2

あなたのアプローチは、その中には、ビュー内のデータ構造をレイアウトし、Vueのは、それを拾うしたい、通常のVueアプローチの逆でありますデータにレイアウトしてVueでレンダリングするのではなく、あなたが達成したいカスタマイズされたレイアウトを持っているなら、それがどのように望ましいかを私は見ることができます。

従来にないソリューションには、従来にないソリューションが必要なため、このアプローチは慣習的ではありません。特に、子コンポーネントが親のデータを変更することは一般的に推奨されていません。つまり、フォーム入力をスロットとして受け入れ、親オブジェクトを小道具として受け入れるコンポーネントを作成することです。 mountedでは、それはname属性を持つすべてのinputのフィールドを取得し、

  1. $set
  2. を使用して、親オブジェクトのメンバーを作成し、新しく作成されたメンバー
  3. に時計をセットにinputイベントリスナーを追加します双方向バインディングを完了する

フォーム自体をより汎用的にするために、おそらくコンポーネントに多くの小道具を追加したいと思うかもしれませんが、これはあなたに機能を提供しますあなた探しています。原則として

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 ways 
 
setTimeout(() => { 
 
    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>

関連する問題