Vue组件中使用vue-chartjs仅第三个折线图加载问题排查
Vue 2中vue-chartjs多折线图仅第三个加载的问题
我在单个Vue组件中使用vue-chartjs实现3个折线图,遵循Vue 2官方示例开发,但只有第三个“Overview”图表正常显示,前两个无内容且无报错,找不到解决办法。期望实现三个折线图依次展示的效果。
LineChart 组件
<template> <LineChartGenerator :chart-id="chartId" :chart-options="chartOptions" :chart-data="chartData" /> </template> <script> import { Line as LineChartGenerator } from "vue-chartjs/legacy"; export default { name: "LineChart", components: { LineChartGenerator, }, props: ["chartData", "chartOptions", "chartId"], }; </script>
Overview 组件
<template> <div> <div class="chart-div"> <h4 class="chart-title m-2"> Top Searches Results </h4> <div class="chart-box"> <line-chart :chart-id="'top-searches'" :chart-data="chartDataTop" :chart-options="chartOptionsTop" /> </div> </div> <div class="chart-div"> <h4 class="chart-title m-2"> Zero Results Overview </h4> <div class="chart-box"> <line-chart :chart-id="'zero-searches'" :chart-data="chartDataZero" :chart-options="chartOptionsZero" /> </div> </div> <div class="chart-div"> <h4 class="chart-title m-2">Overview</h4> <div class="chart-box"> <line-chart :chart-id="'overview-searches'" :chart-data="chartDataOverview" :chart-options="chartOptionsOverview" /> </div> </div> </div> </template> <script> import LineChart from "../charts/LineChart"; export default { components: { LineChart }, data(){ return { chartDataTop: { labels: [ "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", ], datasets: [ { label: "Orders", data: [10, 20, 15, 30, 50, 20, 30, 10, 20, 30], lineTension: 0.6, backgroundColor: "#3E80E1", borderColor: "#3E80E1", pointRadius: 3, }, ], }, chartOptionsTop: { responsive: true, legend: { display: false, }, maintainAspectRatio: false, plugins: { legend: false, datalabels: { display: false, }, }, scales: { x: { grid: { color: "rgba(217,143,7,0.1)", }, }, y: { grid: { display: false, }, }, }, }, chartDataZero: { labels: [ "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", ], datasets: [ { label: "Orders", data: [10, 20, 15, 30, 50, 20, 30, 10, 20, 30], lineTension: 0.6, backgroundColor: "#3E80E1", borderColor: "#3E80E1", pointRadius: 3, }, ], }, chartOptionsZero: { responsive: true, legend: { display: false, }, maintainAspectRatio: false, plugins: { legend: false, datalabels: { display: false, }, }, scales: { x: { grid: { color: "rgba(217,143,7,0.1)", }, }, y: { grid: { display: false, }, }, }, }, chartDataOverview: { labels: [ "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", ], datasets: [ { label: "Orders", data: [10, 20, 15, 30, 50, 20, 30, 10, 20, 30], lineTension: 0.6, backgroundColor: "#3E80E1", borderColor: "#3E80E1", pointRadius: 3, }, ], }, chartOptionsOverview: { responsive: true, legend: { display: false, }, maintainAspectRatio: false, plugins: { legend: false, datalabels: { display: false, }, }, scales: { x: { grid: { color: "rgba(217,143,7,0.1)", }, }, y: { grid: { display: false, }, }, }, }, } } } </script> <style scoped> .chart-box { height: 300px; } </style>
修复方案
1. 统一Props命名规范
原代码中chartID的驼峰命名在Vue props绑定中容易出现匹配问题,将LineChart组件的props改为chartId,父组件中使用:chart-id传递参数,保持与vue-chartjs组件的原生props命名一致。
2. 给图表容器设置固定高度
由于开启了maintainAspectRatio: false,图表容器需要明确高度才能正常渲染,给.chart-box添加高度样式(如上述代码中的height: 300px)。
3. 全局注册ChartJS插件
将ChartJS的插件注册移到项目入口文件main.js中,避免组件重复注册导致的冲突:
// main.js import { Chart as ChartJS, Title, Tooltip, Legend, LineElement, LinearScale, CategoryScale, PointElement } from "chart.js"; ChartJS.register(Title, Tooltip, Legend, LineElement, LinearScale, CategoryScale, PointElement);
同时移除LineChart组件中的注册代码。
4. 监听数据变化强制更新(可选)
如果图表仍不渲染,在LineChart组件中添加watch监听props变化,确保数据更新时图表重绘:
<template> <LineChartGenerator ref="chart" :chart-id="chartId" :chart-options="chartOptions" :chart-data="chartData" /> </template> <script> import { Line as LineChartGenerator } from "vue-chartjs/legacy"; export default { name: "LineChart", components: { LineChartGenerator, }, props: ["chartData", "chartOptions", "chartId"], watch: { chartData: { handler() { this.$nextTick(() => { this.$refs.chart?.update(); }); }, deep: true }, chartOptions: { handler() { this.$nextTick(() => { this.$refs.chart?.update(); }); }, deep: true } }, mounted() { this.$nextTick(() => { this.$refs.chart?.render(); }); } }; </script>
内容的提问来源于stack exchange,提问作者Hamza Afzal
相关产品推荐
相关产品推荐

