Вернуть массив к исходному виду VUE JS

161
31 декабря 2019, 13:50

Есть переменная, содержащая в себе массив объектов. При клике на checkbox, объекты сортируются в зависимости от первой буквы в значении одного из ключей. То есть, сортируются по алфавиту.

НО. Как сделать так, чтобы при повторном клике (когда чекбокс принимает false), массив объектов приходил к исходному виду?

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>

Answer 1

Не нужно изменять исходный массив. Для этого лучше использовать computed свойство. И не забудьте клонировать исходный массив прежде чем сортировать, например, с помощью [].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: Всегда инициализируйте объект data c помощью функции:

data() {
    return {
        ...
    }
}

иначе, если компонент будет использоваться несколько раз на странице, они будут ссылаться на один объект и доставят много неприятностей. В варианте с функцией - при инициализации компонента будет создан обособленный объект

Answer 2

Вам необходимо сохранять изначальный порядок элементов. Для этого можно добавить свойство к объектам массива towns, к примеру orderIndex. При клике Вы можете передавать в метод событие и определять отмечен ли чекбокс или нет. Если "да", то можно брать значение value из чекбокса и использовать его для сортировки, если "нет", то использовать значение по-умолчанию. Выглядеть это может примерно так:

<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;
      });
    }
  }
});

По этому принципу можно построить сортировку по другим свойствам, но это будет удобней сделать с радио-кнопками, т.к. отмечен будет лишь один элемент, в отличии от чекбоксов, где пользователь может создать любую комбинацию из отмеченных и не отмеченных элементов.

READ ALSO
Парсинг даты из строки

Парсинг даты из строки

Как из такой строки можно извлечь дату?

188
Почему не удаляется класс по клику?

Почему не удаляется класс по клику?

По клику на мою цель в консоли выводится сообщение, значит делегирование правильно работает, но тогда почему не удаляется класс?

171
mysql 8.0.15 (only innodb) Утечка ОЗУ?

mysql 8.0.15 (only innodb) Утечка ОЗУ?

После перехода с mysql 57 на mysql 8

173
Выборка из MySql в диапазоне дат

Выборка из MySql в диапазоне дат

есть таблица в формате

156