
本文介绍在 Vue 2 中为原生 绑定双向数据与变更事件的正确方式,解决因使用 Select2 插件导致原生 @change 失效的问题,并提供可直接运行的集成方案。
本文介绍在 vue 2 中为原生 `
在 Vue.js(尤其是 Vue 2)中,为多选下拉框(<select multiple></select>)绑定变更响应逻辑时,不能依赖原生 DOM 事件监听器(如 addEventListener('change', ...))或 jQuery 的 .on('change', ...),尤其当该元素已被第三方插件(如 Select2)接管 DOM 行为时——Select2 会隐藏原生 <select></select> 并渲染自定义 UI,导致原生事件无法触发。
✅ 正确做法是:放弃对 Select2 实例的手动事件监听,转而利用 Vue 的响应式系统 + v-model + @change 原生指令,但前提是 <select></select> 必须由 Vue 完全控制其渲染与状态。这意味着你需要:
-
移除 Select2 对目标
<select></select>的初始化(避免 DOM 接管冲突); -
使用
v-model绑定一个数组数据(Vue 自动处理多选值同步); -
通过
@change触发自定义方法,获取最新选中项并执行业务逻辑。
以下是完整、可落地的改造步骤:
✅ 步骤 1:更新 HTML 模板(关键修改)
确保 <option></option> 具有 :value 绑定(推荐用唯一 ID),并添加 v-model 与 @change:
<select id="invitees_list1" class="form-select" multiple name="multi" v-model="selectedInviteeIds">
@foreach ($seatedTable->invitees as $invitee)
<option :value="{{ $invitee['id'] }}">
{{ $invitee['name'] }}
</option>
@endforeach
</select>
⚠️ 注意:
v-model绑定的selectedInviteeIds必须是Array类型(如[]),否则 Vue 无法正确同步多选值。
✅ 步骤 2:在 Vue 实例中声明数据与方法
const app = new Vue({
el: '#filtersContainer',
data: {
// ...其他已有字段
selectedInviteeIds: [] // ← 必须初始化为空数组!
},
methods: {
handleMultiSelectChange() {
console.log('当前选中的邀请人 ID 列表:', this.selectedInviteeIds);
// ✅ 示例:发起异步请求,提交选中结果
if (this.selectedInviteeIds.length > 0) {
axios.post(this.assignTableRoute, {
table_id: this.selectedTableInfo?.id,
invitee_ids: this.selectedInviteeIds
})
.then(res => {
if (res.data.status) {
this.$message.success('分配成功!');
}
})
.catch(err => {
console.error('分配失败:', err);
this.$message.error('分配失败,请重试');
});
}
}
},
mounted() {
// ❌ 移除这一行!避免 Select2 接管 #invitees_list1
// $('#invitees_list1').select2();
// ✅ 保留其他未冲突的 Select2 初始化(如 #name_filter 等)
$("#name_filter").select2();
$('#side_filter').select2();
$('#caller_filter').select2();
$('#relation_filter').select2();
// $('#invitees_list1').select2(); ← 删除此项
}
});
⚠️ 重要注意事项
-
不要混用 Select2 和
v-model:Select2 会破坏 Vue 对<select></select>的响应式追踪。若 UI 必须使用 Select2 风格,请改用专为 Vue 设计的组件(如vue-select)。 -
v-model数组必须深响应:确保selectedInviteeIds是响应式数组(Vue 2 中通过data()返回即可,无需额外Vue.set)。 -
服务端接收格式:Laravel 后端需接收
invitee_ids[]形式数组(如request()->get('invitee_ids')自动解析为数组)。 -
调试技巧:在
handleMultiSelectChange中console.log(this.$data)可验证selectedInviteeIds是否实时更新。
✅ 替代方案(如必须保留 Select2)
若 UI 强制要求 Select2 样式且无法替换,可监听 Select2 的自定义事件:
mounted() {
// ...其他初始化
$('#invitees_list1').select2().on('change', (e) => {
// e.val() 返回字符串数组(即使 value 是数字,也转为字符串)
const ids = e.val().map(id => parseInt(id, 10));
this.selectedInviteeIds = ids;
this.handleMultiSelectChange(); // 手动调用业务逻辑
});
}
但此方式绕过 Vue 响应式,需手动同步数据,不推荐作为首选方案。
综上,拥抱 Vue 的数据驱动范式,用 v-model + @change 替代 DOM 事件监听,是简洁、可靠、可维护的最佳实践。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











