VUE,element-ui,优化tabs组件每次点击,所有子页面都重新渲染问题。

本文介绍了如何优化Vue和Element-UI中的Tabs组件,避免每次切换Tab时所有子页面重新渲染,从而节省网络资源。通过使用v-if实现惰性加载,减少代码冗余,提升性能。文章详细展示了从第一版到第三版的优化过程,包括数据处理、代码简化和子组件渲染的改进。
部署运行你感兴趣的模型镜像

在element-ui的tabs组件中,我们发现每次切换页面,所有的子组件都会重新渲染一次。当子页面需要发送数据请求并且子页面过多时,这样会过多的占用网络资源。这里我们可以使用v-if来进行判断是否渲染该子页面。
不会如何在父页面载入子页面的可用看这一篇文章:在父页面引入子页面文件

v-if属于惰性加载,当值为false的时候,就不会加载。

这个办法是自己研究出来的一个方法,应该还有改善的空间,
本人在不断的优化代码,在发现了更简短的代码之后会在下面更新,已经更新到第三版。

需要使用的可直接看最后一个版本,如果想要学习交流的可用从上往下看。

第一版本:

1.在data中定义每个子组件相应的值,ture为加载,false为不加载。
在这里插入图片描述2.在子组件中使用v-if来判断是否渲染当前页面
在这里插入图片描述3.在函数中对子组件的值进行切换。

handleClick(tab) {
      switch (tab.name) {
        case "first":
          this.pageOne = true;
          this.pageTwo = false;
          this.pageThree = false;
          break;
        case "second":
          this.pageOne = false;
          this.pageTwo = true;
          this.pageThree = false;
          break;
        case "third":
          this.pageOne = false;
          this.pageTwo = false;
          this.pageThree = true;
          break;

        default:
          break;
      }

使用switch来判断tab的name值,并且对不同情况做出不同的判断。
但是这对于子页面过多的情况来说实在是太麻烦了。所以研发出第二版~

第二版:解决handleClick(tab)代码冗余

1.这一次定义一个数组,将子页面的值都放在里面,用来判断该页面是否需要渲染

data() {
    return {
      activeName: "allOrder",
      pages: {
        allOrder: true,//第一个需要渲染的页面
        unpaid: false,
        wangtingList: false,
        wangtingService: false,
        unCheck: false,
        finish: false,
        stayAway: false,
      },
    };
  },

2.在子页面组件中使用v-if判断是否渲染

 <el-tab-pane label="所有订单" name="allOrder">
     <allOrder v-if="pages.allOrder"></allOrder>
  </el-tab-pane>

3.定义切换组件时,需要渲染的界面,修改data内page中对应的数据的值。
handleClick(tab)是element-ui在原版代码中已经绑定好的函数,可以直接在method里定义,切换tabs的时候就会自动调用。
这一次我们使用了for循环来进行一个判断处理,代码会比第一版的switch要简洁一些。

handleClick(tab) {
      for (var i in this.pages) {
        console.log(i);
        if (tab.name != i) {
          this.pages[i] = false;
          //   console.log(this.pages[i]);
        } else {
          this.pages[i] = true;
        }
      }
    },

虽然在handleClick中我们进行了一些优化,但是在子组件代码上还是非常的冗余。七个子页面需要写七次,如果子页面再增加就会变得异常的繁琐。

    <el-tabs v-model="activeName" @tab-click="handleClick">
      <el-tab-pane label="所有订单" name="allOrder">
        <allOrder v-if="pages.allOrder"></allOrder>
      </el-tab-pane>
      <el-tab-pane label="待支付" name="unpaid">
        <unpaid v-if="pages.unpaid"></unpaid>
      </el-tab-pane>
      <el-tab-pane label="待派单" name="stayAway">
        <stayAway v-if="pages.stayAway"></stayAway>
      </el-tab-pane>
      <el-tab-pane label="待接单" name="wangtingList">
        <wangtingList v-if="pages.wangtingList"></wangtingList>
      </el-tab-pane>
      <el-tab-pane label="待服务" name="wangtingService">
        <wangtingService v-if="pages.wangtingService"></wangtingService>
      </el-tab-pane>
      <el-tab-pane label="待确认" name="unCheck">
        <unCheck v-if="pages.unCheck"></unCheck>
      </el-tab-pane>
      <el-tab-pane label="已完成" name="finish">
        <finish v-if="pages.finish"></finish>
      </el-tab-pane>
    </el-tabs>

第三版:解决子组件代码冗余(目前最终版)

1.在data中创建一个数组对象,在里面存放子组件名称以及展示在页面上的中文名。并定义一个变量存放当前需要渲染加载的页面。

data() {
    return {
      activeName: "allOrder",//第一个加载的页面
      nowPage: "allOrder",//当前需要渲染的页面
      pages: [
      //所有子页面信息
        {
          name: "allOrder",
          label: "所有订单",
        },
        {
          name: "unpaid",
          label: "待支付",
        },
        {
          name: "stayAway",
          label: "待派单",
        },
        {
          name: "wangtingList",
          label: "待接单",
        },
        {
          name: "wangtingService",
          label: "待服务",
        },
        {
          name: "unCheck",
          label: "待确认",
        },
        {
          name: "finish",
          label: "已完成",
        },
      ],
    };
  },
  

2.在html中使用v-for循环生成子组件,将name和label赋值。
在循环生成的子组件中不能直接使用
<pages.name></pages.name>这样的写法来生成子页面,需要使用:is来加载对应的子页面,并用v-if来判断是否需要渲染当前子页面。

<el-tabs v-model="activeName" @tab-click="handleClick">
      <el-tab-pane
        v-for="(pages, index) in pages"
        v-bind:key="index"
        :label="pages.label"
        :name="pages.name"
      >
      <!--循环生成子页面-->
        <components :is="pages.name" v-if="pages.name == nowPage"></components>
      </el-tab-pane>
    </el-tabs>

3.在handleClick(tab)中修改需要加载的子页面

 handleClick(tab) {
      this.nowPage = tab.name;   
    },

这样代码中html部分和函数部分就会变得非常的简短

整体代码

<template>
  <div style="padding: 20px" id="order">
    <!--  @tab-click="handleClick"-->
    <el-tabs v-model="activeName" @tab-click="handleClick">
      <el-tab-pane
        v-for="(pages, index) in pages"
        v-bind:key="index"
        :label="pages.label"
        :name="pages.name"
      >
        <components :is="pages.name" v-if="pages.name == nowPage"></components>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
import allOrder from "./components/allOrder";
import unpaid from "./components/unpaid";
import wangtingList from "./components/wangtingList";
import wangtingService from "./components/wangtingService";
import unCheck from "./components/unCheck";
import finish from "./components/finish";
import stayAway from "./components/stayAway";
export default {
  data() {
    return {
      activeName: "allOrder",
      nowPage: "allOrder",
      pages: [
        {
          name: "allOrder",
          label: "所有订单",
        },
        {
          name: "unpaid",
          label: "待支付",
        },
        {
          name: "stayAway",
          label: "待派单",
        },
        {
          name: "wangtingList",
          label: "待接单",
        },
        {
          name: "wangtingService",
          label: "待服务",
        },
        {
          name: "unCheck",
          label: "待确认",
        },
        {
          name: "finish",
          label: "已完成",
        },
      ],
    };
  },
  methods: {
    //每次切换只渲染一个界面
    handleClick(tab) {
      this.nowPage = tab.name;
     
    },
  },
  components: {
    allOrder,
    unpaid,
    wangtingList,
    wangtingService,
    unCheck,
    finish,
    stayAway,
  },
};
</script>

效果:
在这里插入图片描述

总结:
element-ui中的tabs每次点击时都会给所有页面重新渲染,为的是保证当子页面存在需要实时加载的情况下能保证数据的更新。

但是当子页面过多,每次切换都会把所有页面都加载,就会占用过多的网络资源。

v-if这个方法适用于非频繁切换的场景。在当前的使用中是非常合适的。

v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;如果在运行时条件很少改变,使用 v-if 进行一个选择性渲染会比较好。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值