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
相关产品推荐
相关产品推荐

