Элементы input и textarea
Для работы с элементами ввода, в частности, с элементами input, select, textarea, применяется директива v-model, которая устанавливает двустороннюю привязку между элементом ввода и свойством объекта Vue. При этом v-model игнорирует значения атрибутов value, checked и selected, которые имеются у элементов ввода.
Например, используем ряд базовых элементов input:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<label>Логин</label>
<input type="text" v-model="login" placeholder="Введите логин" class="form-control" /><br>
<label>Пароль</label>
<input type="password" v-model="password" placeholder="Введите пароль" class="form-control" /><br>
<label>Возраст</label>
<input type="number" v-model="age" min="18" placeholder="Введите возраст" class="form-control" /><br>
<label>Дата регистрации</label><br>
<input type="date" v-model="date" placeholder="Введите дату" class="form-control" />
<br>
<div>
<h3>Введенная информация</h3>
<p>Логин: {{ login }}</p>
<p>Пароль: {{ password }}</p>
<p>Возраст: {{ age }}</p>
<p>Дата регистрации: {{ date }}</p>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
login: '',
password: '',
date: '',
age: 22
}
})
</script>
</body>
</html>
textarea
Элемент textarea позволяет вводить многострочный текст и также связывается со свойством во Vue через директиву v-model:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<label>Введите комментарий</label>
<textarea v-model="comment" class="form-control"></textarea>
<br>
<div>
<h3>Комментарий</h3>
<p style="white-space: pre-line">{{ comment }}</p>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
comment: 'Комментарий...'
}
})
</script>
</body>
</html>
В то же время есть некоторые особенности по работе с textarea. Прежде всего, если используется директива v-model, то внутри textarea мы не можем поместить текст с помощью интерполяции:
<textarea v-model="comment" class="form-control">{{ comment }}</textarea>
И кроме того, при вводе текста в textarea с помощью клавиши Enter мы можем переносить строки. Чтобы переносы строк сохранялись при выводе текста на страницу, необходимо применять соответствующие стили css:
<p style="white-space: pre-line">{{ comment }}</p>
Флажки (Checkbox)
Флажки представляют элементы управления, которые могут находиться в двух состояниях: отмеченном и неотмеченном.
Одиночный флажок может быть привязан к логическому значению true или false:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
checked: true
}
})
</script>
</body>
</html>
По умолчанию для отмеченного состояния используется значение true, а для неотмеченного - false. Но вместо них можно определить свои собственные значения для обоих состояний и между этими значениями переключаться:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="checkbox" v-model="light" v-bind:true-value="on" v-bind:false-value="off" />
<span v-if="light === on">Выключить</span>
<span v-else>Включить</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
on: true,
off: false,
light: true
}
})
</script>
</body>
</html>
Вместо значений true и false флажок привязывается к одному из свойств on или off. С помощью атрибута v-bind:true-value="on" отмеченное состояние будет сопоставляться со свойством on. Соответственно в неотмеченном состоянии флажок приобретает значение off. А само выбранное значение попадает в свойство light.
Привязка к массиву
Также группа флажков может быть привязана к одному массиву. В этом случае при отметке флажка его значение попадает в массив:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="checkbox" value="Tom" v-model="selectedUsers">
<label>Tom</label><br>
<input type="checkbox" value="Bob" v-model="selectedUsers">
<label>Bob</label><br>
<input type="checkbox" value="Sam" v-model="selectedUsers">
<label>Sam</label><br>
<input type="checkbox" value="Alice" v-model="selectedUsers">
<label>Alice</label><br>
<span>Выбрано: {{ selectedUsers }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
selectedUsers: []
}
})
</script>
</body>
</html>
В данном случае 4 флажка привязаны к массиву selectedUsers. Отметив определенный флажок, мы добавим его значение в массив.
Привязка к объекту
В примере выше значение каждого флажка представляло некоторую строку. Но также флажок может быть привязан к целому объекту. Для динамической привязки у элемента HTML применяется атрибут v-bind:value:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<template v-for="user in users">
<input type="checkbox" v-bind:value="user" v-model="selectedUsers">
<label>{{ user.name }}</label><br>
</template>
<ul>
<li v-for="user in selectedUsers">{{ user.name }} - {{ user.age }}</li>
</ul>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
users: [
{ name: 'Tom', age: 22 },
{ name: 'Bob', age: 25 },
{ name: 'Sam', age: 28 },
{ name: 'Alice', age: 26 }
],
selectedUsers: []
}
})
</script>
</body>
</html>
Здесь динамически для каждого объекта в массиве формируется флажок, а при выборе флажка объект попадет в массив selectedUsers.
Переключатели (radiobutton)
Переключатели или радиокнопки позволяют определить группу альтернативных вариантов, из которых одномоментно пользователь может выбрать только один. Переключатели привязываются к одному свойству. При выборе переключателя связанное свойство получает выбранное значение:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="radio" value="Tom" v-model="user">
<label>Tom</label>
<br>
<input type="radio" value="Bob" v-model="user">
<label>Bob</label>
<br>
<input type="radio" value="Sam" v-model="user">
<label>Sam</label>
<br>
<span>Выбрано: {{ user }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
user: ''
}
})
</script>
</body>
</html>
Привязка к объекту
Также каждый из переключателей может быть привязан к сложному объекту. В этом случае используется атрибут v-bind:value. Результатом выбора соответственно также будет сложный объект:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<input type="radio" v-bind:value="{name: 'Tom', age: 22}" v-model="user">
<label>Tom</label>
<br>
<input type="radio" v-bind:value="{name: 'Bob', age: 25}" v-model="user">
<label>Bob</label>
<br>
<input type="radio" v-bind:value="{name: 'Sam', age: 28}" v-model="user">
<label>Sam</label>
<br>
<span>Выбрано: {{ user.name }} - {{ user.age }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
user: {}
}
})
</script>
</body>
</html>
Привязка к массиву объектов
В случае выше было бы более оптимально хранить данные в массиве и динамически создавать по элементам массива группу радиокнопок:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<template v-for="user in users">
<input type="radio" v-bind:value="user" v-model="selectedUser">
<label>{{ user.name }}</label><br>
</template>
<span v-if="selectedUser !== null">Выбрано: {{ selectedUser.name }} - {{ selectedUser.age }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
users: [
{ name: 'Tom', age: 22 },
{ name: 'Bob', age: 25 },
{ name: 'Sam', age: 28 },
{ name: 'Alice', age: 26 }
],
selectedUser: null
}
})
</script>
</body>
</html>
Список select
Элемент select позволяет создать список с возможностью одиночного и множественного выбора.
Список с одиночным выбором
Выпадающий список с одиночным выбором можно привязать к свойству Vue, которое хранит выбранный элемент:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<select v-model="user">
<option>Tom</option>
<option>Bob</option>
<option>Sam</option>
</select>
<span>Выбрано: {{ user }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
user: ''
}
})
</script>
</body>
</html>
Список с множественным выбором
Список select с множественным выбором можно связать с массивом, в который попадут все выбранные значения:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<select v-model="users" multiple>
<option>Tom</option>
<option>Bob</option>
<option>Sam</option>
<option>Alice</option>
</select>
<span>Выбрано: {{ users }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
users: []
}
})
</script>
</body>
</html>
Привязка к массиву объектов
Нередко источником для элементов списка служит массив, элементы которого нередко представляют сложные объекты. Для динамического создания списка из массива применяется директива v-for, а для привязки значения к элементу списка - атрибут v-bind:value:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<select v-model="selectedUser">
<option v-for="user in users" v-bind:value="user.name">{{ user.name }}</option>
</select>
<span>Выбрано: {{ selectedUser }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
users: [
{ name: 'Tom', age: 22 },
{ name: 'Bob', age: 25 },
{ name: 'Sam', age: 28 },
{ name: 'Alice', age: 26 }
],
selectedUser: ''
}
})
</script>
</body>
</html>
В данном случае в списке отображается значение свойства name объекта из массива и это же свойство name будет использоваться в качестве значения при выборе элемента. Однако мы можем выбирать и весь объект в целом:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<select v-model="selectedUser">
<option v-for="user in users" v-bind:value="user">{{ user.name }}</option>
</select>
<span v-if="selectedUser !== null">Выбрано: {{ selectedUser.name }} - {{ selectedUser.age }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
users: [
{ name: 'Tom', age: 22 },
{ name: 'Bob', age: 25 },
{ name: 'Sam', age: 28 },
{ name: 'Alice', age: 26 }
],
selectedUser: null
}
})
</script>
</body>
</html>
В данном случае выбранный объект из массива будет попадать в свойство selection.
Привязка к объектам в списке с множественным выбором
Аналогично можно установить привязку к объектам в списке с множественным выбором. В этом случае выбранные элементы попадут в массив:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<select v-model="selectedUsers" multiple>
<option v-for="user in users" v-bind:value="user">{{ user.name }}</option>
</select>
<h3>Выбранные объекты</h3>
<ul>
<li v-for="user in selectedUsers">{{ user.name }} - {{ user.age }}</li>
</ul>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
users: [
{ name: 'Tom', age: 22 },
{ name: 'Bob', age: 25 },
{ name: 'Sam', age: 28 },
{ name: 'Alice', age: 26 }
],
selectedUsers: null
}
})
</script>
</body>
</html>
Модификаторы
Для управленя вводом с элементов форм можно использовать модификаторы.
.lazy
По умолчанию директива v-model обновляет связанные с полем ввода данные при каждом вызове события input. То есть при вводе каждого символа в текстовое поле будут изменяться связанные данные. Но вместо этого мы также можем вызывать обновление не после события input, а после события change. То есть связанные данные будут обновляться только после того, как текстовое поле потеряет фокус. Для этого применяется модификатор .lazy:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<input type="text" v-model.lazy="name" />
<span>Введено: {{ name }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
name: ''
}
})
</script>
</body>
</html>
.number
Модификатор .number позволяет автоматически конвертировать при вводе вводимое значение в число. Поскольку даже если мы установим у поля input атрибут type="number", то такое поле все равно будет возвращать строку:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<input v-model.number="age" type="number">
<span>Введено: {{ age }}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
age: 0
}
})
</script>
</body>
</html>
.trim
Модификатор .trim автоматически обрезает начальные и концевые пробелы при вводе строки:
<!DOCTYPE html>
<html>
<head>
<title>Vue.js</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
<input v-model.trim="message">
<span>Введено: {{message}}</span>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: ''
}
})
</script>
</body>
</html>
Объединение модификаторов
Также можно объединять модификаторы:
<input v-model.lazy.trim="message"> <input v-model.lazy.number="age" type="number">