weixin_58412143 2024-04-13 14:50 采纳率: 91.6%
浏览 9
已结题

vue2+eacharts 获取后端数据显示饼图并且是父子组件的方式?

vue2+eacharts 获取后端数据显示饼图并且是父子组件的方式,目前的问题是,控制台打印子组件先出现一遍有内容,然后报错 echarts is not defined然后再出现父组件打印数据,下面是我的代码,另外如果这个弄好了,我会再引入一个会话次数饼状图,那么是不是他俩用一个子组件就行?在el-tabs的时候判断是哪个图如何设置一个变量传不同的参数就行?
父组件

    <el-tabs v-model="activeName">
      <el-tab-pane label="来源渠道饼状图" name="second">
        <vab-chart-pie title="来源渠道饼状图" :pieData="pieData"  v-if="chartDataIsReady"/>
      </el-tab-pane>
      <el-tab-pane label="会话次数饼状图" name="third">
        <!-- <vab-chart-pie title="会话次数饼状图" /> -->
      </el-tab-pane>
    </el-tabs>
//return里的内容
 pieData: {
          //子组件中需要用到的数组
          lineData: [],
          SearData: [],
        },
  async  mounted() {
       await  this.fetchDataPie()
       this.chartDataIsReady = true;
      },
//获取饼图数据
      fetchDataPie(){
        getListPieSource().then((res)=>{
          // 将对象转换为数组对象
          const arr = Object.keys(res).map(key => ({name:key, value: res[key] }));
          this.pieData.SearData=arr
          // this.SearData=arr
          // 使用 Object.keys() 方法获取对象的键
          this.pieData.lineData = Object.keys(res);
          // 如果 lineData 属性之前不存在
          // this.$set(this.pieData, 'SearData', arr); // 使用 Vue.set 或 this.$set 来添加响应式属性
          // this.$set(this.pieData, 'lineData', Object.keys(res)); // 使用 Vue.set 或 this.$set 来添加响应式属性
          console.log('父---this.pieData')
          console.log(this.pieData)
        })
      },

子组件

<template>
  <!-- <el-col :lg="8" :md="12" :sm="24" :xl="6" :xs="24"> -->
  <el-col :span="24">
    <el-card shadow="hover">
      <template #header>
        <!-- <span>{{ title }}</span> -->
      </template>
      <!-- :init-options="initOptions" :option="option"  -->
      <vab-chart  ref="pieChart" theme="vab-echarts-theme" />
    </el-card>
  </el-col>
</template>

<script>
  import VabChart from '@/extra/VabChart'

  export default {
    name: 'VabChartPie',
    components: {
      VabChart,
    },
    props: {
      title: {
        type: String,
        default: '',
      },
      pieData: {
        type: Object,
        // required: true, // 这个prop是必须的
        // default: () => ({}) // 提供一个默认值,如果父组件没有传递Data
      },
    },
    data() {
      return {

      }
    },
    created() {

    },
    mounted() {
      console.log('子———this.pieData')
      console.log(this.pieData)
      console.log(this.pieData.SearData)
      this.initPieChart();
    },
    methods: {
      initPieChart() {
        const pieChart = echarts.init(this.$refs.pieChart);
        const option = {
          tooltip: {
            trigger: 'item'
          },
          series: [{
            name: '访问来源',
            type: 'pie',
            radius: '55%',
            data: this.pieData.SearData,
            // this.data.values.map((value, index) => {
            //   return {
            //     value: value,
            //     name: this.data.categories[index]
            //   };
            // }),
            itemStyle: {
              emphasis: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }]
        };
        pieChart.setOption(option);
      }
    }
  }
</script>



  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-13 14:50
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试创建一个带有两个饼图的Vue应用,其中一个饼图是来源渠道饼状图,另一个是会话次数饼状图,并且这些图表都由同一个子组件VabChartPie管理。目前遇到的问题是关于ECharts库未定义的错误。

    首先,确保已经在项目中正确安装并导入了ECharts库。如果你还没有这样做,可以通过npm安装:

    npm install echarts --save
    

    然后,在你的主入口文件(通常是main.js)中全局注册ECharts,这样在所有Vue组件中都可以直接使用:

    import Echarts from 'echarts';
    
    Vue.prototype.$echarts = Echarts; // 全局注册Echarts
    

    接下来,修复子组件中的问题。为了防止在ECharts实例化前就调用echarts.init(),可以在mounted钩子中添加一个检查,确认ECharts已经被定义:

    mounted() {
      if (window.echarts) { // 检查ECharts是否已经加载
        console.log('子———this.pieData');
        console.log(this.pieData);
        console.log(this.pieData.SearData);
    
        this.initPieChart();
      } else {
        setTimeout(() => {
          if (window.echarts) {
            this.initPieChart();
          }
        }, 100);
      }
    },
    

    同时,考虑到可能存在的异步加载问题,可以考虑使用Vue的 $nextTick 来确保DOM渲染完成后再执行初始化方法:

    mounted() {
      this.$nextTick(() => {
        if (window.echarts) {
          console.log('子———this.pieData');
          console.log(this.pieData);
          console.log(this.pieData.SearData);
    
          this.initPieChart();
        } else {
          setTimeout(() => {
            if (window.echarts) {
              this.initPieChart();
            }
          }, 100);
        }
      });
    },
    

    至于会话次数饼状图,你可以通过在父组件中动态地传递不同的数据给子组件。例如,当用户切换到会话次数饼状图时,更新相应的数据并重新渲染子组件。由于你的代码示例中没有展示如何获取会话次数的数据,这里假设你有一个名为 fetchDataSessionPie 的方法用于获取会话次数数据,并将结果保存到 sessionPieData 中。

    在父组件中:

    data() {
      return {
        activeName: 'second',
        pieData: {
          // 子组件中需要用到的数组
          lineData: [],
          SearData: [],
        },
        sessionPieData: {}, // 假设这是会话次数的数据
      };
    },
    
    methods: {
      fetchDataPie() {
        // ...
      },
    
      fetchDataSessionPie() {
        // 获取会话次数数据的方法
      },
    },
    watch: {
      activeName(newActiveName) {
        if (newActiveName === 'third') {
          this.fetchDataSessionPie();
          this.chartDataIsReady = true;
        } else {
          this.chartDataIsReady = false;
        }
      },
    },
    

    然后在模板中:

    <!-- ... -->
    <el-tab-pane label="会话次数饼状图" name="third">
      <vab-chart-pie
        title="会话次数饼状图"
        :pieData="sessionPieData"
        v-if="chartDataIsReady && activeName === 'third'"
      />
    </el-tab-pane>
    <!-- ... -->
    

    子组件保持不变,但是要根据父组件传递的不同数据进行渲染。你可以通过修改initPieChart方法来处理不同类型的饼图数据。

    现在你应该能正常显示两个饼图,并且在切换标签时加载对应的数据。记得根据实际情况调整fetchDataSessionPie方法以从后端获取正确的会话次数数据。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月21日
  • 已采纳回答 4月13日
  • 创建了问题 4月13日

悬赏问题

  • ¥15 数据量少可以用MK趋势分析吗
  • ¥15 使用VH6501干扰RTR位,CANoe上显示的错误帧不足32个就进入bus off快慢恢复,为什么?
  • ¥15 大智慧怎么编写一个选股程序
  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中