1. 程式人生 > 其它 >簡要比較使用vue實現表格資料篩選的三種方式:@event、watch、computed

簡要比較使用vue實現表格資料篩選的三種方式:@event、watch、computed

需求描述

在前端頁面實現:根據輸入的關鍵詞,篩選指定資料等於關鍵詞的資料行,並更新表格

直接看總結

基本思路

  1. 在輸入框中繫結input變數
  2. 根據input值過濾原始陣列;input為空則返回原始陣列的副本;通過lodash外掛實現防抖
  3. 將得到的新陣列賦予表格繫結的model物件

方式 1——繫結按鈕事件

思路描述:將步驟2封裝成查詢方法,並將input作為引數傳入,然後繫結到按鈕的點選事件

JS 實現:

data() {
  return {
    input: "", // 實時關鍵詞
    oldInput: "", // 上一次使用篩選功能時的關鍵詞
    origData: [], // 儲存請求到的原始資料
    tableData: [], // 表格展示的資料
  };
},
created() {
  this.setOrigData();
  this.setTableData(this.origData); // 第一次載入時需手動新增表格資料
},
methods: {
  // 獲取服務端資料並將原始資料儲存副本
  setOrigTableData() {
    this.origData = getServerData();
  },
  // 設定表格model
  setTableData(data) {
    this.tableData = data;
  },
  // 定義輸入處理,並設定防抖功能
  handleInput: _.debounce(function (newInput) {
    this.queryData(newInput);
  }, 500),
  // 前端查詢,篩選符合條件的原始資料並更新表格model,清空關鍵詞時複製上一次請求服務端返回的資料副本
  queryData(newInput) {
    if (this.oldInput !== newInput) { // 關鍵詞變化時才重新篩選
      this.oldInput = newInput; // 儲存本次的關鍵詞
      if (!this.origData) this.setOrigData(); // 原始資料不存在時重新請求
      if (newInput) {
        this.setTableData(
          this.origData.filter(row => row.val === newInput && row)
        );
      } else {
        this.setTableData(JSON.parse(JSON.stringify(this.origData)));
      }
    //} else {
    //  console.log("不需要修改表格資料");
    //}
  },
}

優點:可以設定防抖或節流
缺點:表格第一次載入時,必須手動新增表格資料;程式碼量太大

評價:比較傳統的處理方式,對全部過程都能把握,可控性較強;小改進,將方法繫結到輸入框的input事件,輸入後自動篩選,可以簡化使用者操作

方式2——watch偵聽關鍵詞變化

思路:基本思路與方式2相同,區別是將事件繫結替換為使用watch偵聽input的變化,並自動呼叫查詢方法

JS 實現:

data() {
  return {
    input: "", // 實時關鍵詞
    origData: [], // 儲存請求到的原始資料
    tableData: [], // 表格展示的資料
  };
},
created() {
  this.setOrigData();
  this.setTableData(this.origData); // 第一次載入時需手動新增表格資料
},
watch: {
  input(val) {
    this.handleInput(val);
  },
},
methods: {
  // 獲取服務端資料並將原始資料儲存副本
  setOrigTableData() {
    this.origData = getServerData();
  },
  // 設定表格model
  setTableData(data) {
    this.tableData = data;
  },
  // 定義輸入處理,並設定防抖功能
  handleInput: _.debounce(function (newInput) {
    this.queryData(newInput);
  }, 500),
  // 前端查詢,篩選符合條件的原始資料並更新表格model,清空關鍵詞時複製上一次請求服務端返回的資料副本
  queryData(newInput) {
    if (!this.origData) this.setOrigData(); // 原始資料不存在時重新請求
    if (newInput) {
      this.setTableData(
        this.origData.filter(row => row.val === newInput && row)
      );
    } else {
      this.setTableData(JSON.parse(JSON.stringify(this.origData)));
    }
  },
}

優點:關鍵詞變化後自動執行,不需要判斷是否發生改變;可以設定防抖或節流
缺點:表格第一次載入時,必須手動新增表格資料;程式碼量還是較大

方式3——computed屬性

思路:通過建立computed屬性,自動更新tableData

JS 實現:

data() {
  return {
    input: "", // 實時關鍵詞
    origData: [], // 儲存請求到的原始資料
  };
},
computed: {
  tableData() { // 表格展示的資料
    if (this.input) { // 關鍵詞非空,執行篩選
      return this.origData.filter(row => row.val === this.input && row)
    } else { // 關鍵詞為空,顯示原始資料
      return JSON.parse(JSON.stringify(this.origData));
    }
  },
},
created() {
  this.setOrigData();
},
methods: {
  // 獲取服務端資料並將原始資料儲存副本
  setOrigTableData() {
    this.origData = getServerData();
  },
}

優點:響應式自動篩選或者重新顯示全部原始資料,實現程式碼少;表格首次載入不需要手動繫結資料,計算屬性會自動更新
缺點:無法設定防抖或節流

評價:計算屬性的作用是根據依賴屬性響應式地更新指定屬性,因此,依賴屬性的每次更新都會自動觸發計算屬性的更新,如果設定防抖,由於計算過程是非同步進行的,無法同步獲取計算結果;而若是使用Promise封裝防抖功能,則相當於依賴屬性的每次更新都會自動生成一個新的Promise物件,使得原本的防抖功能失效

總結

  • 繫結事件的實現思路最直接,也因此程式碼量最多,需要實現對所有過程的控制
  • 通過watch偵聽可以省去部分判斷邏輯,程式碼量相對較少;適用於偵聽系統或元件的狀態變化,並作出反應,只適合偵聽僅有單個依賴屬性的場景,多依賴的場景請使用計算屬性
  • Vue原生的計算屬性無法設定防抖或節流,要實現防抖功能請使用watch代替;適用於響應式更新存在依賴關係的屬性,尤其適合依賴項多的場景,比如官方示例的firstName、familyName和fullName,fullName依賴前兩項,此時使用計算屬性更方便且依賴關係清晰