周日-选项卡切换中图表 无法自适应 ?

昨天写的 tabs标签页切换中存在一个问题,除了默认展示的页面,其他页面也可以切换,只是发生了坍缩,挤成了一小块。

  • 经过这两天的工作,我总结的问题所在 及注意点。

    • tabs是一次性渲染完毕的
    • 注意点: 图表的展示需要一个宽高确定的容器

首先 tabs 是一次性渲染完毕的

  • 我是这样理解的:
  • 图表不是真正意义上的坍缩,而是在一次性渲染的时候他的宽高就那么大,所以图也就那么大. 要想证明也不难,看看图表组件内部的 created 钩子在点击的时候会不会执行就可以。
    • 执行-就证明它是会在点击的时候重新构建的。
js 复制代码
<template>
  <div class="charts" ref="chart"></div>
</template>

<script>
import * as echarts from "echarts";
export default {
  name: "Chart",
  props: {/* ··· */},
  created(){
    console.log('我被创造出来了!');
  },
  data() {
    return {/* ··· */};
  },
  mounted() {/* ··· */},
  methods: {/* ··· */},
  watch: {/* ··· */},
};
</script>

<style scoped lang="less"> /* ··· */ </style>
  • 很显然,一经挂载它就执行了9次说明它只会在最初的时候会对这些数据进行处理。
  • 通过显示的小图,其实也可以窥见到,每一项的 tab-pane 是有多大(挺有趣的),虽然没啥用。

  • 从上面可以得到两个结论

    • 1.首次展示是正常的。
    • 2.渲染是一次性渲染完毕的。
  • 也就是说只有我们看见的时候渲染的组件显示是 "正常" 的。

其次 图表的展示需要 宽高确定的容器

  • 容器的高度必须给确定值 百分比无效( el-input的宽度也一样 );
  • 无效的情况

    • 这个问题我在遇见的时候,迷迷糊糊不清楚原因,临时解决是给他设置了 vw 和 wh ( 最大值100 和百分比的用法一样 不过他是 以屏幕大小作为计算依据的 )
    • 当时只想着不能给死值,且是在 el-card 的包裹里面 ,怎么设置怎么不生效别说撑开了,让它显示都难。
      • el-card 设置样式有一个设定好的方法 :body-style="{width:"100%",/*···*/}" ; 这也是后两天才发现的。( 去翻的文档)

最后 是解决方式

  • 既然只有首次挂载,看的见的才能 "正常" 那就每次挂载,都让它 卸载再挂载一次。
  • 我采用的方式也是最简单的,就是 v-if
    • v-if 为true 时显示组件 为false 时不显示,且dom信息直接消失,是删除不是隐藏。
    • v-show 是隐藏 不是消失 (我认为:在大量数据 且切换频繁的组件用 v-show 比较合适),这里并不能起到效果
    • 只有把组件删除掉,才会在挂载的时候 触发挂载,不然一直都在的哪里来的挂载。
  • 我选择在 点击事件都是用的 为图表更改数据的方法里(省事,只写一次);
js 复制代码
editOption( index = 0){

      this.chartOption.xAxis.data = Object.keys(this.titleContent2[index]);

      this.chartOption.series.data = Object.values(this.titleContent2[index]);

      this.chartShow = false

      clearTimeout(this.time)

      this.time = setTimeout(()=>{

        this.chartShow = true;

      },200);

    }

问题出来了,他在切换的时候会缩进去。 原因是切换的时候,它的内容(图表)是销毁了的,没有东西撑着,它就缩进去了。 给tabs 设置固定高度,百分比无效

以下就是完整的代码了!

js 复制代码
<template>
  <div class="box">
    <h2 style="color:rgb(122, 105, 204)">el-tabs 渲染</h2>
    <el-tabs v-model="value" @tab-click="handleClick">
      <el-tab-pane v-for="(item,index) in titleList1" :key="index"
        :label="item"
        :name="item"
      >
        <el-tabs style="height:240px" v-model="value2" @tab-click="handle2Click">
          <el-tab-pane v-for="(arrItem,index) in titleList2" :key="index"
            :label="arrItem"
            :name="arrItem"
          >
            <Chart v-if="chartShow" class="chartHeight"
              :option="chartOption"
            />
          </el-tab-pane>
        </el-tabs>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import axios from 'axios';
import Chart from "../../components/Chart.vue";
export default {
  name: "RenderingForObjectForm",
  data() {
    return {
       chartOption: {
         xAxis: { data: [] },
         series: {
           type: "line",
           smooth: true,
           data: [],
         },
       },
      objData:{},
      // 渲染一级 标题的数据
      titleList1:[],
      // 一级 标题对应的数据
      titleContent1:[],
      titleList2:[],
      titleContent2:[],
      value: "",
      value2:"",

      time:'',
      chartShow:true,
    };
  },
  mounted(){
    // 我是用了mock
    this.getList();//获取数据 的方法
  },
  methods: {
    async getList(){// 初始化
      // 我们通过发请求,拿到了数据,并赋值给了 objData
      let data = await axios.get("/web/getList")
      this.objData = data.data
      console.log(this.objData);
      // 解析出来渲染一级 标题的数据
      this.titleList1 =  Object.keys(this.objData);
      this.titleContent1 = Object.values(this.objData);
        // 首先设置 一级title的默认值
        this.value = this.titleList1[0];
        this.setList1()
    },
    handleClick() { // 点击事件
      this.setList1()
    },
    handle2Click() {
      this.titleList1.forEach((item,index)=>{
        if(item == this.value){
          this.titleList2.forEach((item,index)=>{
            if(item == this.value2){
              this.editOption(index)
            }
          })
        }
      })
    },
    setList1(){
      this.titleList1.forEach((item,index)=>{
        if(item == this.value){
          let t2 = this.titleContent1[index]; 
            this.titleList2 = Object.keys(t2);
            this.titleContent2 = Object.values(t2);
            this.value2 = this.titleList2[0]
            this.editOption()
        }
      })
    },
    editOption( index = 0){
      this.chartOption.xAxis.data = Object.keys(this.titleContent2[index]);
      this.chartOption.series.data = Object.values(this.titleContent2[index]);
      this.chartShow = false
      clearTimeout(this.time)
      this.time = setTimeout(()=>{
        this.chartShow = true;
      },200);
    }
  },
  components: { Chart },
};
</script>

<style scoped lang="less">
.chartHeight {
  height: 200px;
  width: 100%;
}
</style>

OK 晚安!!!

相关推荐
星语卿1 小时前
Vuetify:构建优雅Vue应用的Material Design组件库
前端·javascript·vue.js
wangbing11251 小时前
界面规范11-对话框
javascript·vue.js·elementui
roman_日积跬步-终至千里1 小时前
【系统架构设计(25)】Web应用服务器与现代架构
前端·架构·系统架构
yshhuang1 小时前
在Windows上搭建开发环境
前端·后端
littleplayer1 小时前
Redux在iOS中的使用
前端
跟橙姐学代码1 小时前
Python里的“管家婆”:带你玩转os库的所有神操作
前端·python·ipython
jingling5551 小时前
uniapp | 快速上手ThorUI组件
前端·笔记·前端框架·uni-app
UrbanJazzerati1 小时前
可拖拽的进度条组件实战:实现思路与Demo
前端·面试
Cache技术分享2 小时前
188. Java 异常 - Java 异常处理规范
前端·后端