👉 该文章承接下文 “父组件异步获取数据传给子组件获取不到”

一、问题

vue项目中运用到了Tab切换,切换vue组件,如图切换封装的echarts图表组件
❗ **==> 注意:此时用的自己写的死数据,图表也添加了监听事件使图表随窗口变化而变化 **

代码如下:

   <el-tabs v-model="attributeName">
     <el-tab-pane label="用户数量" name="first">
       <Charts :barData="bardatas.count" type="bar" />
     </el-tab-pane>
     <el-tab-pane label="用户金额" name="second">
       <Charts :barData="bardatas.money" type="bar" />
     </el-tab-pane>
     <el-tab-pane label="服务模式" name="third">
       <Charts :barData="bardatas.type" type="bar" />
     </el-tab-pane>
   </el-tabs>

初始状态默认显示第一个tab时是正确的,如图:
在这里插入图片描述
当切换到第二第三个tab时,图表显示不完整,如图:
在这里插入图片描述

二、探究

后来发现,在初始页面加载完成时这三个tab都加载完成,再次切换的时候你会发现,组件不会重新渲染了
在这里插入图片描述
之后通过display:none;和 display: block;实现Tab来回切换
在这里插入图片描述
找到原因: 第二个和第三个tab中的echarts图表之所以显示不完整是因为echarts在页面加载之前就完成了绘制,此时图表所在div没有宽度,echarts会默认一个宽度绘制成图表
现在找到问题所在了,只要在切换到该tab时再绘制改tab下的echarts图表就可以

三、解决

1、发现有个属性element-ui中的属性 lazy:标签是否延迟渲染 (该方法不可取:等窗口大小发生变化时再切换tab图表不完整)

   <el-tabs v-model="attributeName">
     <el-tab-pane label="用户数量" name="first" :lazy="true">
       <Charts :barData="bardatas.count" type="bar" />
     </el-tab-pane>
     <el-tab-pane label="用户金额" name="second" :lazy="true">
       <Charts :barData="bardatas.money" type="bar" />
     </el-tab-pane>
     <el-tab-pane label="服务模式" name="third" :lazy="true">
       <Charts :barData="bardatas.type" type="bar" />
     </el-tab-pane>
   </el-tabs>

在这里插入图片描述

结果发现:在三个tab都加载完后,窗口大小发生变化时又回到了那个图表显示不全的问题
原因:因为这个属性仅仅是控制什么时候渲染tab-pane内的组件,和路由懒加载的逻辑一样,第一次仅加载首屏,后面用到了再加载(渲染),加载完三个tab之后通过display:none;和 display: block;实现接下来的Tab来回切换功能

2、利用v-if实现:我们想要的是每次切换tab都能够让对应的tab子组件进行重新渲染。

  <el-tabs v-model="attributeName">
    <el-tab-pane label="用户数量" name="first">
      <Charts v-if="attributeName === 'first'" :barData="bardatas.count" type="bar" />
    </el-tab-pane>
    <el-tab-pane label="用户金额" name="second">
      <Charts v-if="attributeName === 'second'" :barData="bardatas.money" type="bar" />
    </el-tab-pane>
    <el-tab-pane label="服务模式" name="third">
      <Charts v-if="attributeName === 'third'" :barData="bardatas.type" type="bar" />
    </el-tab-pane>
  </el-tabs>

小插曲

  // 监听窗口变化 - 只刷新最后一个图表
  window.onresize = myChart.resize;
  // 监听窗口变化 - 多个图表同时刷新
  window.addEventListener("resize", () => {
    myChart.resize();
  });

=== >如有错误欢迎指出😁

Logo

前往低代码交流专区

更多推荐