canvas is null 错误主因是 dom 未加载完就执行初始化,需将 script 置于 /body 前或用 domcontentloaded 监听;canvas 必须设 html width/height 属性而非仅 css;data 结构须严格符合 labels+datasets 嵌套格式;重复 new chart() 需先 destroy。

直接用 <script></script> 引入 CDN 就能跑通第一个柱状图,但 80% 的人卡在「页面空白」或「Canvas is null」——问题几乎都出在 DOM 加载时机、<canvas></canvas> 属性设置、或数据结构不匹配上。
为什么 new Chart() 报错 Canvas is null
不是代码写错了,而是 JavaScript 执行时 <canvas id="myChart"></canvas> 还没被浏览器解析出来。常见于把初始化脚本放在 里,或没等 DOM 加载完就调用 document.getElementById()。
- 最稳妥做法:把
<script></script>标签放在前,紧贴页面底部 - 或者显式监听:用
window.addEventListener('DOMContentLoaded', () => { ... })包裹初始化逻辑 - 别用 jQuery 的
$(document).ready()混搭原生 API,容易因加载顺序出错
canvas 宽高必须写 HTML 属性,不能只靠 CSS
<canvas></canvas> 是位图容器,Chart.js 依赖其原生 width 和 height 属性计算像素密度和渲染精度。仅用 style="width:400px;height:200px" 会导致图表模糊、文字锯齿、响应式失效。
- 正确写法:
<canvas id="myChart" width="400" height="200" style="width:400px;height:200px"></canvas> - 响应式场景下,设
responsive: true+maintainAspectRatio: false,同时保留 HTML 属性值(建议设为设计稿基准尺寸,如 600×400) - 动态创建
<canvas></canvas>元素时,记得手动赋值canvas.width = 600和canvas.height = 400,不能只设style
data 结构不对,图表就完全不显示
Chart.js 对 data 的嵌套层级和字段名非常敏感。最典型错误是把数组直接塞进 data.datasets,或漏掉 labels 数组。
-
data必须是对象,含labels(字符串数组)和datasets(对象数组)两个顶层键 -
datasets里每个对象必须有data字段(数值数组),label字段(字符串)可选但强烈建议加 - 颜色字段如
backgroundColor可以是单个值(全柱同色),也可以是数组(每柱不同色),但长度必须与data数组一致 - 示例合法结构:
data: { labels: ['Jan', 'Feb', 'Mar'], datasets: [{ label: 'Sales', data: [12, 19, 7], backgroundColor: ['red', 'blue', 'green'] }] }
重复初始化 new Chart() 导致 Canvas is already in use
这个错误高频出现在 Vue/React 组件重渲染、AJAX 成功回调里反复执行初始化、或手误写了两遍 new Chart()。本质是同一个 <canvas></canvas> 被传给多个 Chart 实例。
- 每次新建前先销毁旧实例:
if (window.myChart) window.myChart.destroy(); - 把实例存到变量里,后续更新用
myChart.data.labels = [...]; myChart.data.datasets[0].data = [...]; myChart.update(); - 在单页应用中,组件卸载时务必调用
chart.destroy(),否则内存泄漏且下次挂载必报错
真正难的不是写第一行 new Chart(),而是理解 <canvas></canvas> 是真实 DOM 元素、Chart.js 是基于它的一次性绘图引擎——所有“刷新”“重绘”“更新”,都得走 .update() 或 .destroy(),而不是重新 new 一个。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











