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

昨天写的 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 晚安!!!

相关推荐
新缸中之脑2 分钟前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8565 分钟前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习12 分钟前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript
blaizeer41 分钟前
深入理解 CSS 浮动(Float):详尽指南
前端·css
速盾cdn1 小时前
速盾:网页游戏部署高防服务器有什么优势?
服务器·前端·web安全
小白求学11 小时前
CSS浮动
前端·css·css3
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(POST)
前端·csrf
XiaoYu20022 小时前
22.JS高级-ES6之Symbol类型与Set、Map数据结构
前端·javascript·代码规范
golitter.2 小时前
Vue组件库Element-ui
前端·vue.js·ui
道爷我悟了2 小时前
Vue入门-指令学习-v-on
javascript·vue.js·学习