簡要比較使用vue實現表格資料篩選的三種方式:@event、watch、computed
阿新 • • 發佈:2022-04-18
需求描述
在前端頁面實現:根據輸入的關鍵詞,篩選指定資料等於關鍵詞的資料行,並更新表格
直接看總結
基本思路
- 在輸入框中繫結input變數
- 根據input值過濾原始陣列;input為空則返回原始陣列的副本;通過lodash外掛實現防抖
- 將得到的新陣列賦予表格繫結的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依賴前兩項,此時使用計算屬性更方便且依賴關係清晰