Как проверить выбранный checkbox во vue.js?
Создаю тест опросник на vue.js, опросник состоит из слайдов, выбрал вариант на первом слайде, нажимаешь далее, там новые варианты, нужно, чтоб если ни один checkbox не выбран, кнопка далее не работала.
- Вопрос задан более трёх лет назад
- 2273 просмотра
Комментировать
Решения вопроса 1

0xD34F @0xD34F Куратор тега Vue.js
Создаёте массив answers для хранения ответов. В зависимости от количества ожидаемых ответов (один или несколько) его элементы будут строками или массивами.
Связываете элементы answers с радиокнопками/чекбоксами вариантов ответов:
Создаёте вычисляемое свойство, которое будет индикатором наличия ответа/ответов на текущий вопрос:
computed: < answerSelected() < return this.answers[this.questionIndex].length; >, >,
И, наконец, используете это свойство для блокирования кнопки перехода к следующему вопросу:
UPD. Вынесено из комментариев:
А можете подсказать, как в результат вывести не только отмеченные поля, но на какой вопрос были эти поля отмечены?
Можно в шаблоне добавить индекс при переборе ответов, по которому будем доставать вопрос. Или можно сделать ответ свойством вопроса — тогда при выводе результатов перебираем вопросы, и вся нужная информация доступна в одном месте.
Как отметить и предыдущие чекбоксы?
Есть ли возможность с помощью vue.js при выборе вторго чекбокса — отмечать выбранными первый и второй, при выборе третьего — 1-ый и 2-ой и т.д. (выбор всех предыдущих)?
Примеров не могу найти и реализовать не понятно с чего. Может кто подскажет.
- Вопрос задан более трёх лет назад
- 427 просмотров
Комментировать
Решения вопроса 1

0xD34F @0xD34F Куратор тега Vue.js
Свойство checked сделать массивом, который будет содержать состояния чекбоксов. Сами чекбоксы на основе этого массива и создавать, через v-for . Слушать событие change, по которому выставлять состояния предыдущих чекбоксов (относительно того, на котором событие случилось) в true, следующих в false:
data: () => (< checked: [ 0, 0, 0, 0, 0 ], >), methods: < onChange(e, index) < const checked = e.target.checked; this.checked = [ . Array(index + checked).fill(1), . Array(this.checked.length - index - checked).fill(0), ]; >, >,
UPD. Вынесено из комментариев:
а если несколько таких списков будет
Очевидно, нужен отдельный массив checked для каждого списка (если только вы не хотите, чтобы все списке выглядели одинаково). Что касается функции onChange, то надо будет добавить ей дополнительный параметр — чтобы была возможность указывать, с каким именно списком в данный момент идёт работа.
Работа с формами
Можно использовать директиву v-model для двунаправленного связывания данных с элементами форм input, textarea и select. Способ обновления элемента выбирается автоматически в зависимости от типа элемента. Хотя v-model и выглядит как нечто волшебное, в действительности это лишь синтаксический сахар для обновления данных в элементах ввода, с некоторыми поправками для исключительных случаев.
v-model игнорирует начальное значение атрибутов value , checked или selected на любых элементах форм. Данные экземпляра Vue всегда считаются источником истины. Начальное значение необходимо объявить на стороне JavaScript, внутри опции data компонента.
Внутренне v-model использует разные свойства и генерирует разные события для различных элементов ввода:
- элементы для ввода текста и многострочного текста используют свойство value и событие input ;
- чекбоксы и радиокнопки используют свойство checked и событие change ;
- выпадающие списки используют свойство value и событие change .
В языках, требующих IME (китайский, японский, корейский и т.д.), можно заметить, что v-model не обновляется по мере IME-композиции. Если вы хотите обрабатывать и эти обновления, используйте события input .
Текст
input v-model="message" placeholder="отредактируй меня">
p>Введённое сообщение: {{ message }} p>
Многострочный текст
span>Введённое многострочное сообщение: span>
p style="white-space: pre-line;">{{ message }} p>
br>
textarea v-model="message" placeholder="введите несколько строчек"> textarea>
Введённое многострочное сообщение:
Интерполяция внутри textarea ( ) не будет работать. Используйте вместо неё директиву v-model
Чекбоксы
Один чекбокс, привязанный к булевому значению:
input type="checkbox" id="checkbox" v-model="checked">
label for="checkbox">{{ checked }} label>
Список чекбоксов, привязанных к одному массиву:
input type="checkbox" id="jack" value="Джек" v-model="checkedNames">
label for="jack">Джек label>
input type="checkbox" id="john" value="Джон" v-model="checkedNames">
label for="john">Джон label>
input type="checkbox" id="mike" value="Майк" v-model="checkedNames">
label for="mike">Майк label>
br>
span>Отмеченные имена: {{ checkedNames }} span>
new Vue({
el: '. ',
data: {
checkedNames: []
}
})
Джек Джон Майк
Отмеченные имена: >
Радиокнопки
input type="radio" id="one" value="Один" v-model="picked">
label for="one">Один label>
br>
input type="radio" id="two" value="Два" v-model="picked">
label for="two">Два label>
br>
span>Выбрано: {{ picked }} span>
Один
Два
Выбрано: >
Выпадающие списки
Выбор одного варианта из списка:
select v-model="selected">
option disabled value="">Выберите один из вариантов option>
option>А option>
option>Б option>
option>В option>
select>
span>Выбрано: {{ selected }} span>
new Vue({
el: '. ',
data: {
selected: ''
}
})
Если начальное значение выражения v-model не соответствует ни одному из вариантов списка, элемент будет отображаться в «невыбранном» состоянии. В iOS это приведёт к тому, что пользователь не сможет выбрать первый элемент, потому что iOS не сгенерирует событие change в этом случае. Поэтому рекомендуется предоставлять отключённый disabled -вариант выбора с пустым значением value, как показано в примере выше.
Выбор нескольких вариантов из списка (с привязкой к массиву):
select v-model="selected" multiple>
option>А option>
option>Б option>
option>В option>
select>
br>
span>Выбрано: {{ selected }} span>
Динамическое отображение списка опций с помощью v-for :
select v-model="selected">
option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
option>
select>
span>Выбрано: {{ selected }} span>
new Vue({
el: '. ',
data: {
selected: 'А',
options: [
{ text: 'Один', value: 'А' },
{ text: 'Два', value: 'Б' },
{ text: 'Три', value: 'В' }
]
}
})
Связывание значений
Для радиокнопок и выпадающих списков в качестве v-model обычно используются статические строки, а для чекбоксов — булевые значения:
input type="radio" v-model="picked" value="a">
input type="checkbox" v-model="toggle">
select v-model="selected">
option value="abc">ABC option>
select>
Иногда необходимо связать значение с динамическим свойством экземпляра Vue. Для этого можно использовать v-bind . Кроме того, использование v-bind позволяет связывать поле ввода с нестроковыми значениями.
Чекбокс
input
type="checkbox"
v-model="toggle"
true-value="да"
false-value="нет"
>
// если чекбокс выбран:
vm.toggle === 'да'
// если чекбокс сброшен:
vm.toggle === 'нет'
Атрибуты true-value и false-value не влияют на атрибут value тега input, потому что браузеры пропускают невыбранные чекбоксы при отправке форм. Чтобы гарантированно отправлять одно из двух значений с формой (например, «да» или «нет») используйте радиокнопки.
Радиокнопки
input type="radio" v-model="pick" v-bind:value="a">
// если отмечено:
vm.pick === vm.a
Списки выбора
select v-model="selected">
option v-bind:value="{ number: 123 }">123 option>
select>
// когда выбрано:
typeof vm.selected // => 'object'
vm.selected.number // => 123
Модификаторы
.lazy
По умолчанию v-model синхронизирует ввод с данными по событию input (за исключением вышеупомянутых событий IME). Можно указать модификатор lazy , чтобы использовать для синхронизации после события change :
input v-model.lazy="msg">
.number
Для автоматического приведения введённого пользователем к Number, добавьте модификатор number :
input v-model.number="age" type="number">
Зачастую это полезно, потому что даже при указанном атрибуте type=»number» значением поля ввода всегда будет строка. Если значение не удаётся распарсить с помощью parseFloat() , то возвращается оригинальное значение.
.trim
Если необходимо, чтобы автоматически обрезались пробелы в начале и в конце строки, используйте модификатор trim для полей ввода, обрабатываемых через v-model :
input v-model.trim="msg">
Использование v-model с компонентами
Если вы ещё не знакомы с компонентами Vue, пока просто пропустите эту секцию
Встроенных в HTML элементов ввода не всегда достаточно. К счастью, компоненты Vue позволяют создавать собственные аналоги с полностью настраиваемым поведением. Эти элементы тоже могут работать с директивой v-model !
Обнаружили ошибку или хотите добавить что-то своё в документацию? Измените эту страницу на GitHub! Опубликовано на Netlify .
Сделать выбранную форму checkbox устойчивой к обновлению страницы в браузере на Vue.js
У меня есть приложение To Do List на Vue. С помощью кнопки добавить запись, добавляется новая строка текста, каждая из которых имеет чекбокс и кнопку удалить. Моя задача: сохранять все введенные данные из форм (текст и выбран или нет чекбокс) при обновлении страницы браузера. Для этого использую mounted и watch, но получается только сохранять данные текста-чекбоксы так и не нашел пока как сохранить (неудачные попытки в коде не выкладывал). Помогите с кодом, пожалуйста.
Vue.createApp( < data()< return< placeholder: 'Start typing', inputvalue: '', notes: [], checked: [] >>, mounted() < this.notes = JSON.parse(localStorage.getItem('note')) || []; >, watch: < notes: < handler: function() < localStorage.setItem('note', JSON.stringify(this.notes)); >, deep: true > >, methods: < addnewtask()< if (this.inputvalue !== '')< this.notes.push(this.inputvalue) this.inputvalue='' >>, removetask(index) < if (confirm('Do you really want to delete?')) this.notes.splice(index, 1) >> >).mount(app)
body < font-family: sans-serif; font-size: 14px; color: #030303; background: #3d5f82; >h1 < font-weight: 500; text-transform: uppercase; text-align: center; font-style: solid; >.btn < color: #31d78c; place-content: center; place-items: center; width: fit-content; border-radius: 99px; border: 1px solid #31d78c; text-decoration: none; text-transform: uppercase; margin-right: 10px; margin-top: 10px; padding: 10px; font-weight: 700; background: #fff; >.btn:hover < cursor: pointer; background-color:rgb(231, 239, 235); >.btn.danger < color: #eb3c15; place-content: center; place-items: center; width: fit-content; border-radius: 99px; border: 1px solid #eb3c15; text-decoration: none; text-transform: uppercase; margin-right: 10px; margin-top: 10px; padding: 10px; font-weight: 700; background: #fff; >.btn.danger:hover < cursor: pointer; background-color:rgb(236, 219, 219); >.container < margin: 0 auto; max-width: 1000px; >.form-control < position: relative; margin-bottom: 10px; >.form-control input, .form-control select < margin: 0; outline: none; border: 2px solid #ccc; display: block; width: 95%; color: #2c3e50; padding: 0.5rem 1.5rem; border-radius: 3px; font-size: 1rem; >.card < overflow: hidden; padding: 1rem; margin-bottom: 1rem; border-radius: 10px; box-shadow: 2px 3px 10px rgba(0, 0, 0, 0.2); background: #fff; >.card.center < display: flex; flex-direction: column; align-items: center; >.list < margin: 0; padding: 0; list-style: none; >.list-item