如何解决使用来自 api
正如我在标题中提到的,我想用 api 初始化 Chart.js 图表。我找到了教程,但它们主要是在页面呈现后更新数据。我想在呈现页面之前更新图表。所以我直接看到了初始化的图表,没有重新加载。
<template>
<h3>Stacked</h3>
<Chart type="bar" v-if="isReady" :data="stackedData" :options="stackedOptions"/>
</template>
<script>
import axios from "axios";
import {defineComponent,ref} from 'vue';
export default {
data() {
return {
isReady: false,stackedData: {
labels: ['A','B','C','D'],datasets: [{
type: 'bar',label: 'Something',backgroundColor: '#42A5F5',data: this.list_all
},{
type: 'bar',label: 'Another',backgroundColor: '#66BB6A',data: this.list_intersection
}]
},stackedOptions: {
tooltips: {
mode: 'index',intersect: false
},responsive: true,scales: {
xAxes: [{
stacked: true,}],yAxes: [{
stacked: true
}]
}
},basicoptions: null,//---------------------------------------------------
all:[]
list_intersection:[],list_all:[]
}
},beforeCreate() {
let apikaderURL = 'http://localhost:4000/apikader';
axios.get(apikaderURL).then(res => {
this.all = res.data;
this.saveData()
this.isReady=true;
}).catch(error => {
console.log(error)
});
},methods:{
saveData: function (){
for (var i in this.all){
if(this.all[i].id==='2' ){
this.list_all.push(this.all[i].someNumber)
}
if(this.all[i].id==='8'){
this.list_intersection.push(this.all[i].someNumber)
}
}
return this.list_all && this.list_intersection
}
}
}
</script>
我只是尝试使用 axios 获取值,对其进行过滤,然后将它们返回给图表对象的 data 属性,以便使用这些值对其进行初始化。
我想,因为我调用了 beforeCreate
,所以它应该可以工作,因为我在渲染之前初始化了值,但图表没有显示任何值。
我也尝试过使用 vue-chartjs
来实现,但我认为它不适用于 Vue 3 或者我做错了什么。
我怎样才能做到这一点? 非常感谢您。
解决方法
生命周期钩子(如 beforeCreate
等)实际上并没有延迟后续的组件生命周期步骤,即使是异步的,它们也只是提供了一个运行代码的入口点。
使用 v-if
延迟图表的呈现,直到数据准备好。 v-if
的作用类似于 watch
,在此之前根本不会呈现图表。使用 isReady
变量,您将在数据保存完成后设置该变量:
<Chart type="bar" v-if="isReady" :data="stackedData" :options="stackedOptions"/>
data() {
return {
isReady: false,...
}
}
axios.get(apiKaderURL).then(res => {
this.all = res.data;
this.saveData()
this.isReady = true; // Triggering the `v-if`
})
(未经测试,但原则上应该可行)
此外,您不能使用 this
从另一个数据属性设置数据属性,它将是 undefined
。您可以将它们设置为 null
:
data: this.list_all // Does nothing,can't use `this` like that
data: null // Change to this
因此将其设置为 null
并修复 saveData
方法:
methods: {
saveData() {
const listAll = [];
const listIntersection = [];
for (var i in this.all){
if(this.all[i].id==='2' ){
listAll.push(this.all[i].someNumber)
}
if(this.all[i].id==='8'){
listIntersection.push(this.all[i].someNumber)
}
}
this.stackedData.datasets[0].data = listAll;
this.stackedData.datasets[1].data = listIntersection;
}
}
,
我以前没有使用过 Chart.js,但我通读了安装、集成和使用文档,并提出了一个可能对您有帮助的示例(带有 Vue CLI 的 Vue 2)。
我使用我的 App.vue SFC 作为子图表组件 ChartTest.vue 的父级。在父级中,我使用“mounted”挂钩中的“setTimeout”调用模拟了 API 调用延迟。
App.vue
<template>
<div id="app">
<chart-test v-if="dataReady" :chartData="chartData" />
</div>
</template>
<script>
import ChartTest from '@/components/ChartTest'
export default {
name: 'App',components: {
ChartTest
},data() {
return {
chartData: [12,19,3,5,2,3],dataReady: false
}
},methods: {
getData() {
this.dataReady = true;
}
},mounted() {
// Simulate API call
setTimeout(this.getData(),2000);
}
}
</script>
ChartTest.vue
<template>
<div class="chart-test">
<h3>Chart Test</h3>
<canvas id="my-chart" width="400" height="400" ref="chartref"></canvas>
</div>
</template>
<script>
import Chart from 'chart.js';
export default {
data() {
return {
myChart: null
}
},props: {
chartData: {
type: Array,required: true
}
},mounted() {
this.myChart = new Chart(this.$refs.chartref,{
type: 'bar',data: {
labels: ['Red','Blue','Yellow','Green','Purple','Orange'],datasets: [{
label: '# of Votes',data: this.chartData,backgroundColor: [
'rgba(255,99,132,0.2)','rgba(54,162,235,'rgba(255,206,86,'rgba(75,192,'rgba(153,102,255,159,64,0.2)'
],borderColor: [
'rgba(255,1)',1)'
],borderWidth: 1
}]
},options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
}
</script>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。