使用 VueJS 在图形上绘制异步信息
Draw asynchronous information on a graph with VueJS
我正在使用一个旧的 codeigniter 项目 2.X MVC。我们开始为 VueJS 更改 JQuery,我现在要做的其中一件事就是制作图形,非常简单。
使用 axios 我得到了数据,这不是问题。问题是我无法让图表呈现信息,即使我传递了它。
我有一个创建图表的函数,其中包含之前已获得的信息:
createChart() {
var ctx = document.getElementById('grafico-historico');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: this.labels,
datasets: [{
label: 'Monto',
data: this.data,
borderWidth: 1
}]
}
});
}
我将信息或响应对象保存在组件的数据 () 部分:
data() {
return {
labels: [],
data: []
}
},
结果是一张空图。另一方面,如果我手动对图表中的标签和数据信息进行硬编码,它是否有效并显示结果。
我是 VueJS 的新手,所以我想这可能是概念错误或者我发生了什么事,你能告诉我我应该注意哪里吗?我尝试使用 vue-charts 库,但得到的结果完全相同。
我添加了我的组件的所有代码,以便您可以获得更多 "global" 外观。
Vue.component('line-chart', {
data() {
return {
labels: [],
data: []
}
},
created() {
this.getData();
},
mounted() {
this.createChart();
},
methods: {
getData() {
var labels = [];
var data = [];
axios.get(`/propietarios/api_buscarExpensasUnidad/${this.unidadid}`, {
credentials: 'same-origin'
}).then(r => {
r.data.datos.map(x => {
this.titulos.push(x[0]);
this.data.push(parseInt(x[1]));
});
}).catch(e => {
console.error(e);
});
},
createChart() {
var ctx = document.getElementById('grafico-historico');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: this.labels,
datasets: [{
label: 'Monto',
data: this.data,
borderWidth: 1
}]
}
});
}
}
});
作为最后的澄清,我不使用 .vue 文件,因为由于我们当前使用的项目的体系结构,这是不可能的,因此我将组件放在一个单独的 * .js 文件中,然后导入html + php 才能使用它。
VueJS 使用 Virtual DOM(像 ReactJS)和
Vue is a jealous library in the sense that you must let it completely
own the patch of DOM that you give it (defined by what you pass to
el).
来源:https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/
因此,直接修改 DOM 的库不适用于 VueJS。例如chartjs,jquery,等...
labels: this.labels,
,data: this.data,
将不会在您的异步函数完成后收到更新的数据。简而言之,它不是 Vue 组件,不能与 Vue 的反应系统一起使用。
幸运的是,人们已经制作了一个 Vue 兼容的 ChartJs 集成库(https://github.com/apertureless/vue-chartjs),它可以与 VueJS 反应系统一起工作。
示例:https://codepen.io/jacobgoh101/pen/YezPLg?editors=0010
您需要使用库中的这个 mixin VueChartJs.mixins.reactiveProp
来使图表具有反应性。
HTML
<div class="app">
{{ message }}
<line-chart :chart-data="chartData" :options="options"></line-chart>
</div>
JS
Vue.component("line-chart", {
extends: VueChartJs.Line,
props: ["chartData", "options"],
mixins: [VueChartJs.mixins.reactiveProp],
mounted() {
this.renderChart(this.chartData, this.options);
}
});
var vm = new Vue({
el: ".app",
data: {
message: "Hello World",
chartData: null,
options: { responsive: true, maintainAspectRatio: false }
},
mounted() {
this.sampleAsync();
},
methods: {
sampleAsync() {
setTimeout(() => {
this.chartData = {
labels: [
"January",
"February",
"March",
"April",
"May",
"June",
"July"
],
datasets: [
{
label: "Data One",
backgroundColor: "#f87979",
data: [40, 39, 10, 40, 39, 80, 40]
}
]
};
}, 1000);
}
}
});
我正在使用一个旧的 codeigniter 项目 2.X MVC。我们开始为 VueJS 更改 JQuery,我现在要做的其中一件事就是制作图形,非常简单。 使用 axios 我得到了数据,这不是问题。问题是我无法让图表呈现信息,即使我传递了它。
我有一个创建图表的函数,其中包含之前已获得的信息:
createChart() {
var ctx = document.getElementById('grafico-historico');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: this.labels,
datasets: [{
label: 'Monto',
data: this.data,
borderWidth: 1
}]
}
});
}
我将信息或响应对象保存在组件的数据 () 部分:
data() {
return {
labels: [],
data: []
}
},
结果是一张空图。另一方面,如果我手动对图表中的标签和数据信息进行硬编码,它是否有效并显示结果。 我是 VueJS 的新手,所以我想这可能是概念错误或者我发生了什么事,你能告诉我我应该注意哪里吗?我尝试使用 vue-charts 库,但得到的结果完全相同。 我添加了我的组件的所有代码,以便您可以获得更多 "global" 外观。
Vue.component('line-chart', {
data() {
return {
labels: [],
data: []
}
},
created() {
this.getData();
},
mounted() {
this.createChart();
},
methods: {
getData() {
var labels = [];
var data = [];
axios.get(`/propietarios/api_buscarExpensasUnidad/${this.unidadid}`, {
credentials: 'same-origin'
}).then(r => {
r.data.datos.map(x => {
this.titulos.push(x[0]);
this.data.push(parseInt(x[1]));
});
}).catch(e => {
console.error(e);
});
},
createChart() {
var ctx = document.getElementById('grafico-historico');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: this.labels,
datasets: [{
label: 'Monto',
data: this.data,
borderWidth: 1
}]
}
});
}
}
});
作为最后的澄清,我不使用 .vue 文件,因为由于我们当前使用的项目的体系结构,这是不可能的,因此我将组件放在一个单独的 * .js 文件中,然后导入html + php 才能使用它。
VueJS 使用 Virtual DOM(像 ReactJS)和
Vue is a jealous library in the sense that you must let it completely own the patch of DOM that you give it (defined by what you pass to el).
来源:https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/
因此,直接修改 DOM 的库不适用于 VueJS。例如chartjs,jquery,等...
labels: this.labels,
,data: this.data,
将不会在您的异步函数完成后收到更新的数据。简而言之,它不是 Vue 组件,不能与 Vue 的反应系统一起使用。
幸运的是,人们已经制作了一个 Vue 兼容的 ChartJs 集成库(https://github.com/apertureless/vue-chartjs),它可以与 VueJS 反应系统一起工作。
示例:https://codepen.io/jacobgoh101/pen/YezPLg?editors=0010
您需要使用库中的这个 mixin VueChartJs.mixins.reactiveProp
来使图表具有反应性。
HTML
<div class="app">
{{ message }}
<line-chart :chart-data="chartData" :options="options"></line-chart>
</div>
JS
Vue.component("line-chart", {
extends: VueChartJs.Line,
props: ["chartData", "options"],
mixins: [VueChartJs.mixins.reactiveProp],
mounted() {
this.renderChart(this.chartData, this.options);
}
});
var vm = new Vue({
el: ".app",
data: {
message: "Hello World",
chartData: null,
options: { responsive: true, maintainAspectRatio: false }
},
mounted() {
this.sampleAsync();
},
methods: {
sampleAsync() {
setTimeout(() => {
this.chartData = {
labels: [
"January",
"February",
"March",
"April",
"May",
"June",
"July"
],
datasets: [
{
label: "Data One",
backgroundColor: "#f87979",
data: [40, 39, 10, 40, 39, 80, 40]
}
]
};
}, 1000);
}
}
});