JAVASCRIPT
Integrating Chart.js into a Vue 3 Component
Learn to wrap a third-party JavaScript library like Chart.js within a Vue 3 component, managing its lifecycle and data reactivity for dynamic visualizations.
// ChartComponent.vue
<template>
<div>
<canvas ref="chartCanvas"></canvas>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import Chart from 'chart.js/auto'; // Or specific modules like 'chart.js/auto'
const props = defineProps({
chartData: {
type: Object,
required: true,
default: () => ({
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
})
},
chartOptions: {
type: Object,
default: () => ({
responsive: true,
maintainAspectRatio: false
})
},
chartType: {
type: String,
default: 'bar' // bar, line, pie, etc.
}
});
const chartCanvas = ref(null);
let myChart = null;
const createChart = () => {
if (myChart) {
myChart.destroy(); // Destroy existing chart before creating a new one
}
myChart = new Chart(chartCanvas.value, {
type: props.chartType,
data: props.chartData,
options: props.chartOptions
});
};
onMounted(() => {
createChart();
});
onBeforeUnmount(() => {
if (myChart) {
myChart.destroy();
myChart = null;
}
});
// Watch for changes in chartData or chartType to re-render the chart
watch(() => [props.chartData, props.chartType, props.chartOptions], () => {
createChart();
}, { deep: true }); // Deep watch for chartData object changes
</script>
<style scoped>
canvas {
max-width: 600px; /* Example styling */
max-height: 400px;
}
</style>
<!-- Example usage in ParentComponent.vue -->
<template>
<div>
<ChartComponent :chartData="data" :chartType="chartType" />
<button @click="updateChartData">Update Data</button>
<button @click="toggleChartType">Toggle Type</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChartComponent from './ChartComponent.vue';
const data = ref({
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
label: 'Sales',
data: [100, 150, 200, 120, 180, 250, 190],
backgroundColor: 'rgba(75, 192, 192, 0.6)'
}]
});
const chartType = ref('bar');
const updateChartData = () => {
data.value = {
...data.value,
datasets: [{
...data.value.datasets[0],
data: data.value.datasets[0].data.map(d => d + Math.floor(Math.random() * 50) - 25)
}]
};
};
const toggleChartType = () => {
chartType.value = chartType.value === 'bar' ? 'line' : 'bar';
};
</script>
How it works: This snippet illustrates how to integrate a third-party JavaScript library like Chart.js into a Vue 3 component. It uses a `ref` to link to the canvas element, `onMounted` to initialize the chart once the component is in the DOM, and `onBeforeUnmount` to destroy the chart instance to prevent memory leaks. A `watch` listener intelligently recreates the chart whenever `chartData`, `chartType`, or `chartOptions` props change, ensuring the visualization stays reactive and up-to-date with your application's state.