I do a filter by clicking on the button should find a item category that matches the category of the button, leave these elements and hide the rest. Faced the problem that in the setSocialSortBy method I made an array that contains Index elements that have this category matchArr = [1,3,5 ...], but I don’t get now to filter this.items by this new array matchArr. How can I do that?

json ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ с api: {name: 'title 1', category: 'cat 1'}, {name: 'title 2', category: 'cat 2'}, {name: 'title 3', category: 'cat 1'}, {name: 'title 4', category: 'cat 2'} ... <button v-for="cat in cats" @click="setCatSortBy(cat)">{{cat}}</button> <div v-if="items.length > 0"> <div v-for="item in items">{{item.name}}</div> </div> <script> export default { data() { items: [], cats: [] }, created () { this.fetchItems(); }, methods: { fetchItems() { this.loading = true; fetch("/api/items") .then(res => res.json()) .then(res => { this.items = res; let catArr = []; this.items.forEach((item) => { catArr.push(item.category); }); catArr.filter((value, index, arr) => { if (arr.indexOf(value) === index) { this.cats.push(value.toLowerCase()); } }); }); }, setCatSortBy(name) { let matchArr = []; this.items.filter((value, index) => { if (value.category.toLowerCase() === name.toLowerCase()) { matchArr.push(index); } }); } } } </script> 
  • Add json at least one item from /api/items - Rustam Gimranov

1 answer 1

I think that it is worth re-accessing the filtering methods described in this answer .

The filter() method does not modify the array to which it is applied, it returns a new array. Those. need to do this:

 this.items = this.items.filter(...) 

But if you do this, the filtered records will be deleted from the original array. And with further filtering, this array will β€œgrow thin” until it becomes empty.

That is why an intermediate filteredItems array is introduced for filtering so that the original one remains untouched.

Instead of a computed property, you can use the same function as a method. From the point of view of the final result, both approaches do the same. But there is an important difference: the calculated properties are cached based on their reactive dependencies. The calculated property is recalculated only when one of its reactive dependencies changes. - source

 new Vue({ el: '#app', data: { // МодСль с записями. items: [], // МодСль с катСгориями. categories: [], ready: false, search: { category: '', } }, computed: { // ВычисляСмый список зависит ΠΎΡ‚ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΉ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ. // ΠŸΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ, список Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Π½. // ΠœΠ΅Ρ‚ΠΎΠ΄ filter() создаёт Π½ΠΎΠ²Ρ‹ΠΉ массив со всСми элСмСнтами, // ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠΈΠΌΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ. // https://ru.vuejs.org/v2/guide/list.html#Π—Π°ΠΌΠ΅Π½Ρ‹-Π²-массивС // https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅_Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ filteredItems() { let category = this.search.category return category ? this.items.filter(item => item.category === category) : this.items } }, /** * Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ…ΡƒΠΊ `mounted` для получСния записСй. */ async mounted() { const response = await this.fetchArticles() this.items = response.data this.categories = this.makeCategoryList(this.items) }, methods: { // БоставляСм список всСх ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ. // Нам Π½ΡƒΠΆΠ½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ значСния, поэтому // Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ созданиСм массива Ρ‡/Π· Set. // Π—Π° ΠΎΠ΄Π½ΠΎ ΠΈ отсортируСм. makeCategoryList(items) { let cats = new Set() items.map(item => cats.add(item.category)) return [...cats].sort((a, b) => a.localeCompare(b)) }, fetchArticles() { this.ready = false // Π˜ΠΌΠΏΡ€ΠΎΠ²ΠΈΠ·Π°Ρ†ΠΈΡ получСния Π΄Π°Π½Π½Ρ‹Ρ… Ρ‡/Π· ajax. return new Promise(resolve => { setTimeout(() => { this.ready = true resolve({ // Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ°: id asc. data: [{ id: 4, name: 'Voluptatem enim optio', category: 'cat 3' }, { id: 8, name: 'Eum praesentium autem', category: 'cat 2' }, { id: 12, name: 'Voluptatem nihil voluptate', category: 'cat 1' }, { id: 18, name: 'Debitis illum ex eum', category: 'cat 3' }], meta: {} }) }, 2000) }) } }, }) 
 .form__group { margin-bottom: 1rem; } .form__control { display: inline-block; padding: .375rem .75rem; line-height: 1; color: #495057; background-color: #fff; background-clip: padding-box; border: 1px solid #ced4da; transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; } .form__control:focus { color: #495057; background-color: #fff; border-color: #80bdff; outline: 0; box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, .25); } .alert { padding: 0.75rem 1.25rem; margin-bottom: 1rem; border: 1px solid transparent; } .alert-info { color: #2f6473; background-color: #def2f8; border-color: #d1edf6; } 
 <div id="app"> <div class="filter__box"> <div class="form__group"> <label for="">Π€ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ</label> <select v-model="search.category" class="form__control"> <option value="">- ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΡ -</option> <option v-for="(category, index) in categories" :value="category">{{ category }}</option> </select> <!-- Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ вычисляСмоС свойство, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Π² ΠΊΠ½ΠΎΠΏΠΊΠ΅ ΠΎΡ‚ΠΏΠ°Π΄Π°Π΅Ρ‚. --> </div> </div> <div v-if="!ready" class="alert alert-info">Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° записСй, ΠΎΠΆΠΈΠ΄Π°ΠΉΡ‚Π΅ 2 сСк ...</div> <div v-if="ready && Boolean(filteredItems.length)" class="items"> <template v-for="(item, index) in filteredItems" :key="item.id"> <article class="article"> <h3 class="article__title">#{{ item.id }} {{ item.name }}</h3> </article> </template> </div> <div v-if="ready && !Boolean(filteredItems.length)" class="alert alert-info">НСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ для отобраТСния.</div> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js"></script> 

  • Rustam Gimranov, thanks after your example, it became clear in general how to work with search and sorting in Vue - Dima Vleskov
  • You can suggest an abbreviated condition in filteredItems () - return !! category - how to record, if not reducing, I do not quite understand what kind of comparison it is. if (category! == "")? - Dima Vleskov
  • This is a double denial. Not a good example. It is equivalent to a Boolean(category) record. Means that the category should not be an empty string, specifically in this case. In select, the first option has an empty string. Now I'll fix it. You can read more here 1 2 - Rustam Gimranov
  • thanks now I understand what is happening there - Dima Vleskov