Laravel 9+Inertia.js+Vue3项目JS文件无法运行问题求助
Laravel 9 + Inertia.js + Vue3 第三方JS无法运行的解决方案
问题背景
- 技术栈:Laravel 9 + Inertia.js + Vue.js 3 搭建后台仪表盘
- 异常现象:CSS文件可正常加载,但第三方JS(如jsvectormap)无法运行;切换至纯Laravel+Blade方案时JS功能正常
- 已尝试操作:更换多个付费后台模板、两种JS引入方式(直接写相对路径/使用
URL::asset()),问题未解决
现有代码示例
app.blade.php 文件
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title inertia>{{ config('app.name', 'Laravel') }}</title> <!-- //css --> <link rel="stylesheet" href="assets/css/dashlite.css?ver=3.1.1"> <link id="skin-default" rel="stylesheet" href="assets/css/theme.css?ver=3.1.1"> <!-- //js --> <script src="{{URL::asset('assets/libs/jsvectormap/js/jsvectormap.min.js')}}"></script> <script src="{{URL::asset('assets/libs/jsvectormap/maps/world-merc.js')}}"></script> <script src="{{URL::asset('assets/libs/jsvectormap/maps/us-merc-en.js')}}"></script> <!-- Scripts --> @routes @vite(['resources/js/app.js', "resources/js/Pages/{$page['component']}.vue"]) @inertiaHead </head> <body class="font-sans antialiased"> @inertia </body> </html>
核心原因
Inertia.js 是单页应用架构,页面切换通过前端路由完成,初始加载时引入的第三方JS仅执行一次。后续页面切换时,新渲染的Vue组件无法触发这些JS的初始化逻辑,且可能存在DOM元素未就绪时JS已执行的时序问题。
解决方案
方案1:通过Vite将JS整合到Vue项目(推荐)
迁移第三方JS文件
将assets/libs/jsvectormap目录复制到resources/js/vendor下(无目录则新建)。在app.js中引入JS
修改resources/js/app.js,添加第三方JS的引入:
import '../css/app.css'; import { createApp, h } from 'vue'; import { createInertiaApp } from '@inertiajs/vue3'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m'; // 引入第三方JS import './vendor/jsvectormap/js/jsvectormap.min.js'; import './vendor/jsvectormap/maps/world-merc.js'; import './vendor/jsvectormap/maps/us-merc-en.js'; const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel'; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')), setup({ el, app, props, plugin }) { return createApp({ render: () => h(app, props) }) .use(plugin) .use(ZiggyVue) .mount(el); }, });
- 在Vue组件中初始化插件
在需要使用JS功能的Vue组件中,利用onMounted钩子确保DOM就绪后初始化:
<script setup> import { onMounted } from 'vue'; onMounted(() => { // 初始化jsvectormap示例 if (document.getElementById('world-map')) { new jsVectorMap({ selector: '#world-map', map: 'world_merc', // 其他配置参数... }); } }); </script>
方案2:监听Inertia页面加载事件初始化JS
保留app.blade.php中的JS引入,添加Inertia事件监听,确保每次页面切换后重新初始化:
<!-- 在app.blade.php的末尾(body结束前)添加 --> <script> document.addEventListener('inertia:page-loaded', () => { // 初始化需要的JS组件,示例: const mapElement = document.getElementById('world-map'); if (mapElement) { new jsVectorMap({ selector: '#world-map', map: 'world_merc', // 其他配置... }); } }); </script>
排查要点
- 打开浏览器控制台(F12)查看是否有报错(如变量未定义、文件404)
- 验证
URL::asset()生成的路径是否可直接访问到JS文件 - 确保初始化JS时,目标DOM元素已存在(依赖
onMounted或inertia:page-loaded事件)
内容的提问来源于stack exchange,提问作者Ramu Ramu
相关产品推荐
相关产品推荐

