在使用naive ui表格組件時,如何避免renderexpand中接口無限重復調用?
許多開發者在使用Naive UI的renderExpand屬性展開表格行時,會遇到一個棘手的問題:當在renderExpand中調用接口請求數據并使用響應式數據時,接口會無限重復調用。這主要是因為響應式數據的變化會觸發組件重新渲染,從而再次調用renderExpand,形成一個死循環。如果不使用響應式數據,雖然接口只會調用一次,但數據卻無法正確渲染到展開的表格中。
本文將詳細解釋這個問題產生的原因,并提供解決方案。問題代碼片段如下:
{ type: 'expand', renderExpand: rowData => { const columns = [ ... ] const tableData = ref([]) // 自動重復調用接口 getTableData().then( // 賦值 tableData = ... ) return h( NDatatable, { columns, data: tableData.value // 重復渲染導致重復調用 }, null ) } }
代碼中,tableData 為響應式數據,getTableData() 方法每次渲染都會被調用,導致接口無限請求。而如果 tableData 不是響應式數據,則接口只調用一次,但由于數據無法被 vue 框架追蹤,所以無法更新視圖,導致數據無法渲染。
解決方法是利用watchEffect來控制接口的調用時機,并結合緩存機制來避免重復請求。改進后的代碼如下:
{ type: 'expand', renderExpand: rowData => { const tableData = ref([]) // 用 watchEffect watchEffect(() => { if (shouldCallApi(rowData)) { // 更新 tableData getTableData(rowData).then(data => { tableData.value = data }) } else { // 用緩存數據 tableData.value = getCachedResult(rowData) } }) const columns = [ // ... ] return h( NDatatable, { columns, data: tableData.value }, null ) } }
在這個改進后的版本中,我們使用了 watchEffect。它會在 rowData 發生變化時執行,但只會在第一次以及 shouldCallApi(rowData) 返回 true 時調用接口。 shouldCallApi 函數用于控制是否需要調用接口,例如可以根據 rowData 是否已緩存來判斷。 getCachedResult 函數用于從緩存中獲取數據。這樣就避免了接口的無限重復調用,同時保證了數據的正確渲染。 通過這種方式,既能保證數據實時更新,又能避免不必要的接口請求,提升了應用的性能和效率。