實作功能

主要功能:透過點擊 th 反轉表格的排序方向,詳細操作如下:

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

實作步驟

STEP 1:資料使用 computed 輸出

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

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

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

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

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

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

以價格為例:

<th class="click th-w100" @click="select='price', isReverse = !isReverse">
  價格
  <span
    class="icon"
    id="priceIcon"
    :class="{'inverse': isReverse}"
    v-if="select == 'price'"
  ></span>
</th>
/* 避免箭頭消失標題亂跑 */
.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

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