問題描述
項目前台有個tab標簽頁切換,三個TabPane標簽,分別掛載三個不同的組件,三個組件中都有網絡請求,且第三組件中數據量大無分頁,需要進行前端顯示優化——Tab頁怎樣進入頁面時只請求默認顯示項的數據?
HTML代碼大致如下,pending-table、warning-select、threshold-table分別是TabPane標簽中的三個組件:
<Tabs>
<TabPane label="等待處理" name="0">
<pending-table></pending-table>
</TabPane>
<TabPane label="預警查詢" name="1">
<warning-select></warning-select>
</TabPane>
<TabPane label="預警閥值" name="2">
<threshold-table></threshold-table>
</TabPane>
</Tabs>
說一下需求:
- 頁面加載時,默認顯示的Tab頁是“等待處理”,pending-table中顯示網絡請求回來的數據,頁面渲染需要流暢;
- “預警查詢”和“預警閥值”頁面中的數據,需要在鼠標點擊切換到對應的Tab頁時再做請求,不點擊不請求。
解決方法
解決思路:
過程1
首先的想法是點擊對應標簽頁時傳值給組件:
仔細查看關於Tabs的官方文檔的API,API中提供了一個Tabs標簽的on-click事件
當點擊TabPane時被觸發,@on-click是寫在<Tabs>
標簽中,使用時要調用方法解決
思路就是點擊tab標簽頁時獲得當前標簽頁的標志值,使用這個值控制子組件v-if隱藏,這個標志值默認為0,點第二個標簽時變成1,點第三個標簽變成2。
再繼續看,API中還提供了v-model雙向綁定的值,比使用on-click方便
給Tabs綁定一個雙向綁定的值,這時value的值就是你點擊的TabPane所對應的name:
<Tabs v-model="value">
<TabPane label="等待處理" name="0">
<pending-table></pending-table>
</TabPane>
<TabPane label="預警查詢" name="1">
<warning-select></warning-select>
</TabPane>
<TabPane label="預警閥值" name="2">
<threshold-table></threshold-table>
</TabPane>
</Tabs>
data() {
return {
value: '',
}
},
過程2
現在已經拿到了當前點擊的TabPane所對應的name,進行下一步“用name值控制組件顯隱”
<TabPane label="預警查詢" name="1">
<warning-select v-if=“value === ’1‘”></warning-select>
</TabPane>
以上代碼可以控制組件顯隱,但是在切換Tab頁時血卡無比,控制顯隱的方法Pass掉。
過程3
換了一種想法,決定將name值傳給子組件然后在子組件中,控制網絡請求是否執行。
使用父傳子將name值傳給子組件
<Tabs v-model="value">
<TabPane label="等待處理" name="0">
<pending-table></pending-table>
</TabPane>
<TabPane label="預警查詢" name="1">
<warning-select :getClick="value"></warning-select>
</TabPane>
<TabPane label="預警閥值" name="2">
<threshold-table :getClick="value"></threshold-table>
</TabPane>
</Tabs>
然后在子組件中編寫監聽函數監聽value值的變化:
其中this.channellevelList.length是渲染warning-select數據的data,this.query_channellevelList();是網絡請求
watch:{
getClick(value) {
if (this.channellevelList.length === 0 && value === '2') {
this.query_channellevelList();
}
}
},
點擊標簽頁時,watch可以監聽到value的變化,如果渲染數據的data長度為0(即還未開始渲染數據),執行網絡請求。
這樣做的意義是不用需要二次請求,數據可以保存在本地。
缺點:第一次切換數據量大的頁面請求時還是會血卡無比,但是只會卡一次。