Vue 初心者筆記 #14 表格排序

透過之前介紹的 computedv-bind:classv-ifv-for…等觀念,可以製作出一個表格排序的小作品,而這篇文章就是紀錄這個表格排序的練習是如何實作的。

實作哪些功能

透過點擊 th 反轉表格的排序方向:

  • 將資料排序改為使用 computed 輸出
  • 使用迴圈的方式,重新依據點擊排序內容,並透過 computed 輸出
  • 反轉時 th 上的指標需要給予正確方向
  • 第二次點擊時能夠再次反轉資料

實作步驟

STEP 1:資料使用 computed 輸出

首先,資料要改為直接使用 data 裡的資料,所以我們先把原本的輸出方式改為以 computed 運算到畫面上。
做法相當簡單,直接在 computed 裡面 return 原本的 data 就可以了:

1
2
3
4
5
6
7
computed: {
// 將資料改為使用 computed 輸出
filterArray: function(){
let vm = this;
return vm.data;
}
},

HTML 的 tr 程式碼也要改為 v-for="item in filterArray"

STEP 2:點擊指標反轉表格內容

價格和到期日都是用點擊標題來做排序,所以 Vue 裡面的 data 參數可以合併一起用。
只要建立 isReverse: true 代表是否依序排列,以及 select: '' 代表目前選擇項目,這兩個變數即可。

HTML 的價格上要改成 @click="select='price', isReverse = !isReverse",也就是目前選擇「價格」,按下排列順序反轉。
到期日也是一樣的設定 @click="select='expiryDate', isReverse = !isReverse"

click 內有多個事件要用「,」逗號隔開

接著只要在 computed 設定 sort() 排序,按下表格標題的「價格」與「到期日」就能排序囉!

Array.prototype.sort()

因為 sort() 排序方法的排序順序是根據字串的 Unicode 編碼位置而定,所以排序上會出現問題,不能單純只寫 sort(),我們要再加上如下的參數。

compareFunction 參數

compareFunction(a, b)

我們要透過這個參數告訴 sort() 怎麼做排序,告訴它 ab 兩個東西誰比較大、誰比較小。

compareFunction 的原理是 a - b

1
2
3
function compareNumbers(a, b) {
return a - b;
}
  • 回傳 -1:指 a 比較小,a 要排在 b 前面。
  • 回傳 0:指兩個值相等,ab 的順序皆不變。
  • 回傳 1:指 a 比較大,a 要排在 b 後面。

上述寫法的排序是「升冪」,也就是由小至大遞增。

範例程式碼(資料使用 computed 輸出):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
computed: {
filterArray: function(){
let vm = this;
let sortItem = vm.select;
let newData = vm.data.sort(function(a, b){
a = a[sortItem];
b = b[sortItem];
if(vm.isReverse){
return a - b; // 升幂 => (由上而下) 遞增
}else{
return b - a; // 降冪 => (由上而下) 遞減
}
})
return newData;
}
},

這邊其實就完成「第二次點擊時能夠再次反轉資料」的功能了,我們透過 isReverse 紀錄反轉是升幂或降冪。

STEP 3:隱藏指標與設定指標方向

隱藏指標

隱藏 icon 的 JavaScript 程式碼在 Vue 可用 v-if

以價格來說,在 HTML 的 span 標籤加上 v-if="select == 'price'"
同理到期日也是一樣的設定 v-if="select == 'expiryDate'"

設定指標方向

指標方向的設定在 STEP 2 時已經設定到 HTML 上了,透過 isReverse 的變化,動態加上 CSS 的 .inverse

以價格為例:

1
2
3
4
<th class="click th-w100"
@click="select='price', isReverse = !isReverse">價格
<span class="icon" id="priceIcon"
:class="{'inverse': isReverse}" v-if="select == 'price'">
1
2
3
4
5
6
7
8
9
10
11
/* 避免箭頭消失標題亂跑 */
.th-w100 {
width: 100px;
}
.icon {
display: inline-block;
}
.icon.inverse {
/* 箭頭朝下 */
transform: rotate(180deg);
}

加入 .th-w100 避免箭頭消失標題亂跑

參考資料

  1. 在 JavaScript 中,如何以 Object 內的 properties 進行陣列排序 | Lance 程式筆記 - 點部落
  2. Array.prototype.sort() - JavaScript | MDN

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。