Стандартной ситуацией при работе с коллекциями объектов является фильтрация. Как правило, при фильтрации есть некоторый начальный список, а пользователю же возвращается некоторый временный результат. Начальный же список при этом не изменяется. И для этого во Vue.js лучше определить привязку к вычисляемому свойству:
<div id="app"> <p><input type="text" v-model="company" /></p> <ul> <li v-for="phone in filteredList"> <p>{{ phone.title }} - {{ phone.company }}</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: { company: '', phones: [ {title:'iPhone 7', company:'Apple'}, {title:'iPhone 6S', company:'Apple'}, {title:'Galaxy S8', company:'Samsung'}, {title:'Galaxy S7 Edge', company:'Samsung'}, {title:'Nokia N8', company:'HMD Global'}] }, computed:{ filteredList: function(){ var comp = this.company; return this.phones.filter(function (elem) { if(comp==='') return true; else return elem.company.indexOf(comp) > -1; }) } } }); </script>
В данном случае фильтрация работает по принципу живого поиска. При вводе значения в текстовое поле происходит повторное вычисление свойства filteredList. Это свойство представляет результат функции, которая возвращает те объекты, у которых поле company соответствует введенному значению. То есть идет фильтрация телефонов по компании производителя. Если же значение не введено, то возвращаем все элементы из массива phones.
В итоге динамически мы можем фильтровать элементы списка.
Для сортировки списка применяется похожая техника, что и для фильтрации:
<!DOCTYPE html> <html> <head> <title>Компоненты Vue.js</title> <meta charset="utf-8" /> <style> a:hover{cursor:pointer;} </style> </head> <body> <div id="app"> <table> <tr> <td><a @click="sortParam='title'">Модель</a></td> <td><a @click="sortParam='company'">Компания</a></td> <td><a @click="sortParam='price'">Цена</a></td></tr> <tr v-for="phone in sortedList"> <td>{{phone.title}}</td><td>{{phone.company}}</td><td>{{phone.price}}</td> </tr> </table> </div> <script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { sortParam: '', phones: [ {title:'Galaxy S8', company:'Samsung', price: 45000}, {title:'iPhone 7', company:'Apple', price: 49000}, {title:'Nokia N8', company:'HMD Global', price: 25000}, {title:'Galaxy Note 8', company:'Samsung', price: 50000}, {title:'iPhone 8', company:'Apple', price: 60000}] }, computed:{ sortedList () { switch(this.sortParam){ case 'title': return this.phones.sort(sortByTitle); case 'company': return this.phones.sort(sortByCompany); case 'price': return this.phones.sort(sortByPrice); default: return this.phones; } } } }); var sortByTitle = function (d1, d2) {return (d1.title.toLowerCase() > d2.title.toLowerCase()) ? 1 : -1;}; var sortByCompany = function (d1, d2) { return (d1.company.toLowerCase() > d2.company.toLowerCase()) ? 1 : -1; }; var sortByPrice = function (d1, d2) { return (d1.price > d2.price) ? 1 : -1; }; </script> </body> </html>
Как и в случае с фильтрацией, привязка устанавливается к вычисляемому свойству. При нажатии на заголовок столбца в таблице происходит переустановка значения свойства sortParam, которое представляет критерий фильтрации. При его изменении повторно вычисляется свойство sortedList, которое сортирует массив phones в соответствии со значением в sortParam. Для фильтрации по трем критериям определены три вспомогательные функции sortByCompany, sortByPrice и sortByTitle.