vue.js передача Связывание данных VueTwo с вложенными компонентами



vue.js передача данных между компонентами (1)

Ответ будет обрабатывать событие click и выпустить событие (custom) selected-answer. У вопроса будет свой собственный элемент данных для хранения выбранного идентификатора ответа; на этом будет основываться 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>

Предположим, я хочу отобразить список вопросов. Для каждого вопроса есть список ответов, ни один из которых не является правильным или неправильным. Для каждого вопроса пользователь может выбрать ответ. Мне интересно, как создать двустороннюю привязку к выбранному ответу.

Vue:

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, я хочу, чтобы выбранная модель вопросаAnswerId / selectedAnswerName модели вопроса соответствовала выбранному свойству ответов. Поэтому, что мне нужно добавить к моим компонентам, чтобы выполнить эту двустороннюю привязку? Я считаю, что для этого нужны входные элементы и v-model, но я не мог понять это. Кроме того, я всего лишь один день в Vue.js и не имею опыта работы с соответствующими структурами. Поэтому, если я делаю что-то явно ошибочное или против лучшей практики, это было бы хорошо знать. Заранее спасибо!