You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3结合Laravel Blade模板生产构建失效问题求助

问题:Laravel Blade结合Vue3 SFC构建后页面空白

场景与代码

尝试在Laravel Blade文件中使用Vue3单文件组件(SFC),开发环境功能正常,但生产构建后页面空白。相关代码如下:

Test.vue

<script setup>
import { ref} from 'vue';
const testValue = ref('Works');
</script>

app.blade.php

<head>
    @stack('js')
</head>
<body>
    <div id="app">
        @yield('content')
    </div>
</body>
</html>

test.blade.php

@extends('layouts.app')
@push('js')
    @vite(['resources/js/test.js'])
@endpush
@section('content')
    <span>@{{ testValue }}</span>
@endsection

test.js

import { createApp } from 'vue';
import Test from "./components/Test.vue";
const app = createApp(Test).mount("#app");

vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
        server: {
            hmr: true,
            https: false,
            host: 'localhost',
            proxy: {
                '/app': {
                    target: 'wss://localhost:6001',
                    ws: true
                }
            }
        },
        plugins: [
            laravel(
                {
                    input: [
                        'resources/js/test.js',
                    ],
                    refresh: true,
                }),
            vue({
                template: {
                    transformAssetUrls: {
                        base: null,
                        includeAbsolute: false,
                    },
                },
            }),
        ],
        resolve: {
            alias: {
                'vue': 'vue/dist/vue.esm-bundler.js',
            },
        },
        build: {
            chunkSizeWarningLimit: 1000,
        },
        define: {
            __VUE_PROD_DEVTOOLS__: true,
            __VUE_OPTIONS_API__: true,
        }
    });

问题现象

  • npm run dev 时功能正常,Blade中的Vue插值@{{ testValue }}能正确渲染
  • npm run build 执行后,页面空白,Blade中的模板内容无法加载

原因分析

  1. Vue挂载逻辑覆盖DOM内容:当前用createApp(Test).mount("#app")时,Vue会替换#app元素的全部内容。开发环境下Vite的HMR机制会等待Blade渲染完成后再挂载Vue,所以Blade内容能被保留并解析;但生产构建后,JS文件可能在Blade内容渲染完成前就执行,或者因为Test.vue没有模板内容,Vue挂载后直接清空了#app内的Blade代码。
  2. Test.vue无模板定义:你的Test.vue仅包含逻辑代码,没有<template>部分,Vue无法找到模板,挂载时只能替换掉#app的原有内容。

解决方法

方法1:调整Vue挂载逻辑,保留Blade模板

无需将Test.vue作为根组件,而是创建空根组件挂载到#app,让Vue接管Blade内的模板:

修改test.js:

import { createApp, ref } from 'vue';

const app = createApp({
  setup() {
    const testValue = ref('Works');
    return { testValue };
  }
}).mount("#app");

若要复用Test.vue的逻辑,可将其改为逻辑导出组件:
Test.vue修改为:

<script setup>
import { ref} from 'vue';
export const testValue = ref('Works');
</script>

test.js对应修改:

import { createApp } from 'vue';
import { testValue } from "./components/Test.vue";

const app = createApp({
  setup() {
    return { testValue };
  }
}).mount("#app");

方法2:让Vue复用Blade模板作为根组件模板

修改test.js,手动获取#app内的Blade渲染内容作为模板:

import { createApp, h } from 'vue';
import Test from "./components/Test.vue";

// 获取Blade渲染后的DOM内容
const appEl = document.getElementById('app');
const template = appEl.innerHTML;

// 合并Test组件逻辑与Blade模板
const app = createApp({
  extends: Test,
  render() {
    return h('div', { innerHTML: template });
  }
}).mount("#app");

方法3:确保JS在DOM加载完成后执行

调整app.blade.php,将JS栈移到</body>前,确保Blade内容先渲染:

<head>
</head>
<body>
    <div id="app">
        @yield('content')
    </div>
    @stack('js')
</body>
</html>

同时在test.blade.php中给Vite添加defer属性,延迟JS执行:

@extends('layouts.app')

@section('content')
    <span>@{{ testValue }}</span>
@endsection

@push('js')
    @vite(['resources/js/test.js'], { defer: true })
@endpush

内容的提问来源于stack exchange,提问作者Sc00rpY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:10:29