Vue.js Vue js+HighChart-如何在呈现组件之前进行同步axios调用?

Vue.js Vue js+HighChart-如何在呈现组件之前进行同步axios调用?,vue.js,highcharts,axios,nuxt.js,Vue.js,Highcharts,Axios,Nuxt.js,亲爱的各位,我是vue js的新手。我制作了一个小的VUEJS+NUXT应用程序,它用图表呈现。通过webservice调用axios检索数据 问题是:webservice调用变得异步,而我的图表已经初始化。在呈现图表之前,如何使调用同步 虽然Highchart本身需要时间来初始化,但我必须使用它来设置超时功能。如果您忽略这一点,我有一个问题,即在图表初始化时设置数据,这会导致图表错误显示的问题 <template> <div> <highcharts :o

亲爱的各位,我是vue js的新手。我制作了一个小的VUEJS+NUXT应用程序,它用图表呈现。通过webservice调用axios检索数据

问题是:webservice调用变得异步,而我的图表已经初始化。在呈现图表之前,如何使调用同步

虽然Highchart本身需要时间来初始化,但我必须使用它来设置超时功能。如果您忽略这一点,我有一个问题,即在图表初始化时设置数据,这会导致图表错误显示的问题

<template>
  <div>
  <highcharts :options="chartOptions"></highcharts>
  </div>
</template>
<script>
    import axios from 'axios';
    import {Chart} from 'highcharts-vue'
    import Highcharts3D from 'highcharts/highcharts-3d'
    import Highcharts from 'highcharts'

    if (typeof Highcharts === 'object') {
        Highcharts3D(Highcharts);
    }

    export default {
        layout: 'contentOnly',
        auth: false,
        components: {
            highcharts: Chart
        },
        data() {
            return {
                data: [],
                chartOptions: {
                    title: {
                        text: ''
                    },
                    tooltip: {
                        pointFormat: '{point.percentage:.2f}%',
                    },
                    chart: {
                        type: 'pie',
                        options3d: {
                            enabled: true,
                            alpha: 50,
                        },
                        // plotBackgroundColor: 0,
                        // plotBorderWidth: 0,
                        // plotShadow: true,
                    },
                    series: [{
                        name: '',
                        data: [1],
                        tooltip: {
                            valueDecimals: 0
                        }
                    }],
                    plotOptions: {
                        pie: {
                            allowPointSelect: true,
                            cursor: 'pointer',
                            innerSize: '30%',
                            depth: 100,
                            dataLabels: {
                                enabled: true,
                                percentageDecimals: 2,
                                color: '#002a52',
                                connectorColor: '#002a52',
                                formatter: function () {
                                    return '<b>' + this.point.name + '</b>: ' + this.percentage.toFixed(2) + ' %';
                                }
                            }
                        }
                    },

                    credits: {
                        enabled: false
                    },
                    exporting: {
                        buttons: {
                            printButton: {
                                enabled: false
                            },
                            contextButton: {
                                enabled: false
                            }
                        }
                    },
                }
            };
        },
        mounted() {
            this.fetchData()
            setTimeout(function(){ 
                let data = []
                var index = 0
                for (var key in this.data) {
                    data[index] = []
                    data[index][0] = key
                    if (key == '30') data[index][0] = '< 30'
                    if (key == '999') data[index][0] = '> 65'
                    data[index][1] = this.data[key]
                    index++;
                }
                this.chartOptions.series[0].data = data
           }.bind(this), 1000);
        },
        methods: {
            fetchData() {       
                axios.post(this.$axios.defaults.baseURL + 'api/analytics/age', {
                    locale: this.$i18n.locale,
                    onlyPaid: this.$route.query.onlyPaid
                }).then(response => {
                    this.data = response.data
                }).catch(e => {
                    console.log(e)
                })
            }
        }
    }
</script>

您不认为需要使调用同步,只需等待web服务完成,然后显示图表,我通常使用布尔值,例如“isChartDataLoaded”,这就是我更新代码的地方

从“axios”导入axios; 从“highcharts vue”导入{Chart} 从“highcharts/highcharts-3d”导入Highcharts3D 从“Highcharts”导入Highcharts 如果Highcharts的类型===“对象”{ Highcharts3DHighcharts; } 导出默认值{ 布局:“仅限内容”, 作者:错, 组成部分:{ 海图:海图 }, 资料{ 返回{ isChartDataLoaded:false, 数据:[], 图表选项:{ 标题:{ 正文: }, 工具提示:{ pointFormat:“{point.percentage:.2f}%', }, 图表:{ 键入“pie”, 选项3D:{ 启用:对, 阿尔法:50, }, //plotBackgroundColor:0, //绘图边框宽度:0, //是的, }, 系列:[{ 姓名:, 数据:[1], 工具提示:{ 数值小数:0 } }], 打印选项:{ 馅饼:{ allowPointSelect:true, 光标:“指针”, 内部尺寸:“30%”, 深度:100, 数据标签:{ 启用:对, 百分比小数:2, 颜色:“002a52”, 接头颜色:“002a52”, 格式化程序:函数{ return+this.point.name+':'+this.percentage.toFixed2+'%'; } } } }, 学分:{ 已启用:false }, 出口:{ 按钮:{ 打印按钮:{ 已启用:false }, 上下文按钮:{ 已启用:false } } }, } }; }, 安装{ 这是fetchData setTimeoutfunction{ 让数据=[] var指数=0 对于此.data中的var键{ 数据[索引]=[] 数据[索引][0]=键 如果键=='30'数据[索引][0]='<30' 如果键=='999'数据[索引][0]='>65' data[index][1]=此.data[key] 索引++; } 此.chartOptions.series[0]。数据=数据 }.这个,1000; }, 方法:{ 获取数据{ this.ischartdataload=false; axios.postthis.$axios.defaults.baseURL+“api/analytics/age”{ 区域设置:此。$i18n.locale, onlyPaid:此.$route.query.onlyPaid }.thenresponse=>{ this.data=response.data; this.ischartdataload=true; }.catch=>{ 控制台日志 } } } }
您不认为需要使调用同步,只需等待web服务完成,然后显示图表,我通常使用布尔值,例如“isChartDataLoaded”,这就是我更新代码的地方

从“axios”导入axios; 从“highcharts vue”导入{Chart} 从“highcharts/highcharts-3d”导入Highcharts3D 从“Highcharts”导入Highcharts 如果Highcharts的类型===“对象”{ Highcharts3DHighcharts; } 导出默认值{ 布局:“仅限内容”, 作者:错, 组成部分:{ 海克 哈特:图表 }, 资料{ 返回{ isChartDataLoaded:false, 数据:[], 图表选项:{ 标题:{ 正文: }, 工具提示:{ pointFormat:“{point.percentage:.2f}%', }, 图表:{ 键入“pie”, 选项3D:{ 启用:对, 阿尔法:50, }, //plotBackgroundColor:0, //绘图边框宽度:0, //是的, }, 系列:[{ 姓名:, 数据:[1], 工具提示:{ 数值小数:0 } }], 打印选项:{ 馅饼:{ allowPointSelect:true, 光标:“指针”, 内部尺寸:“30%”, 深度:100, 数据标签:{ 启用:对, 百分比小数:2, 颜色:“002a52”, 接头颜色:“002a52”, 格式化程序:函数{ return+this.point.name+':'+this.percentage.toFixed2+'%'; } } } }, 学分:{ 已启用:false }, 出口:{ 按钮:{ 打印按钮:{ 已启用:false }, 上下文按钮:{ 已启用:false } } }, } }; }, 安装{ 这是fetchData setTimeoutfunction{ 让数据=[] var指数=0 对于此.data中的var键{ 数据[索引]=[] 数据[索引][0]=键 如果键=='30'数据[索引][0]='<30' 如果键=='999'数据[索引][0]='>65' data[index][1]=此.data[key] 索引++; } 此.chartOptions.series[0]。数据=数据 }.这个,1000; }, 方法:{ 获取数据{ this.ischartdataload=false; axios.postthis.$axios.defaults.baseURL+“api/analytics/age”{ 区域设置:此。$i18n.locale, onlyPaid:此.$route.query.onlyPaid }.thenresponse=>{ this.data=response.data; this.ischartdataload=true; }.catch=>{ 控制台日志 } } } }
您需要在beforeCreate钩子中获取数据,将其保存在组件数据中,并使组件渲染依赖于该数据:

<template>
  <div v-if="chartOptions.series[0].data.length">
    <highcharts class="hc" :options="chartOptions" ref="chart"></highcharts>
  </div>
</template>

<script>
export default {
  beforeCreate() {
    fetch("https://api.myjson.com/bins/hj6se")
      .then(resp => resp.json())
      .then(resp => {
        this.chartOptions.series[0].data = resp;
      });
  },

  data() {
    return {
      chartOptions: {
        series: [{
          data: []
        }]
      }
    };
  }
};
</script>

实时演示:

您需要在beforeCreate钩子中获取数据,将其保存在组件数据中,并使组件呈现依赖于该数据:

<template>
  <div v-if="chartOptions.series[0].data.length">
    <highcharts class="hc" :options="chartOptions" ref="chart"></highcharts>
  </div>
</template>

<script>
export default {
  beforeCreate() {
    fetch("https://api.myjson.com/bins/hj6se")
      .then(resp => resp.json())
      .then(resp => {
        this.chartOptions.series[0].data = resp;
      });
  },

  data() {
    return {
      chartOptions: {
        series: [{
          data: []
        }]
      }
    };
  }
};
</script>

现场演示:

我不明白您何时需要将if置于vue导出默认值之外。你应该在组件生命周期钩子中移动它。如果我保持HighCharts3DHighcharts而没有如果我得到错误类型错误:无法读取未定义的属性的parts/Globals.js。根据Github上描述的问题,这是一个解决方法吗?请看,我不明白什么时候需要将if置于vue导出默认值之外。你应该在组件生命周期钩子中移动它。如果我保持HighCharts3DHighcharts而没有如果我得到错误类型错误:无法读取未定义的属性的parts/Globals.js。根据Github上描述的问题,这是一个解决方法吗?请参见“谢谢”,但只有在HighChart组件不需要很长时间初始化的情况下,这才有效。我仍然需要使用你的方法超时功能,这不是最佳的。如果我可以切换到同步方法,我就不会有这个问题了。谢谢,但只有在HighChart组件不需要很长时间初始化的情况下,这才有效。我仍然需要使用你的方法超时功能,这不是最佳的。如果我可以切换到同步方法,我就不会有这个问题。