Обратный звонок
17-04-2018
Дмитрий Лаврик

Vue.JS - директива

 

Что такое директива

Директива записывается как атрибут к любому узлу, обычно начинается с префикса v.

V-show - одна из самых простых директив. В ней должна быть либо правда, либо ложь. Как это осуществить: в значение атрибута записываем либо просто булевское значение, либо операцию или метод, которые дадут булевское значение.

Если v-show присвоить false, то заголовок пропадёт. Если я поставлю v-show = “true”, то заголовок снова вернется. Это одна из самых лаконичных директив и здесь мы видим две части любой директивы.

Итак, “v-show” - это название директивы, а “true” - значение. Напрашивается полная аналогия с html атрибутами, но на самом деле это не так. На самом деле помимо названия и значения у директив могут появляться аргументы и модификаторы.
Давайте оживим директиву. Перенесем значение true в объекта data и разместим его по ключу show h2, и запишем в него значение true. И теперь мы имеем право записать в директиву v-show переменную showh2. Подробнее пройдем на следующем уроке, сейчас рассмотрим кратко.
Внимание! Вы уже успели убедиться, что для эффективного использования Vue нужно понимать некоторые основы чистого JS.  Заметьте, что true написано в двойных кавычках. В JS это было бы не true, а строка из 4 букв. Кавычки просто обозначают начало и конец значения для нашей директивы. Все, что мы напишем между этими кавычками, написано на языке JavaScript. Т.е., вы можете в кавычках написать одну (только одну!!!) любую операцию на JS. Если нужно просто поставить значение - как в нашем случае - его можно просто вписать.

Смысл в том, что showH2 выполнится в контексте экземпляра Vue. Таким образом, когда мы прописываем в v-show какое-либо название поля, то это поле ищется автоматическим в экземпляре Vue.

Мы пока не прошли эту тему подробно, поэтому считайте, что он ищется в экземпляре Vue в поле data. На самом деле это не так, на самом деле здесь может быть поставлено любое название из объектов data, computed, methods. Но об этом позже.

Переходим ко Vue. Если сейчас обновить страничку, Hello world покажется на экране. Если поставить false - Hello world пропадет.

Перейдем к более сложной директиве, которую вы видели на предыдущем уроке - v-on. На её примере можно показать намного больше частей, из которых состоит директива. Мы пишем v-on, ставим кавычки и напишем что-нибудь. Все хорошо, только не хватает события. У любой директивы может быть один параметр, который вписывается после двоеточия. И это главный параметр для директивы. В нашем случае название этого параметра совпадает с названием события, на которые мы хотим подписаться. Например, если мы подпишемся на click, получится:

v-on:click= “1+1”
После этого Vue уже будет обрабатывать данное событие клика по кнопке. Только операцию “1+1” мы визуально на экране не заметим.

Общий вид директивы:

v-название:аргумент=”значение”

Возможно, вы сейчас по привычке захотели вывести 1+1 в консоль, но этот фрагмент кода выполняется в контексте экземпляра Vue. Это значит, что переменную консоль тут получить не так просто. Давайте попробуем. Написал console.log(1+1), открыл отладчик. И увидите ошибку: нет метода “console” в экземпляре. Никогда нельзя забывать про контекст, в котором выполняется операция. Но контекст есть и это хорошо, ведь это позволяет нам точно также как и в директиве v-show дотянуться до поля show H2 и допустим, сделать что-нибудь типа такого

v-on:click="showH2 = !showH2"”
Очень короткий фрагмент кода, который просто-напросто записывают в данную переменную обратное значение.

Поначалу все кто видят подобные Фреймворки и Vue путаются, потому что не понимают, что за локальная переменная, как в нее можно записывать значение. Не относитесь к этому как к локальной переменной. Дело в том, что ядро Vue будет выполнять этот код после того как наступит событие click и оно знает то, что вы хотите не просто написать локальную переменную show, а, вы хотите дотянуться именно до поля объекта, Vue сама поможет вам это сделать.

И вот после этого мы получаем интересный пример: при клике на кнопку “Toggle header” Hello world либо появляется, либо исчезает.

Посмотрим на код:

<div class="container">
    <div class="sample">
		<button class="btn btn-primary"
				v-on:click="showH2 = !showH2"
				>
			Toggle header
		</button>
		<hr>
		<h2 v-show="showH2">Hello, World!</h2>
	</div>
</div>
let sample = new Vue({
    el: '.sample',
    data: {
        showH2: true,
    }
});

Название директивы (v-on, v-show), то, что после знака “=”, мы договорились называть значением директивы. v-show часть на это заканчивается, а у v-on существует еще и аргумент, который сейчас равен click, это означает, что мы подписались на событие click.

На этом в данном уроке у нас заканчиваются составные части директив, но на будущее просто знайте, здесь еще так называемые модификаторы. Например, я могу для события поставить модификатор once, и это значит, что событие осуществится единожды. Точно также есть интересные модификаторы типа prevent и т.д., которые как-то меняют поведение в плане обработки этого события. Но нам пока в примере достаточно вот такой реализации.

В работе директив есть один важный момент - все директивы парсятся по одному, а все директивы v-on парсятся по-другому. Кусок кода, который мы прописываем в любой директиве выполняется сразу, т.е., если я v-show напишу тернарный оператор, он выполнится в момент вывода тега h2 на экран или даже в момент решения, выводить его на экран или нет. А код, который я пишу в директиве v-on выполняется именно в момент наступления данного события. Это единственная такая директива, остальные директивы выполняют тот кусочек кода, который прописан в двойных кавычках моментально.

Чтобы как-то разнообразить директивы, давайте посмотрим еще одну. Есть такая директива v-bind, вы ее видели на прошлом занятии. Это директива, которая позволяет записать динамическое значение в атрибут HTML. Если я напишу атрибут title и поставлю значение 1+1, то это будет текстовое значение. Все логично, у тега button есть атрибут title, и что туда написали - то там и будет. Чтобы добавить обработку значения атрибута мы используем директиву v-bind и аргумент - название атрибута, который мы хотим с вами создать. В этом случае в атрибут будет записано значение выражения. Обновите хром, наведите на кнопку “Toggle button” - и вы увидите “2” в title.  

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

<div class="sample">
	<button class="btn btn-primary" 
			v-on:click="showH2 = !showH2"
			v-bind:title="showH2 ? 'Hide' : 'Show'"
			>
		Toggle header
	</button>
	<hr>
	<h2 v-show="showH2">Hello, World!</h2>
</div>
let sample = new Vue({
    el: '.sample',
    data: {
        showH2: true,
    }
});

И теперь наведите на кнопку - сначала будет Hide, потом - Show. Пример очень простой, но он показывает, какими возможностями мы обладаем.

Для директив v-on и v-bind существуют также сокращенная форма записи. Не пугайтесь, если вы увидите ее где-то в сети, но пока что нам лучше соблюсти единую форму записи, так как она проще для новичков. В принципе на этом можно было бы завершить первый разговор про директивы, потому что главное - понимать, как они работают, остальное все очень легко гуглится, да и у Vue замечательная документация, в том числе и на русском языке.

На следующем занятии мы увидим то, что в директивы можно подставлять элементы экземпляра Vue, например вычисляемые свойства, либо методы.

Сейчас давайте сделаем немного более сложный пример. Наверное, у тех, кто первый раз знакомится с Vue возникает ощущение, что ничего крутого нет, и на jQuery можно сделать то же. Мы сейчас познакомимся с директивой v-for. Ведь главные проблемы jQuery и похожих на нее библиотек начинаются, когда контент генерируется динамически и взаимодействия пользователя с ним надо обрабатывать так же, как с тем контентом, который уже был.

Реализуем небольшой пример, использующий цикл, который будет генерить части разметки. Добавим в уже готовый пример несколько элементов.

<div class="container">
    <div class="sample">
        <button class="btn btn-primary" 
                v-on:click="showH2 = !showH2"
                v-bind:title="showH2 ? 'Hide' : 'Show'"
                >
            Toggle header
        </button>
        <hr>
        <h2 v-show="showH2">Hello, World!</h2>
        <hr>
		<button class="btn btn-success" 
				v-on:click="numbers.push(Math.random())"
				>
			Add number
		</button>
		<hr>
	</div>
</div>

Сделаем такой пример, когда у нас теги li генерируется динамически - они завязаны на какой-нибудь массив данных. Создадим пустой массив, который будет называться numbers. Чтобы сделать динамический вывод элементов, пропишем для тега li директиву под название v-for. Директива как правило не вызывает никаких трудностей потому что очень похоже на стандартные циклы которые есть во всех языках программирования. Важно понимать только одну вещь: мы опять работаем в контексте экземпляра Vue, поэтому можем спокойно дотянуться как до поля showH2, так и до поля numbers. И написать что-нибудь такое:

<ul class="list-group">
	<li class="list-group-item"
		v-for="number in numbers"
	>
	</li>
</ul>
let sample = new Vue({
    el: '.sample',
    data: {
        showH2: true,
        numbers: []
    }
});

и вывести значение numbers

<ul class="list-group">
	<li class="list-group-item"
		v-for="number in numbers"
	>
		{{ number }}
	</li>
</ul>
let sample = new Vue({
    el: '.sample',
    data: {
        showH2: true,
        numbers: []
    }
});

Если обновлю страничку, мы увидим то, что ничего интересного не произошло, потому что у нас нет этих чисел. Но если создать массив с числами 1, 2, 3, они сразу появятся в списке. Что нам это дает – есть всего лишь один тег, один элемент в html и нужное количество элементов получается за счет того, что у нас отрабатывает цикл v-for. Данный пример тоже не слишком динамичный. Уберем numbers и сделаем так, чтобы в список добавлялись случайные числа.

<button class="btn btn-success" 
		v-on:click="numbers.push(Math.random())"
		>
	Add number
</button>
<hr>
<ul class="list-group">
	<li class="list-group-item"
		v-for="number in numbers"
		>
		{{ number }}
	</li>
</ul>
let sample = new Vue({
    el: '.sample',
    data: {
        showH2: true,
        numbers: []
    }
});

Проверим работоспособность такого кусочка кода. Нажимаем на кнопку, и числа добавляются в разметку. Заметьте, в разметку, не в массив, потому что эти элементы синхронизированы друг с другом. Вот она - главная фишка, главные плюсы реактивности данных. Мы работаем на уровне данных, а шаблон автоматом эти данные подхватывает.

На самом деле в директивах еще есть много нюансов. Чтобы понять как директивы работают, лучше конечно с нуля написать целую директиву. Но нам с вами в рамках данной серии уроков важнее двигаться в сторону вычисляемых свойств и методов, потому что здесь выполняется ровно одна какая-то операция и сильно здесь не развернешься. Там нужно какое-то место в экземпляре Vue, где мы сможем реализовать более сложную логику. И на следующем уроке главной темой будут как раз таки вычисляемые свойства и методы. Они позволят, опираясь на директивы, сделать гораздо более красочные и интересные примеры. Успехов, до следующего урока.

Самые читаемые: