Фильтрация и сортировка массива

Последнее обновление: 02.11.2020

Фильтрация массива

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

<!DOCTYPE html>
<html>
<head>
<title>Изучаем Vue 3</title>
<meta charset="utf-8" />
</head>
<body>
<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"></script>
<script>
Vue.createApp({
  data() {
    return { 
		company: '',
		phones: [
                {title:'iPhone 12', company:'Apple'}, 
                {title:'iPhone 10', company:'Apple'},
                {title:'Galaxy S20', company:'Samsung'},
                {title:'Galaxy A10', company:'Samsung'},
                {title:'Xiaomi Redmi 8', company:'Xiaomi'}]
	}
  },
  computed:{
	filteredList(){
		let comp = this.company;
		return this.phones.filter(function (elem) {
			if(comp==='') return true;
			else return elem.company.indexOf(comp) > -1;
		})
	}
  }
}).mount('#app');
</script>
</body>
</html>

В данном случае фильтрация работает по принципу живого поиска. При вводе значения в текстовое поле происходит повторное вычисление свойства filteredList. Это свойство представляет результат функции, которая возвращает те объекты, у которых поле company соответствует введенному значению. То есть идет фильтрация телефонов по компании производителя. Если же значение не введено, то возвращаем все элементы из массива phones.

В итоге динамически мы можем фильтровать элементы списка.

Фильтрация и живой поиск в Vue 3

Сортировка списка

Для сортировки списка применяется похожая техника, что и для фильтрации:

<!DOCTYPE html>
<html>
<head>
<title>Изучаем Vue 3</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"></script>
<script>
Vue.createApp({
  data() {
    return { 
		sortParam: '',
		phones: [
                {title:'iPhone 12', company:'Apple', price: 65000},
                {title:'Galaxy S20', company:'Samsung', price: 63000},
                {title:'Galaxy A10', company:'Samsung', price: 38000},
                {title:'iPhone 10', company:'Apple', price: 45000},
                {title:'Xiaomi Redmi 8', company:'Xiaomi', price: 42000}]
	}
  },
  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;
		}
	}
  }
}).mount('#app');

const sortByTitle = (d1, d2) => (d1.title.toLowerCase() > d2.title.toLowerCase()) ? 1 : -1;
const sortByCompany = (d1, d2) => (d1.company.toLowerCase() > d2.company.toLowerCase()) ? 1 : -1;
const sortByPrice = (d1, d2) =>(d1.price > d2.price) ? 1 : -1;
</script>
</body>
</html>

Как и в случае с фильтрацией, привязка устанавливается к вычисляемому свойству. При нажатии на заголовок столбца в таблице происходит переустановка значения свойства sortParam, которое представляет критерий фильтрации. При его изменении повторно вычисляется свойство sortedList, которое сортирует массив phones в соответствии со значением в sortParam. Для фильтрации по трем критериям определены три вспомогательные функции sortByCompany, sortByPrice и sortByTitle.

Сортировка массивов в Vue 3
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850