Во Vue.js для каждого массива определено ряд методов, с помощью которых можно управлять элементами массива:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
Эти методы являются обертками над одноименными стандартными методами javascript для управления массивами и работают точно также. Единственное отличие их от стандартных методов состоит в том, что эти методы-обертки информируют систему Vue.js о том, что с массивом были произведены некоторые действия, и соответственно для этого массива может быть произведен повторный рендеринг на веб-странице.
Но кроме выше описанных методов, которые изменяют отдельные элементы массив, есть ряд методов в javascript, которые возвращают новый массив, типа
filter()
, concat()
, slice()
. Результат таких функций лучше привязывать к вычисляемому свойству, которое позволит произвести повторный рендеринг
элементов веб-страницы.
Определим код для добавления нового элемента в массив и удаления из массива:
<!DOCTYPE html> <html> <head> <title>Изучаем Vue.js</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <p> <input type="text" v-model="newPhone" /> <button v-on:click="phones.push(newPhone)">Добавить</button> </p> <ul> <li v-for="(phone, index) in phones"> <p>{{ phone }} <button v-on:click="phones.splice(index, 1)">Удалить</button></p> </li> </ul> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { newPhone: '', phones: ['iPhone 7', 'Galaxy S8', 'Nokia N8', 'Xiaomi Mi6'] } }); </script> </body> </html>
При нажатии на кнопку в массив будет добавлять введенное в текстовое поле значение, которое доступно через свойство newPhone. И в итоге произойдет обновление списка на веб-странице, и мы увидим добавленный элемент.
И кроме того, для каждого элемента предусмотрена кнопка, через которую по индексу можно удалить элемент из массива.
При работе с массивами мы можем столкнуться с некоторыми ограничениями. В частности, мы не можем просто по индексу переустановить элемент массива, присвоив ему новое значение:
this.phones[1] = 'Samsung Galaxy S8';
Для установки значения нам надо использовать метод Vue.set():
Vue.set(массив, индекс_элемента, новое_значение);
Например, обновим второй элемент массива:
<div id="app"> <ul> <li v-for="phone in phones"> <p>{{ phone }}</p> </li> </ul> <button v-on:click="updateList">Обновить</button> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { phones: ['iPhone 7', 'Galaxy S8', 'Nokia N8', 'Xiaomi Mi6'] }, methods:{ updateList: function(){ Vue.set(this.phones, 1, 'Samsung Galaxy S8'); } } }); </script>
Ряд методов, такие как slice, concat, filter, не изменяют текущий массив, а возвращают новый. Одно из решений может заключаться в переустановке массива. Например, используем метод slice, который возвращает часть массива:
<div id="app"> <ul> <li v-for="phone in phones"> <p>{{ phone }}</p> </li> </ul> <button v-on:click="updateList">Обновить</button> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { phones: ['iPhone 7', 'Galaxy S8', 'Nokia N8', 'Xiaomi Mi6'] }, methods:{ updateList: function(){ this.phones = this.phones.slice(1,3); } } }); </script>
Для фиксации нового массива присваиваем полученный массив свойству phones.
Однако данный способ не всегда является оптимальным. Особенно если мы хотим сохранить старый массив и изменять лишь его визуальное представление. И более идеальным вариантом, как правило, является разделение данных и представления этих данных. Для представления данных обычно определяется вычисляемое свойство-список, элементы которого выводятся на веб-страницу:
<div id="app"> <input v-model="start" type="number" /> <input v-model="end" type="number" /> <ul> <li v-for="phone in visibleList"> <p>{{ phone }}</p> </li> </ul> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { start:0, end:3, phones: ['iPhone 7', 'Galaxy S8', 'Nokia N8', 'Xiaomi Mi6'] }, computed:{ visibleList: function(){ return this.phones.slice(this.start,this.end); } } }); </script>