繁体   English   中英

如何让 vue 组件等到数据准备好渲染?

[英]How to let vue component wait until the data is ready for render?

vue 组件不会等待来自 controller 的数据使用 axios 获取,它提示错误:

index.vue?d4c7:200 Uncaught (in promise) TypeError: Cannot read property 'ftth' of undefined

我的代码如下:

<template>
    <div class="dashboard-editor-container">
        <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
            <line-chart :chart-data="lineChartData"/>
        </el-row>
    </div>
</template>

<script>
    import LineChart from './components/LineChart';
    import axios from 'axios';

    const lineChartData = {
        all: {
            FTTHData: [],
            VDSLData: [],
            ADSLData: [],
        },
    };
    export default {
        name: 'Dashboard',
        components: {
            LineChart,
        },
        data() {
            return {
                lineChartData: lineChartData.all,
            };
        },
        created() {
            this.getData();
        },
        methods: {
            handleSetLineChartData(type) {
                this.lineChartData = lineChartData[type];
            },
            async getData() {
                axios
                    .get('/api/data_graphs')
                    .then(response => {
                        console.log(response.data);
                        var data = response.data;
                        var i = 0;
                        for (i = Object.keys(data).length - 1; i >= 0; i--) {
                            lineChartData.all.FTTHData.push(data[i]['ftth']);
                            lineChartData.all.VDSLData.push(data[i]['vdsl']);
                            lineChartData.all.ADSLData.push(data[i]['adsl']);
                        }
                    });
            },
        },
    };
</script>

我必须使用监视方法吗?

首先,因为你有这样一个嵌套的数据结构,你需要一个计算属性来返回数据是否被加载。 通常,您可以在模板中执行此检查。

computed: {
  isDataLoaded() {
    const nestedLoaded = Object.keys(this.lineChartData).map(key => this.lineChartData[key].length !== 0)
    return this.lineChartData && nestedLoaded.length !== 0
  }
}

您可以使用v-if="isDataLoaded"隐藏元素,直到数据加载完毕。

尚不清楚response.data的外观,但因为您使用的是Object.keys ,所以我假设它是 object。

如果您需要遍历键,那么在使用数字索引时,您很可能不会得到 object。 因此,您需要获取key和索引i并使用该值来访问 object。 改变这个:

for (i = Object.keys(data).length - 1; i >= 0; i--) {
  lineChartData.all.FTTHData.push(data[i]['ftth']);
  lineChartData.all.VDSLData.push(data[i]['vdsl']);
  lineChartData.all.ADSLData.push(data[i]['adsl']);
}

对此:

const keys = Object.keys(data)
for (i = keys.length - 1; i >= 0; i--) {
  lineChartData.all.FTTHData.push(data[keys[i]]['ftth']);
  lineChartData.all.VDSLData.push(data[keys[i]]['vdsl']);
  lineChartData.all.ADSLData.push(data[keys[i]]['adsl']);
}

但是对于循环对象的键更容易使用:

for (let key in data) {
  lineChartData.all.FTTHData.push(data[key]['ftth']);
  lineChartData.all.VDSLData.push(data[key]['vdsl']);
  lineChartData.all.ADSLData.push(data[key]['adsl']);
}

替代语法将为您提供密钥,并且在我看来更容易阅读。

与此同时:

使用设置 Axios Timeout 5000ms

axios
.get('/api/data_graphs', { timeout: 5000 })
.then(response => {
  console.log(response.data);
  var data = response.data;
  var i = 0;
  for (i = Object.keys(data).length - 1; i >= 0; i--) {
    lineChartData.all.FTTHData.push(data[i]['ftth']);
    lineChartData.all.VDSLData.push(data[i]['vdsl']);
    lineChartData.all.ADSLData.push(data[i]['adsl']);
  }
  this.lineChartIsLoaded = true;
});

在 vue 组件中使用 v-if

<line-chart v-if="lineChartIsLoaded" :chart-data="lineChartData" :date-data="dateData" />

默认将 lineChartIsLoaded 设置为 false

const lineChartIsLoaded = false;

您可以在加载真实数据之前在数据属性中写入虚拟数据

all: {
  FTTHData: ["Loading..."],
  VDSLData: ["Loading..."],
  ADSLData: ["Loading..."],
},

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM