测试基础 [已解决] vue 中 echart 在子组件中只显示一次的问题

zailushang · 2020年07月01日 · 最后由 zailushang 回复于 2020年07月03日 · 91 次阅读

问题描述

vue 推荐组件化开发,所以就把每个图表封装成子组件,然后在需要用到该图表的父组件中直接使用。
实际开发中,数据肯定都是异步获取的。所以我们在 mounted 生命周期中获取数据。
由于父组件请求的数据并不是一成不变的,会根据不同的条件请求不同的数据,此时需要图表进行更新。
发现,数据更新后,图表没有变化。

父组件使用子组件

// 直接使用子组件
<new-pie title="产品用例分布" subtext="标注" backgroundStyle="light" :pieData=casePieData></new-pie>
// 组件引入
import newPie from '../../lib/newPie'
export default {
  components: {DocCard, NewsCard, InterfaceCard, myChart, oldPie, newPie},
  ...
  methods: {
getProjectCases() {
      this.casePieData = [];
      this.$ajax
              .get("/report/cases")
              .then(res => {
                this.casePieData = res.data.data.casePieData;
              })
              .catch(function (error) {
                console.log(error);
      })
    }
}
}

子组件(饼图)代码

<template>
    <Card>
        <div id="newPie" style="width: 100%;height:400px;"></div>
    </Card>
</template>
<script>
    export default {
        name: "app",
        props: ['title', 'subtext', 'backgroundStyle', 'pieData'],
        data() {
            return {
            }
        },
        methods: {
            // 定制饼图
            drawWonderland(title, subtext, backgroundStyle, pieData) {
                // 基于准备好的dom,初始化echarts实例
                var myWonderland = this.$echarts.init(document.getElementById("newPie"), backgroundStyle);
                let option = {
                    title: {
                        text: title,
                        subtext: subtext,
                    },
                    legend: {top: 30},
                    tooltip: {
                        trigger: 'axis'
                    },
                    toolbox: {
                        show: true,  // 是否显示工具栏
                        orient: 'vertical',  // 工具栏方向,垂直排列或水平排列
                        itemSize: 15,  // 工具栏大小
                        itemGap: 15,  // 每项之间的间隔
                        showTitle: true,  // 鼠标 hover 的时候显示每个工具 icon 的标题
                        top: 100,
                        right: 0,
                        feature: {
                            dataView: { //数据视图
                                show: true
                            },
                            saveAsImage: {}
                        }
                    },
                    // 全局调色盘。
                    color: ['#c23531','#2f4554', '#61a0a8', '#d48265', '#91c7ae','#749f83',  '#ca8622', '#bda29a','#6e7074', '#546570', '#c4ccd3'],
                    series : [
                        {
                            name: '访问来源',
                            center: ['50%', '50%'],
                            type: 'pie',    // 设置图表类型为饼图
                            radius: '55%',  // 饼图的半径,外半径为可视区尺寸(容器高宽中较小一项)的 55% 长度。
                            data: pieData,
                            itemStyle:{
                                normal:{
                                    label:{
                                        show: true,
                                        formatter: '{b} : {c} ({d}%)'
                                    },
                                    labelLine :{show:true}
                                }
                            }
                        }
                    ]
                };
                myWonderland.setOption(option, true);
            },

            // 引入第三方js库
            importWonderland() {
                const wonderland = document.createElement('script');
                wonderland.type = 'text/javascript';
                wonderland.src = 'https://www.runoob.com/static/js/wonderland.js';
                document.body.appendChild(wonderland);
            }
  },
  mounted() {
            this.importWonderland();
            this.drawWonderland(this.title, this.subtext, this.backgroundStyle, this.pieData);
  }
};
</script>

我们发现第一次图表能正常显示,但是页面一刷新或者跳转到其它页面,再返回到该页面,图表就不显示了。
原因
自己当时没有想那么多为什么无法加载,因此在另一个父组件进行应用的时候,他是首屏就加载,数据不变动。

但是当数据变动之后,无法自动的更新图表。

由于 mounted 只会在挂载的时候执行一次,因此无法后续进行更新

解决办法

通过 watch 进行图表的更新

watch: {
            pieData() {
                this.$nextTick( () => {
                    if (this.pieData) {
                        this.drawWonderland(this.title, this.subtext, this.backgroundStyle, this.pieData);
                    }
                } )
            }
        },

这样就能解决我们的问题了

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 2 条回复 时间 点赞
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册