Bug: e.preventDefault is not a function when clicking upload inside form (v4.18.13)
Bug Report: e.preventDefault is not a function when clicking upload button inside VbenForm
Version: vxe-table 4.18.13
Vue: 3.5.34
Browser: Chrome
Link: https://github.com/x-extends/vxe-table/issues
Description
When clicking an upload button (or any non-input element that triggers form value change) inside a vxe-table form, the following error occurs:
TypeError: e.preventDefault is not a function
at prevent (vendor-vxe.js:3:67059)
at vendor-vxe.js:3:67506
...The prevent function in Ql (event helper object) blindly calls e.preventDefault() without checking whether e is a valid Event object:
Ql = {
stop: e => e.stopPropagation(),
prevent: e => e.preventDefault(), // ← crash here when e is not Event
self: e => e.target === e.currentTarget,
}Reproduction Steps
- Use vxe-table with
useVbenForm(Vben admin form integration) - Add a form field with an upload component (e.g.
CustomPdfDisplayorFileUpload) - Click the upload button to trigger file selection
- The form value change triggers vxe-table's internal event system
prevent()receives a non-Event object → error
Root Cause
The prevent helper in Ql at table/src/table.js line 67059 (compiled) does not guard against non-Event objects:
// Current (unsafe):
prevent: e => e.preventDefault()
// Expected (safe):
prevent: e => e?.preventDefault?.()Or more defensively:
prevent: e => {
if (e && typeof e.preventDefault === 'function') {
e.preventDefault();
}
}Related Code
Located in lib/table/src/table.js around the Ql helper object:
var Ql = {
stop: e => e.stopPropagation(),
prevent: e => e.preventDefault(), // unsafe
self: e => e.target === e.currentTarget,
};This Ql object is used in various event handling contexts (keydownEvent, handleGlobalKeydownEvent, pointerDownOutside, etc.). Some of these callers may pass non-Event objects, especially when the table is embedded in a form system that programmatically triggers value changes.
Suggested Fix
Add a type guard to prevent:
prevent: e => {
if (e && typeof e.preventDefault === 'function') {
e.preventDefault();
}
}This is a safe, backward-compatible change that won't break any existing functionality.
Source: x-extends/vxe-table