Продвинутая работа с методами и событиями в фреймворке Vue


Сейчас мы будем изучать продвинутую работу с методами и событиями в фреймворке Vue. Мы научимся использовать метод в методе, освоим передачу параметров в метод и с ее помощью реализуем удаление пунктов списка по клику на любой из них. Давайте приступим.

Использование метода в методе
Итак, вы уже знаете, что внутри настройки methods можно писать необходимые нам методы. Не обязательно каждый метод должен быть привязан к какому-либо событию - часть методов может быть вспомогательными.

Вспомогательные методы будут использоваться внутри других методов. Причем, так же, как и при обращении со свойствами, при использовании одного метода внутри другого мы не можем просто написать имя используемого метода, а должны обратиться к нему через this.

Пусть, к примеру, в data у нас хранится имя и возраст юзера:

let app = new Vue({
el: '#app',
data: {
name: 'Коля',
age: 20,
},
});
Выведем эти данные на экран:

<div id="app">
<p>Имя: {{ name }}, возраст: {{ age }} </p>
</div>
Сделаем теперь кнопочку, по нажатию на которую имя и возраст пользователя поменяются. Для этого привяжем к кнопочке метод changeUser:

<button v-on:click="changeUser">Изменить юзера</button>
Добавим эту кнопочку после абзаца:

<div id="app">
<p>Имя: {{ name }}, возраст: {{ age }} </p>
<button v-on:click="changeUser">Изменить юзера</button>
</div>
Итак, по нажатию на эту кнопочку сработает метод changeUser. Этот метод должен одновременно сменить имя и возраст юзера.

Пусть у нас уже есть два метода - метод changeName, который изменяет имя и метод changeAge, который изменяет возраст:

methods: {
// Изменяет имя:
changeName: function() {
this.name = 'Вася';
},

// Изменяет возраст:
changeAge: function() {
this.age = 30;
},
}
Используем внутри привязанного к кнопке метода changeUser два наших вспомогательных метода:

changeUser: function() {
this.changeName(); // обращаемся к другому методу через this
this.changeAge(); // и к этому тоже
}
Соберем все вместе и запустим:

<div id="app">
<p>Имя: {{ name }}, возраст: {{ age }} </p>
<button v-on:click="changeUser">Изменить юзера</button>
</div>
let app = new Vue({
el: '#app',
data: {
name: 'Коля',
age: 20,
},
methods: {
// Вспомогательный метод:
changeName: function() {
this.name = 'Вася';
},

// Вспомогательный метод:
changeAge: function() {
this.age = 30;
},

// Этот метод привязан к кнопке:
changeUser: function() {
this.changeName(); // изменим имя
this.changeAge(); // изменим возраст
},
}
});
Если запустить этот код и нажать на кнопку - имя и возраст пользователя при этом поменяются.

Таким образом внутри одного метода можно использовать другой. При этом к нему нужно обращаться через this.

Передача параметров в метод
Иногда бывает такая ситуация: у нас есть один метод, однако, мы бы хотели вызвать его с разными параметрами.

Например: у нас есть метод showMessage, который выводит на экран некоторое сообщение. Пусть мы хотим, чтобы это сообщение передавалось параметром этого метода, причем при привязке события в HTML коде, вот так:

<div id="app">
<button v-on:click="showMessage('привет')">Поприветствовать</button>
<button v-on:click="showMessage('пока')">Попрощаться</button>
</div>
То есть сейчас по нажатию на первую кнопку наш showMessage должен вывести 'привет', а по нажатию на вторую - 'пока'. Давайте реализуем это.

На самом деле методы можно привязывать к событиям как без круглых скобок, вот так: v-on:click="showMessage", так и с ними - вот так: v-on:click="showMessage()". Во втором случае метод также выполнится по наступлению события, в нашем случае клика.

Второй способ с круглыми скобками нужен нам для передачи параметров в метод. То есть вот так - v-on:click="showMessage('привет')" - можно делать. При этом переданный параметр 'привет' попадет в первый параметр метода showMessage.

Давайте напишем реализацию метода showMessage:

let app = new Vue({
el: '#app',
methods: {
// Переданный параметр попадает в переменную message:
showMessage: function(message) {
alert(message); // выведем содержимое параметра
},
}
});
Вот и все. Осталось собрать все вместе и запустить:

<div id="app">
<button v-on:click="showMessage('привет')">Поприветствовать</button>
<button v-on:click="showMessage('пока')">Попрощаться</button>
</div>
let app = new Vue({
el: '#app',
methods: {
showMessage: function(message) {
alert(message);
},
}
});
Запустите этот код самостоятельно, понажимайте на кнопки и вы увидите, что эти кнопки работают по-разному, хотя к ним привязан один и тот же метод.

Удаление пунктов списка
Пусть у нас есть массив, назовем его items, который мы выводим в виде списка ul. Давайте сделаем так, чтобы по нажатию на любую li она удалялась.

Для этого нам необходимо сделать следующее: при нажатии на li вызвать какой-то метод (назовем его removeItem), который удалит соответствующий элемент из массива. При этом сработает реактивность и вместе с удалением элемента из массива удалится и сам тег li.

Удаление можно организовать так: с помощью метода splice из массива items вырезать элемент, который содержит номер li, на которую мы кликнули.

Для этого нам нужно знать порядковый номер этой li в массиве items. Если бы мы знали его, тогда метод removeItem выглядел бы так:

removeItem: function() {
// Здесь index - порядковый номер li, который мы откуда-то знаем:
this.items.splice(index, 1);
}
Не понятно как тут работает splice? Смотрите его описание и примеры работы в справочнике: splice.

Откуда же нам в методе removeItem взять этот порядковый номер? Передадим его параметром в наш метод, как мы разбирали это выше:

removeItem: function(index) {
this.items.splice(index, 1);
}
Пол дела сделано. Осталось теперь передать этот номер в момент привязки метода removeItem к событию. Давайте сделаем это.

Сейчас я подробно распишу, как мы придем к рабочему коду, так как если его сразу привести - будет не очень понятно. Начну издалека.

Итак, из массива items мы будем формировать список ul:

<div id="app">
<ul>
<li v-for="item in items">
{{ item }}
</li>
</ul>
</div>
В переменную item будет попадать текст элемента массива, но нас, однако, интересует его порядковый номер. Доработаем наш цикл так, чтобы в переменной index лежал порядковый номер элемента:

<div id="app">
<ul>
<li v-for="(item, index) in items">
{{ item }}
</li>
</ul>
</div>
Итак, после доработки в переменной item будет текст элемента массива, а в переменной index - его порядковый номер.

Повесим теперь на клик по li метод removeItem:

<div id="app">
<ul>
<li v-for="(item, index) in items" v-on:click="removeItem">
{{ item }}
</li>
</ul>
</div>
Пока наш код нерабочий, так как removeItem ожидает, что мы передадим ему параметром порядковый номер элемента в массиве. Так давайте сделаем это, ведь номер хранится в переменной index, а параметры передавать мы уже умеем:

<div id="app">
<ul>
<li v-for="(item, index) in items" v-on:click="removeItem(index)">
{{ item }}
</li>
</ul>
</div>
Все, задача решена. Осталось собрать все вместе и запустить. После этого вы можете кликать на любую li и она при этом будет удаляться.

Итак, вот полный код:

let app = new Vue({
el: '#app',
data: {
items: ['a', 'b', 'c', 'd', 'e'],
},
methods: {
removeItem: function(index) {
this.items.splice(index, 1);
}
}
});
<div id="app">
<ul>
<li v-for="(item, index) in items" v-on:click="removeItem(index)">
{{ item }}
</li>
</ul>
</div>
Запустите этот код и понажимайте на li-шки - они будут удаляться по нажатию.