如何在Django模板中使用Vue.js 3实现可复用Doughnut图表组件
问题描述
在Django模板中使用Vue.js 3实现可复用的环形图组件,此前简单文本组件能正常渲染视图传递的标题,但修改为图表时遇到报错:
Uncaught TypeError: Failed to resolve module specifier "vue-chartjs". Relative references must start with either "/", "./", or "../".
相关代码如下:
base.html
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script> {% block vue %} {% endblock %}
status.html(初始版本)
{% extends "../base.html" %} {% load static %} <doughnut-plot title={{title}}></doughnut-plot> {% block vue %} <script type="module" src="{% static 'js/status.js' %}"></script> {% endblock %}
status.js
import DoughnutPlot from "./components/doughnut_plot.js" const app_status = Vue.createApp({ components: { DoughnutPlot, } }); app_status.mount("#app_status");
doughnut_plot.js(初始版本)
export default { props: ['title'], template: `<h4>{{title}}</h4>` };
修改后的尝试代码
status.html
{% block vue %} <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <!-- Include Vue Chart.js wrapper --> <script src="https://cdn.jsdelivr.net/npm/vue-chartjs@3"></script> <!-- Include your Vue component script --> <script type="module" src="{% static 'js/components/doughnut_plot.js' %}"></script> <script type="module" src="{% static 'js/status.js' %}"></script> {% endblock %}
doughnut_plot.js
import { Doughnut } from 'vue-chartjs'; export default { extends: Doughnut, props: ['data', 'options'], mounted() { this.renderChart(this.data, this.options); } };
解决方案
报错原因是:你通过CDN引入的是vue-chartjs的UMD全局版本,但组件代码中使用了ES模块的import语法,浏览器无法识别vue-chartjs这种裸模块名称,必须使用相对路径、绝对路径或完整模块URL。
提供两种解决方式:
方式一:使用全局变量适配UMD版本
直接利用CDN引入后暴露的全局VueChartJs对象,无需import:
修改doughnut_plot.js为:
export default { extends: VueChartJs.Doughnut, props: ['data', 'options'], mounted() { this.renderChart(this.data, this.options) } }
同时确保status.html中的脚本引入顺序正确(依赖必须先加载):
{% block vue %} <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue-chartjs@3"></script> <script type="module" src="{% static 'js/components/doughnut_plot.js' %}"></script> <script type="module" src="{% static 'js/status.js' %}"></script> {% endblock %}
方式二:改用ES模块版本的CDN
使用支持ES模块的vue-chartjs CDN链接,并在组件中使用完整模块URL:
- 修改
status.html中的vue-chartjs引入:
{% block vue %} <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script type="module" src="https://cdn.jsdelivr.net/npm/vue-chartjs@3/dist/vue-chartjs.esm.js"></script> <script type="module" src="{% static 'js/components/doughnut_plot.js' %}"></script> <script type="module" src="{% static 'js/status.js' %}"></script> {% endblock %}
- 修改
doughnut_plot.js的导入语句为完整URL:
import { Doughnut } from 'https://cdn.jsdelivr.net/npm/vue-chartjs@3/dist/vue-chartjs.esm.js' export default { extends: Doughnut, props: ['data', 'options'], mounted() { this.renderChart(this.data, this.options) } }
额外注意事项
使用组件时,传递图表数据和配置需要用Vue的绑定语法(前缀:),否则会被解析为字符串而非对象:
<doughnut-plot :data="{ labels: ['已完成', '进行中', '未开始'], datasets: [{ data: [45, 30, 25], backgroundColor: ['#4BC0C0', '#FF6384', '#FFCE56'] }] }" :options="{ responsive: true, maintainAspectRatio: false }" ></doughnut-plot>
内容的提问来源于stack exchange,提问作者kbr85
相关产品推荐
相关产品推荐

