turkish777
@turkish777
junior frontend

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

Необходимо организовать подобный опрос — TJ
Интересует подход, стоит ли использовать vue.js или можно обойтись jquery или нативным js, рекомендуется максимальная эффективность и лучше без больших библиотек. Если на vue намного быстрее, то интересует, как реализовать на vue, спасибо)
p.s. Опрос по одному вопросу, без перезагрузки, следующая открывается только по клику на btn
  • Вопрос задан
  • 204 просмотра
Решения вопроса 1
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/
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы