🚀 @mgcloud/vite-plugin-auto-prevent-form-submit
一个 Vite 插件,自动为 Element UI/Plus 的 <el-form> 标签添加 @submit.prevent(Vue 3)或 @submit.native.prevent(Vue 2),防止表单默认提交行为。
✨ 特性
- 🎯 自动处理:无需手动为每个表单添加
@submit.prevent - 🔧 智能识别:自动跳过已有
@submit处理器的表单 - 🚀 高性能:使用正则表达式和缓存的 picomatch 匹配器,处理速度快
- 🎨 灵活配置:支持自定义文件过滤、Vue 版本选择等
- 💪 TypeScript 支持:完整的类型定义
- ⚡ 依赖:仅依赖
picomatch用于 glob 模式匹配
📦 安装
bash
pnpm add -D @mgcloud/vite-plugin-auto-prevent-form-submit🔨 使用
基础用法
在 vite.config.ts 中配置插件:
typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import autoPreventFormSubmit from '@mgcloud/vite-plugin-auto-prevent-form-submit'
export default defineConfig({
plugins: [
vue(),
autoPreventFormSubmit()
]
})Vue 3 示例
转换前:
vue
<template>
<el-form :model="form" :rules="rules">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-form-item>
</el-form>
</template>转换后:
vue
<template>
<el-form :model="form" :rules="rules" @submit.prevent>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-form-item>
</el-form>
</template>Vue 2 示例
typescript
// vite.config.ts
import vue from '@vitejs/plugin-vue2'
import autoPreventFormSubmit from '@mgcloud/vite-plugin-auto-prevent-form-submit'
export default defineConfig({
plugins: [
vue(),
autoPreventFormSubmit({
vueVersion: 2 // 使用 Vue 2 模式
})
]
})转换后:
vue
<template>
<el-form :model="form" :rules="rules" @submit.native.prevent>
<!-- form content -->
</el-form>
</template>⚙️ 配置选项
AutoPreventFormSubmitOptions
typescript
interface AutoPreventFormSubmitOptions {
/**
* Glob 模式匹配要处理的文件
* @default ['**\/*.vue']
*/
include?: string[]
/**
* Glob 模式匹配要排除的文件
* @default []
*/
exclude?: string[]
/**
* 自定义过滤函数,用于判断文件是否需要处理
* 如果提供此函数,将覆盖 include/exclude 配置
* @param id - 文件路径
* @returns true 表示需要处理该文件
*/
filter?: ((id: string) => boolean) | null
/**
* 是否启用插件
* @default true
*/
enabled?: boolean
/**
* Vue 版本(2 或 3)
* - Vue 3: 添加 @submit.prevent
* - Vue 2: 添加 @submit.native.prevent
* @default 3
*/
vueVersion?: 2 | 3
}配置示例
1. 自定义文件匹配
typescript
autoPreventFormSubmit({
include: ['src/**/*.vue', 'components/**/*.vue'],
exclude: ['**/*.spec.vue', '**/*.test.vue', 'src/test/**/*.vue']
})2. 使用自定义过滤函数
typescript
autoPreventFormSubmit({
filter: (id: string) => {
// 只处理 components 和 views 目录,排除 admin 目录
return (id.includes('/components/') || id.includes('/views/')) && !id.includes('/admin/')
}
})3. Vue 2 项目配置
typescript
autoPreventFormSubmit({
vueVersion: 2,
include: ['src/**/*.vue']
})4. 条件启用
typescript
autoPreventFormSubmit({
enabled: process.env.NODE_ENV !== 'production' // 仅在开发环境启用
})🎯 工作原理
- 文件过滤:根据配置的
include/exclude或filter函数判断是否处理文件 - 智能检测:使用正则表达式检测
<el-form>标签 - 跳过已处理:如果表单已有任何
@submit处理器(如@submit、@submit.prevent、@submit.native.prevent等),则跳过 - 添加处理器:
- Vue 3:添加
@submit.prevent - Vue 2:添加
@submit.native.prevent
- Vue 3:添加
- 保留原有属性:转换过程中保留所有原有的表单属性和格式
📝 注意事项
✅ 会被处理的情况
vue
<!-- 基础表单 -->
<el-form :model="form">
...
</el-form>
<!-- 带多个属性的表单 -->
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
...
</el-form>
<!-- 自闭合表单 -->
<el-form :model="form" />
<!-- 多行表单 -->
<el-form
:model="form"
:rules="rules"
ref="formRef"
>
...
</el-form>❌ 不会被处理的情况
vue
<!-- 已有 @submit 处理器 -->
<el-form @submit="handleSubmit">
...
</el-form>
<!-- 已有 @submit.prevent -->
<el-form @submit.prevent>
...
</el-form>
<!-- 已有 @submit.native.prevent -->
<el-form @submit.native.prevent>
...
</el-form>
<!-- 已有任何 @submit 修饰符 -->
<el-form @submit.stop="handleSubmit">
...
</el-form>
<!-- 非 el-form 标签 -->
<el-form-item>
...
</el-form-item>
<el-form-dialog>
...
</el-form-dialog>🚀 性能
- ⚡ 快速处理:使用正则表达式,处理 100 个表单通常在 100ms 内完成
- 🎯 智能跳过:不包含
<el-form>的文件会被快速跳过 - 💾 缓存优化:picomatch 匹配器会被缓存,重复匹配性能更好
- 📦 轻量级:核心代码简洁,不会显著增加构建时间
🤔 为什么需要这个插件?
在使用 Element UI/Plus 开发表单时,如果不阻止表单的默认提交行为,按下回车键会触发页面刷新。通常我们需要手动为每个 <el-form> 添加 @submit.prevent:
vue
<!-- 手动添加,容易遗漏 -->
<el-form @submit.prevent :model="form">
<!-- form content -->
</el-form>这个插件可以:
- ✨ 自动添加,无需手动处理
- 🛡️ 避免遗漏导致的页面刷新问题
- 🎯 智能识别已有处理器,不会重复添加
- 🔧 统一管理,提高代码一致性
🔍 常见问题
Q: 插件会修改已有的 @submit 处理器吗?
A: 不会。插件会检测表单是否已有任何 @submit 相关的处理器,如果有则完全跳过该表单。
Q: 支持 TypeScript 吗?
A: 是的,插件提供了完整的 TypeScript 类型定义。
Q: 会影响构建性能吗?
A: 影响很小。插件使用高效的正则表达式和缓存机制,通常不会显著增加构建时间。
Q: 可以在生产环境禁用吗?
A: 可以,使用 enabled: false 或根据环境变量条件启用:
typescript
autoPreventFormSubmit({
enabled: process.env.NODE_ENV !== 'production'
})Q: 支持 Element Plus 和 Element UI 吗?
A: 是的,两者都支持。插件只处理 <el-form> 标签,与具体的组件库版本无关。
Q: 可以自定义要处理的标签吗?
A: 目前插件专门针对 <el-form> 标签设计。如果需要处理其他标签,可以 fork 项目并修改正则表达式。
