There is a variable containing an array of objects. When you click on the checkbox , the objects are sorted according to the first letter in the meaning of one of the keys. That is, sorted alphabetically.

BUT. How to make it so that when you click again (when the checkbox accepts false ), the array of objects comes to its original form?

 new Vue({ el: '.townsProject', data: { towns: [{ town: Moscow, yearvisited: 2015 }, { town: Saint - Petersburg, yearvisited: 2019 }, { town: Novorossiisk, yearvisited: 2016 } ] }, methods: sort: function() { this.towns.sort(function(a, b) { if (a.town > b.town) { return 1; } if (a.town < b.town) { return -1; } return 0; }) } 
 <div class="townsProject"> <input class="container__movieList__seen" type='checkbox' id='sort2' v-on:click="sort()"> <label for='sort2'>Отсортировать по алфавиту</label> </div> 

  • Is the array filtered or sorted? In the text it is filtered, in the code it is sorted. Where is the truth? - Stepan Kasyanenko am
  • one
    Add a property to maintain order in towns (for example, orderIdx), fill it in when initialized with the ordinal number of the element in the array, and use it as the default sorting. - XelaNimed am
  • @stepanKasyanenko sorted, I apologize) corrected - nbelle

2 answers 2

No need to change the source array. For this it is better to use the computed property. And don't forget to clone the source array before sorting, for example, using [].concat()

 new Vue({ el: '.townsProject', data() { return { sort: false, towns: [ { town: "Moscow", yearvisited: 2015 }, { town: "Saint - Petersburg", yearvisited: 2019 }, { town: "Novorossiisk", yearvisited: 2016 } ] } }, computed: { sorted_list() { if (this.sort) { return [].concat(this.towns).sort(function(a, b) { if (a.town > b.town) { return 1; } if (a.town < b.town) { return -1; } return 0; }) } return this.towns } } }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div class="townsProject"> <input class="container__movieList__seen" type='checkbox' id='sort2' v-model="sort"> <label for='sort2'>Отсортировать по алфавиту</label> <ul> <li v-for="town in sorted_list" :key="town.town">{{ town.town }}</li> </ul> </div> 


PS: Always initialize the data object using the function:

 data() { return { ... } } 

otherwise, if the component will be used several times on the page, they will refer to one object and cause a lot of trouble. In the variant with the function - when the component is initialized, a separate object will be created

  • Do not tell me why you can not change the original array? - XelaNimed
  • The reason is in question. To keep the original data) - Nikita Umnov

You need to keep the original order of the elements. To do this, you can add a property to the objects of the towns array, for example orderIndex . When you click, you can pass an event to the method and determine whether the checkbox is checked or not. If "yes", then you can take the value value from the checkbox and use it to sort, if "no", then use the default value. It might look something like this:

 <input type='checkbox' value="town" v-on:click="sort($event)" /> 
 new Vue({ el: '.townsProject', data: { towns: [ { town: "Moscow", orderIndex: 0}, { town: "Saint-Petersburg", orderIndex: 1 }, { town: "Novorossiisk", orderIndex: 2} ] }, methods: { sort: function (ev) { var isChecked = ev.target.checked; var sortProp = isChecked ? ev.target.value : 'orderIndex'; this.towns.sort(function (a, b) { if (a[sortProp] > b[sortProp]) { return 1; } if (a[sortProp] < b[sortProp]) { return -1; } return 0; }); } } }); 

By this principle, it is possible to build a sorting according to other properties, but it will be more convenient to do this with radio buttons, since Only one item will be marked, unlike checkboxes, where the user can create any combination of marked and unchecked items.

  • If only they would indicate for what a minus ... What is the mistake? The proposed option does not solve the problem? Not Feng Shui? Is the moon in the wrong phase? - XelaNimed