Vueで並び替え(ソート)してリストレンダリングする

2 min読了の目安(約1900字TECH技術記事

実現したいこと

v-forでリストレンダリングするときに中身の値(価格など)で並び替える

実装方法

まず普通にリストレンダリングする

<ul>
    <li v-for="fruit in fruits">
        {{ fruit }}
    </li>
</ul>
<!-- 省略 -->
<script>
  export default {
    data() {
      return {
        fruits: [{
            name: 'apple',
            price: 100
          },
          {
            name: 'banana',
            price: 200
          },
          {
            name: 'strawberry',
            price: 50
          }
        ]
      }
    }
  }
</script>

出力結果

{ "name": "apple", "price": 100 }
{ "name": "banana", "price": 200 }
{ "name": "strawberry", "price": 50 }

バラバラですね。未ソートなんで。
これから価格順に並び替えます。

computedで中身を並び替える

for in文の中でcomputedに通してからリストレンダリングします。
computedでは並び替えたあとの配列をreturn(返)します。

<ul>
  <!-- sortedFruitsByPriceから返ってきた配列を仮変数fruitに格納 -->
  <li v-for="fruit in sortedFruitsByPrice">
    {{ fruit }}
  </li>
</ul>
<!-- 省略 -->
<script>
  export default {
    computed: {
      sortedFruitsByPrice() {
        return this.fruits.sort((a, b) => {
          return a.price - b.price;
        });
      }
    },
    data() {
      return {
        fruits: [{
            name: 'apple',
            price: 100
          },
          {
            name: 'banana',
            price: 200
          },
          {
            name: 'strawberry',
            price: 50
          }
        ]
      }
    }
  }
</script>

表示結果

{ "name": "strawberry", "price": 50 }
{ "name": "apple", "price": 100 }
{ "name": "banana", "price": 200 }

無事、価格の昇順でソートされましたね。
降順にソートしたければ、aとbを逆にすればOK。

sortedFruitsByPrice() {
  return this.fruits.sort((a, b) => {
    return b.price - a.price;
  });
}

sort()メソッドはVueというよりJavaScriptの内容ですので、ここでは詳しく言及しませんが、
this.fruitsという配列を並び替える処理だと理解してください。
これに関してはMDNが分かりやすいのでそちらを参照してください 🙏🏻

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort