Vue中使用iview-UI实现切换Tab页网络请求优化

问题描述

项目前台有个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事件
Vue中使用iview-UI实现切换Tab页网络请求优化
当点击TabPane时被触发,@on-click是写在<Tabs>标签中,使用时要调用方法解决

思路就是点击tab标签页时获得当前标签页的标志值,使用这个值控制子组件v-if隐藏,这个标志值默认为0,点第二个标签时变成1,点第三个标签变成2。

再继续看,API中还提供了v-model双向绑定的值,比使用on-click方便
Vue中使用iview-UI实现切换Tab页网络请求优化

给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(即还未开始渲染数据),执行网络请求。
这样做的意义是不用需要二次请求,数据可以保存在本地。
缺点:第一次切换数据量大的页面请求时还是会血卡无比,但是只会卡一次。