Vue 2 sortowanie tabelki

W niniejszym artykule pokażę jeden ze sposobów na implementację sortowania tabelki w Vue. Zaczniemy od aplikacji Vue, która ładuje dane za pośrednictwem ajax i renderuje tabelę. Ta początkowa wersja nie ma sortowania, po prostu ładuje dane i wyświetla je w widoku. Oto układ:

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>Job</th>
        <th>Gender</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="user in users">
        <td>{{user.name}}</td>
        <td>{{user.age}}</td>
        <td>{{user.job}}</td>
        <td>{{user.gender}}</td>
      </tr>
    </tbody>
  </table>
</div>
Mamy tabelę z czterema kolumnami: imię, wiek, zawód i płeć. A potem po prostu wyświetlam userów w pętli. Kod JavaScript jest taki jak poniżej:
const app = new Vue({
  el: '#app',
  data: {
    users: []
  },
  created: function() {
    fetch('https://api.myjson.com')
    .then(res => res.json())
    .then(res => {
      this.users = res;
    })
  }
});
Teraz dodamy możliwość sortowania tabeli. Wprowadzimy w tym celu kilka zmian w widoku. Przede wszystkim dodamy handler zdarzenia click. Zmieniona została również pętla (przechodzimy teraz przez tablicę sortedUsers, którą za chwilę zaimplementujemy jako właściwość computed w Vue).
<div id="app">
  <table>
    <thead>
      <tr>
        <th @click="sort('name')">Name</th>
        <th @click="sort('age')">Age</th>
        <th @click="sort('job')">Job</th>
        <th @click="sort('gender')">Gender</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="user in sortedUsers">
        <td>{{user.name}}</td>
        <td>{{user.age}}</td>
        <td>{{user.job}}</td>
        <td>{{user.gender}}</td>
      </tr>
    </tbody>
  </table>
  debug: sort={{currentSort}}, dir={{currentSortDir}}
</div>
Po stronie JavaScript dodamy właściwości, aby śledzić, po czym sortujemy i w jakim kierunku.
data:{
  users: [],
  currentSort: 'name',
  currentSortDir: 'asc'
}
Następnie dodajemy metodę sort, która odpowiada za nasze sortowanie. Musi rozpoznać, kiedy sortujemy według tej samej kolumny i odwrócić kierunek.
methods:{
  sort: function(s) {
    if(s === this.currentSort) {
      this.currentSortDir = this.currentSortDir==='asc'?'desc':'asc';
    }
    this.currentSort = s;
  }
}
Pozostaje już tylko dodanie właściwości computed.
computed:{
  sortedUsers: function() {
    return this.users.sort((a, b) => {
      let modifier = 1;
      if(this.currentSortDir === 'desc') modifier = -1;
      if(a[this.currentSort] < b[this.currentSort]) return -1 * modifier;
      if(a[this.currentSort] > b[this.currentSort]) return 1 * modifier;
      return 0;
    });
  }
}