• Как организовать опрос, как на tj?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Структура данных, содержащая вопросы.
    Массив объектов, каждый из которых представляет один вопрос. Внутри два свойства - текст вопроса, и массив с вариантами ответа:

    data: () => ({
      questions: [
        {
          text: '2 x 2?',
          answers: [ '5', '3', '69', '187' ],
        },
        {
          text: '...',
          answers: [ '...', '...', ... ],
        },
        ...
      ],
    }) ,

    Компонент вопроса.
    Принимает три параметра - текст вопроса, массив вариантов ответа, и выбранный ответ:

    props: [ 'text', 'answers', 'value' ],

    Показываем текст вопроса; на основе массива ответов создаём радиокнопки, если ответ совпадает с выбранным, соответствующая кнопка помечается как выбранная; при выборе кнопки отправляем значение родительскому компоненту:

    <div>{{ text }}</div>
    <div v-for="n in answers">
      <label>
        <input
          type="radio"
          :checked="n === value"
          @change="$emit('input', n)"
        >
        {{ n }}
      </label>
    </div>

    Компонент опроса.
    Принимает список вопросов в качестве параметра:

    props: [ 'questions' ],

    Из данных содержит в себе индекс текущего вопроса и массив выбранных ответов:

    data: () => ({
      index: 0,
      answers: [],
    }),

    Если индекс меньше количества вопросов, значит опрос ещё не окончен, показываем вопрос, в противном случае следует отобразить результаты:

    <div v-if="index < questions.length">
      вопрос
    </div>
    <div v-else>
      результаты
    </div>

    Чтобы показать вопрос, отрендерим экземпляр компонента вопроса, передав ему в качестве параметров содержимое элемента массива вопросов + привязав элемент массива ответов:

    <question
      v-bind="questions[index]"
      v-model="answers[index]"
    />

    Чтобы перейти к следующему вопросу, достаточно увеличить индекс текущего вопроса (кнопку, пока пользователь не выбрал ответ, можно: а) блокировать - :disabled="!answers[index]"; б) скрывать - v-show="answers[index]"):

    <button @click="index++">дальше</button>

    Результаты - список вопросов и соответствующих им (с тем же индексом) ответов:

    <div v-for="(n, i) in questions">
      {{ n.text }} - {{ answers[i] }}
    </div>


    https://jsfiddle.net/fdbj1w29/
    Ответ написан
    1 комментарий
  • Как использовать однофайловый компонент много раз?

    Ni55aN
    @Ni55aN
    <chat-message ...> должен быть прописан в шаблоне текущего компонента с v-for директивой, а по событию нужно добавлять данные в массив в состоянии. Прямая работа с DOM не приветствуется, тем более здесь она вообще не в тему. Смотрите документацию по Vue.js
    Ответ написан
    5 комментариев