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

Laravel10+Inertia项目中Vue组件内Select2无法正常工作求助

解决Laravel 10 + Inertia.js + Vue中Select2初始化错误的方案

1. 配置Vite全局注入jQuery

修改vite.config.js,添加jQuery的全局别名和挂载配置,确保Select2能正确识别全局的$和jQuery:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: {
        alias: {
            jquery: 'jquery/dist/jquery.min.js'
        }
    },
    define: {
        'window.jQuery': 'jquery',
        'window.$': 'jquery'
    }
});

2. 调整bootstrap.js的依赖引入顺序

在resources/js/bootstrap.js中先引入jQuery并挂载到全局,再引入Select2的JS和CSS:

import $ from 'jquery';
window.$ = window.jQuery = $;

// 导入Select2核心文件
import 'select2/dist/js/select2.min.js';
import 'select2/dist/css/select2.min.css';

确保app.js中正确导入bootstrap.js:

import './bootstrap';
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';

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);
    },
});

3. 修复Vue Select2组件的初始化逻辑

核心问题是组件挂载时DOM未完全渲染,或Select2实例未正确维护,修改组件代码:

<template>
    <select ref="selectElement" :value="modelValue" @change="handleChange">
        <option v-for="option in options" :key="option.value" :value="option.value">
            {{ option.label }}
        </option>
    </select>
</template>

<script setup>
import { ref, onMounted, watch, onBeforeUnmount, nextTick } from 'vue';

const props = defineProps({
    modelValue: {
        type: [String, Number, Array],
        default: ''
    },
    options: {
        type: Array,
        required: true
    }
});

const emit = defineEmits(['update:modelValue']);

const selectElement = ref(null);
let selectInstance = null;

onMounted(() => {
    // 等待DOM完全渲染后初始化Select2
    nextTick(() => {
        if (selectElement.value && window.$) {
            selectInstance = $(selectElement.value).select2({
                placeholder: '请选择',
                allowClear: true
                // 其他Select2配置项
            });
        }
    });
});

const handleChange = (e) => {
    emit('update:modelValue', e.target.value);
};

// 监听父组件值变化,同步到Select2实例
watch(() => props.modelValue, (newVal) => {
    if (selectInstance) {
        selectInstance.val(newVal).trigger('change');
    }
});

// 组件销毁时清理Select2实例,避免内存泄漏
onBeforeUnmount(() => {
    if (selectInstance) {
        selectInstance.select2('destroy');
    }
});
</script>

4. 重启Vite服务验证

执行命令重启开发服务:

npm run dev

生产环境构建执行:

npm run build

关键注意事项

  • 不要在组件内重复引入jQuery或Select2,避免重复加载冲突
  • 必须用nextTick确保DOM挂载完成后再初始化Select2
  • 组件销毁时手动销毁Select2实例,防止内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:58:18