在Vue的模板开发中,事件修饰符是提升开发效率的利器,通过简单的@click.stop.prevent链式调用,即可轻松实现事件冒泡阻止和默认行为拦截。但当我们在JSX/TSX环境中开发时,则需要手动处理事件细节。不过通过深入探索Vue的API,我们会发现官方其实提供了解决方案。
传统模板语法与Jsx/Tsx的事件处理差异:
-
模板语法:通过声明式修饰符处理
<button @click.stop.prevent="handleClick">Click</button>
-
JSX/TSX:原始事件对象需要手动处理
<button onClick={(e) => { e.stopPropagation(); e.preventDefault(); // 其余处理逻辑 }} > Click </button>
Vue官方提供了withModifiers
工具函数:
// 类型定义揭示其设计哲学
function withModifiers(
fn: Function,
modifiers: ModifierGuardsKeys[]
): Function
JSX/TSX中使用修饰符:
import { withModifiers } from 'vue'
const TestButton = () => (
<button
// 与模板语法完全等效的事件控制
onClick={withModifiers(handleAnalyticsClick, ['stop', 'prevent', 'once'])}
// 支持键盘修饰符组合
onKeyup={withModifiers(submitForm, ['enter', 'exact']}
>
按钮
</button>
)
诚然这似乎并没有比手动处理冒泡等简洁多少,但是如果封装几个处理不同事件的工具函数,只传入需要处理数据的函数或许也能简单提提效哈哈哈,这个过程中我还发现了 ts 提示enter
和tab
不能被分配给类型VOnModifiers
参照此链接
心下当下一阵窃喜,用了这么多年的vue,终于可以狠狠的给他注入自己的...(bushi),克隆源码仓库搜索了下
withModifiers
关键词,发现他位于packages/runtime-dom/src/directives/vOn.ts中,上面ts报错的根源就是VOnModifiers
类型中的CompatModifiers
类型,可以看到他的按键修饰符中确实没有enter
和tab
而
CompatModifiers
又来自KeyNames
接下来一切就很简单了,在KeyNames中补上对应的字符即可,然后add && commit && push一条龙,一个水灵灵的PR就此诞生,似乎vue的contributors已经在向我招手,从此走向人生巅峰,出任CEO,迎娶白富美,不出意外的话就要出意外了,很快团队成员就review了PR,并回复了我,大概意思就是这个api不应该被修复,大概原因有两个,一个是withModifiers
是私有api不建议使用,二是KeyNames
是用来向后兼容v2的,v3可以使用任意的键名,有点莫名的失落是怎么回事,这个api的使用也是大大方方写在文档渲染函数 & JSX里的,但是也没有办法了
唉,一代天骄的崛起之路就此折戟(bushi...),以上就是这个不知道有没有用的tips的全链路,希望有朝一日能为vue注入自己的(bushi...)
更新
在我的死缠烂打、不懈努力、不甘放弃、百折不挠的精神下,团队成员还是给打上了ready to merge的标签,终于vue还是有了我的形状(bushi...),还是非常高兴的,用了很多年的vue了,第一次有机会可以改一点点非常简单的源码了,🎉~