2017-03-28 7 views
0

質問リストを表示するとします。各質問には、答えのリストがありますが、どれも正しいか間違っていません。各質問について、ユーザは回答を選択することができる。私は選択された答えに双方向バインディングを作成する方法が不思議です。VueTwo Wayネストされたコンポーネントによるデータのバインド

ヴュ:

new Vue(
{ 
    el: "#app", 

    data: 
    { 
     questions: [{}] 
    } 
} 

例質問モデル:

{ 
    id: 1, 
    name: "Which color is your favorite?", 
    selectedAnswerId: null, 
    selectedAnswerName: null, 
    answers: 
    [ 
     {id: 1, name: red, photoUrl: ".../red", selected: false}, 
     {id: 2, name: green, photoUrl: ".../green", selected: false}, 
     {id: 3, name: blue, photoUrl: ".../blue", selected: false}, 
    ] 
} 

コンポーネント:

var myAnswer = 
{ 
    props: ["id", "name", "url", "selected"], 
    template: 
    ` 
     <div class="answer" v-bind:class="{selected: selected}"> 
      <img class="answer-photo" v-bind:src="url"> 
      <div class="answer-name">{{name}}</div> 
     </div> 
    ` 
}; 

Vue.component("my-question", 
{ 
    props: ["id", "name", "answers"], 
    components: 
    { 
     "my-answer": myAnswer 
    }, 
    template: 
    ` 
     <div class ="question"> 
      <div class="question-name">{{name}}</div> 
      <div class="question-answers"> 
       <my-answer v-for="answer in answers" v-bind:id="answer.id" v-bind:name="answer.name" v-bind:url="answer.photoUrl" v-bind:selected="answer.selected"></my-answer> 
      </div> 
     </div> 
    ` 
}); 

ユーザーがdiv要素をクリックすることで、質問への回答を選択し、I質問モデルのselectedAnswerId/selectedAnswerNameと、回答が選択されたプロパティをsそれに応じて。したがって、この双方向バインディングを達成するために、コンポーネントに何を追加する必要がありますか?私はそれが入力要素とVモデルを必要とすると信じていますが、私はそれを理解できませんでした。また、私はVue.jsへの唯一の日であり、関連するフレームワークに関する経験はありません。だから、もし私が間違ったことやベストプラクティスに対して何かをしているのであれば、それも知っていると良いでしょう。前もって感謝します!

+0

まあ結合2つの方法を持っているために、あなたはこれまで、私はここに任意の入力を見ることができないいくつかのdata.Soに囲まれていることでV-モデルディレクティブを持っているいくつかの入力が必要です。 ..選択した答えに 'select'入力を使用したいのですか? –

+0

名前と写真の両方を含む回答divをクリックするようにします。したがって、ユーザーが好きな色として赤色を選択したい場合、赤色の画像を「赤色」のタイトルでクリックします。したがって、私は答えdivが正しい入力をトリガーするラベルにラップされている隠された入力要素が必要であると信じています。 –

+1

入力はまったく必要ありません。値を受け入れて入力イベントを発生させるには、コンポーネントが必要です。 https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events – Bert

答えて

0

答えはclickイベントを処理し、(カスタム)selected-answerイベントを出力します。質問には、選択した回答IDを保存する独自のデータ項目があります。回答コンポーネントのselected小道具はそれに基づいています。質問は、選択された応答イベントをselectedIdに設定することによって処理されます。

var myAnswer = { 
 
    props: ["id", "name", "url", "selected"], 
 
    template: ` 
 
     <div class="answer" v-bind:class="{selected: selected}" 
 
     @click="setSelection()" 
 
     > 
 
      <img class="answer-photo" :src="url"> 
 
      <div class="answer-name">{{name}}</div> 
 
     </div> 
 
    `, 
 
    methods: { 
 
    setSelection() { 
 
     this.$emit('selected-answer', this.id); 
 
    } 
 
    } 
 
}; 
 

 
Vue.component("my-question", { 
 
    props: ["id", "name", "answers"], 
 
    data() { 
 
    return { 
 
     selectedId: null 
 
    }; 
 
    }, 
 
    components: { 
 
    "my-answer": myAnswer 
 
    }, 
 
    template: ` 
 
     <div class ="question"> 
 
      <div class="question-name">{{name}}</div> 
 
      <div class="question-answers"> 
 
       <my-answer v-for="answer in answers" 
 
       :id="answer.id" :name="answer.name" :url="answer.photoUrl" 
 
       :selected="answer.id === selectedId" @selected-answer="selectAnswer"></my-answer> 
 
      </div> 
 
     </div> 
 
    `, 
 
    methods: { 
 
    selectAnswer(answerId) { 
 
     this.selectedId = answerId; 
 
    } 
 
    } 
 
}); 
 

 
new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    questions: [{ 
 
     id: 1, 
 
     name: "Which color is your favorite?", 
 
     answers: [{ 
 
      id: 1, 
 
      name: 'red', 
 
      photoUrl: ".../red" 
 
     }, 
 
     { 
 
      id: 2, 
 
      name: 'green', 
 
      photoUrl: ".../green" 
 
     }, 
 
     { 
 
      id: 3, 
 
      name: 'blue', 
 
      photoUrl: ".../blue" 
 
     }, 
 
     ] 
 
    }] 
 
    } 
 
});
.answer { 
 
    cursor: pointer; 
 
} 
 

 
.selected { 
 
    background-color: #f0f0f0; 
 
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script> 
 
<div id="app"> 
 
    <my-question v-for="q in questions" :name="q.name" :answers="q.answers"></my-question> 
 
</div>

関連する問題