无需React与@qwikify,如何在QWIK中集成Chart.js?
在Qwik中直接集成Chart.js实现环形图组件的方法
1. 安装依赖
首先安装Chart.js:
npm install chart.js
2. 实现环形图组件
利用Qwik的useRef$获取canvas元素引用,替代document.getElementById,再通过useClientEffect$在客户端初始化图表:
import { component$, useRef$, useClientEffect$ } from '@builder.io/qwik'; import Chart from 'chart.js/auto'; export const DonutChart = component$(() => { // 获取canvas元素的引用 const canvasRef = useRef$<HTMLCanvasElement>(null); useClientEffect$(() => { if (!canvasRef.current) return; // 获取绘图上下文 const ctx = canvasRef.current.getContext('2d'); if (!ctx) return; // 初始化环形图 const chart = new Chart(ctx, { type: 'doughnut', data: { labels: ['数据1', '数据2', '数据3'], datasets: [{ label: '占比统计', data: [35, 45, 20], backgroundColor: ['#E74C3C', '#3498DB', '#2ECC71'], borderWidth: 0, hoverOffset: 5 }] }, options: { responsive: true, maintainAspectRatio: false, cutout: '70%' // 控制环形的空心大小 } }); // 组件卸载时销毁图表,避免内存泄漏 return () => chart.destroy(); }); return ( <div style={{ width: '300px', height: '300px' }}> <canvas ref={canvasRef}></canvas> </div> ); });
核心要点说明
- 获取DOM元素:使用Qwik的
useRef$钩子获取canvas引用,这是框架推荐的DOM元素获取方式,替代原生的document.getElementById - 客户端副作用:
useClientEffect$确保图表初始化代码仅在浏览器端执行,因为Chart.js依赖DOM环境 - 内存管理:在副作用的清理函数中调用
chart.destroy(),防止组件卸载后残留图表实例导致内存泄漏
动态更新数据(可选)
如果需要根据props动态更新图表数据,可以监听props变化并更新图表:
import { component$, useRef$, useClientEffect$, $ } from '@builder.io/qwik'; import Chart from 'chart.js/auto'; export const DonutChart = component$<{ data: number[]; labels: string[] }>((props) => { const canvasRef = useRef$<HTMLCanvasElement>(null); const chartRef = useRef$<Chart | null>(null); useClientEffect$(({ track }) => { track(() => props.data); track(() => props.labels); if (!canvasRef.current) return; const ctx = canvasRef.current.getContext('2d'); if (!ctx) return; if (chartRef.current) { // 更新现有图表数据 chartRef.current.data.labels = props.labels; chartRef.current.data.datasets[0].data = props.data; chartRef.current.update(); } else { // 初始化新图表 chartRef.current = new Chart(ctx, { type: 'doughnut', data: { labels: props.labels, datasets: [{ label: '占比统计', data: props.data, backgroundColor: ['#E74C3C', '#3498DB', '#2ECC71'], borderWidth: 0, hoverOffset: 5 }] }, options: { responsive: true, maintainAspectRatio: false, cutout: '70%' } }); } return () => chartRef.current?.destroy(); }); return ( <div style={{ width: '300px', height: '300px' }}> <canvas ref={canvasRef}></canvas> </div> ); });
内容的提问来源于stack exchange,提问作者FG99
相关产品推荐
相关产品推荐

