Laravel7使用Chart.js出现Cannot find element: #app错误怎么解决
问题根因
- Laravel7 默认编译的
app.js内置了Vue实例挂载逻辑,不加defer且脚本放在<head>中时,脚本执行早于DOM渲染,页面还未生成#app元素,因此抛出挂载错误。 - 加
defer后app.js会延迟到DOM解析完成后执行,但如果你将Chart.js打包进了app.js、且统计页面的图表初始化脚本是内联在Blade中的,内联脚本会早于app.js执行,找不到Chart实例导致图表失效;如果你的代码中混用了Blade模板语法和Vue模板语法,加载顺序错误也会导致模板标签无法被正确解析。
可行解决方案
方案1:项目无需使用Vue时(最简方案)
- 修改
resources/js/app.js,删除默认的Vue挂载逻辑,仅保留公共依赖引入:
// 保留bootstrap基础引入 require('./bootstrap'); // 引入Chart.js并挂载到全局window对象,供页面内联脚本直接调用 import Chart from 'chart.js'; window.Chart = Chart; // 删除以下原有Vue相关代码即可 // window.Vue = require('vue'); // const app = new Vue({ // el: '#app', // });
- 修改
resources/views/layouts/app.blade.php中app.js的加载位置,去掉defer属性,将脚本放到</body>闭合标签之前,保证DOM渲染完成后再加载脚本:
<!-- 原有页面内容 --> <script src="{{ asset('js/app.js') }}"></script> </body> </html>
- 统计页面的图表初始化代码直接写在统计视图的底部,此时
Chart已经挂载到全局,可直接调用,不会出现加载冲突。
方案2:项目需要保留Vue功能时
将统计图表逻辑封装为Vue组件,统一由Vue处理加载时序:
- 新建
resources/js/components/StatChart.vue图表组件:
<template> <canvas ref="chartCanvas"></canvas> </template> <script> import Chart from 'chart.js'; export default { // 接收后端传递的统计数据 props: ['commentsStats', 'messagesStats'], mounted() { // 组件挂载完成后再初始化图表,保证DOM节点存在 new Chart(this.$refs.chartCanvas, { type: 'bar', data: { labels: ['1月', '2月', '3月', '4月', '5月', '6月'], datasets: [ { label: '评论数量', data: this.commentsStats }, { label: '消息数量', data: this.messagesStats } ] } // 其余图表配置按需补充 }) } } </script>
- 在
app.js中注册该组件,原有Vue挂载逻辑保留不变:
require('./bootstrap'); window.Vue = require('vue'); // 注册全局统计图表组件 Vue.component('stat-chart', require('./components/StatChart.vue').default); const app = new Vue({ el: '#app', });
- 统计视图中直接调用组件,将控制器返回的统计数据转为JSON格式传递给组件:
<div id="app"> <stat-chart :comments-stats="{{ json_encode($commentsStats) }}" :messages-stats="{{ json_encode($messagesStats) }}" ></stat-chart> </div>
快速排查验证方案
无需修改现有app.js逻辑,直接将Chart.js单独放到public/js目录,在统计视图中单独引入,同时将初始化逻辑包裹在DOM加载完成事件中:
<!-- 单独引入本地Chart.js文件 --> <script src="{{ asset('js/chart.min.js') }}"></script> <script> document.addEventListener('DOMContentLoaded', function() { // 此处写你的图表初始化代码即可 }) </script>
内容的提问来源于stack exchange,提问作者D.D.
相关产品推荐
相关产品推荐

