2017-06-07 13 views
2

親コンポーネントのプロパティオブジェクトを取得するのが難しく、同じコンポーネント内で値を使用できるようにするために、動的に入力されるプロパティがあります。親コンポーネントのプロパティオブジェクトとのVueJs反応性

説明するのは少し難しいので、以下の例を見てください。

親コンポーネント

<script> 
    export default { 
     data() { 
      return { 
       fields: {}, 
      } 
     } 
    } 
</script> 

子コンポーネント

<template> 
    <select 
     @change="update()" 
     v-model="field" 
    > 
     <option 
      v-for="option in options" 
      :value="option.value" 
     > 
      {{ option.name }} 
     </option> 
    </select> 
</template> 
<script> 
    export default { 
     props: { 
      initialOptions: { 
       type: Array, 
       required: true 
      } 
     }, 
     data() { 
      return { 
        field: '', 
       options: this.initialOptions 
      } 
     }, 
     mounted() { 
      if (
       (this.field === undefined || this.field === '') && 
       this.options.length > 0 
      ) { 
       this.field = this.options[0].value; 
      } 
      this.update(); 
     }, 
     methods: { 
      update() { 
       this.$emit('input', this.field); 
      } 
     } 
    } 
</script> 

DOM

それらがマウントされたときに、私はしかし dn :class="{ dn : fields.type_id == 2 }"がクラスを追加していないいくつかの奇妙な理由で、彼らは inputを発するよう fieldsオブジェクトがその関連値を持つ子コンポーネントモデルの全てを取得することがわかりますVueのコンソールを使用
<parent-component inline-template> 

    <div> 

     <child-component>   
      :initial-options="[{..}, {..}]" 
      v-model="fields.type_id" 
     ></child-component> 

    </div> 

    <div :class="{ dn : fields.type_id == 2 }"> 

     // ... 

    </div> 

</parent-component> 

選択が2に変更されます。 Domは、親コンポーネントと子コンポーネントの間で同期される変更を反映していないようです。

どのように機能させるための助け?

+0

親の 'fields'にどのようにプロパティを追加していますか? – Bert

+0

子コンポーネントに対して 'v-model'指示文を使用し、各子コンポーネントからの関連値を持つ' mounted'イベントを出力します。 –

+0

あなたはそれを見せてもらえますか?私が得意とするのは、 'fields'が空のオブジェクトとして始まっていることです。そのプロパティを間違って追加すると、Vueは変更を検出できなくなります。 – Bert

答えて

2

ここで私はコメントで取得しようとしていたものです。オブジェクトに動的に追加されるプロパティには、$setを使用して追加しない限り、Vue cannot detect changesが追加されます。 fieldsオブジェクトにはtype_idプロパティはありませんが、v-model="fields.type_id"を使用しているため追加されています。したがって、Vueはいつ変化するのか分かりません。

ここでは、それを追加して、テキストの色が期待どおりに変化します。

console.clear() 
 

 
Vue.component("child-component", { 
 
    template: ` 
 
    <select 
 
     @change="update()" 
 
     v-model="field" 
 
    > 
 
     <option 
 
      v-for="option in options" 
 
      :value="option.value" 
 
     > 
 
      {{ option.name }} 
 
     </option> 
 
    </select> 
 
    `, 
 
    props: { 
 
    initialOptions: { 
 
     type: Array, 
 
     required: true 
 
    } 
 
    }, 
 
    data() { 
 
    return { 
 
     field: '', 
 
     options: this.initialOptions 
 
    } 
 
    }, 
 
    mounted() { 
 
    if (
 
     (this.field === undefined || this.field === '') && 
 
     this.options.length > 0 
 
    ) { 
 
     this.field = this.options[0].value; 
 
    } 
 
    this.update(); 
 
    }, 
 
    methods: { 
 
    update() { 
 
     this.$emit('input', this.field); 
 
    } 
 
    } 
 
}) 
 

 
new Vue({ 
 
    el: "#app", 
 
    data: { 
 
    fields: { 
 
     type_id: null 
 
    } 
 
    } 
 
})
.dn { 
 
    color: red; 
 
}
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script> 
 
<div id="app"> 
 
    <div> 
 
    <child-component :initial-options="[{name: 'test', value: 1}, {name: 'test2', value: 2}]" v-model="fields.type_id"></child-component> 
 
    </div> 
 
    <div :class="{ dn : fields.type_id == 2 }"> 
 
    Stuff 
 
    </div> 
 
</div>

+0

これは残念ですが、私はいつもそれらを小道具を介して親コントローラに渡す必要があります。 –

0

あなたは再利用可能なコンポーネントを作成しようとしているように見えます。

親コンポーネントがその努力の半分以上を処理する必要がある場合、再使用可能なコンポーネントの価値はどのようなものかと思います。コンポーネントは、より良いあなたは、すべて自分自身で、次のHTMLのすべてを提供するコンポーネントを作成している、...

基本的に
<DifficultToUseSelect/>. 

指名されるかもしれません...

<select></select> 

他のすべてはによって管理されています親コンポーネントおそらく、次のいずれかを実行するために、より有用であろう

...

  • StateAbbrevsSelectのように、特定のコンポーネントの選択で

    カプセル化頻繁に必要なオプション、Vモデル=「状態」

  • 選択コンポーネントにデータモデルの名前を渡します。コンポーネントは、モデルを介して独自のデータをロードして管理します。

  • WebサービスのURLをコンポーネントに渡し、コンポーネントを呼び出してオプションをロードします。

私がここで伝えようとしている主な点は、親コンポーネントによって半分以上の労力が処理される再使用可能なコンポーネントを作成することは、実際にはあまり再利用できないということです。

関連する問題