在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 进行一个选择性渲染会比较好。

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





