背景
- 目前需求有
input回车事件需求
- 项目背景用的是
tsx
- 想跟模板语法一样简单
@keyup.enter.native="handleSearch"
- 找了很久,最后终于解决了github issues 参考
1、新建工具withEventmodifiers.ts
import { withModifiers, withKeys, capitalize } from 'vue'
function makeMap(
str: string,
expectsLowerCase?: boolean
): (key: string) => boolean {
const map: Record<string, boolean> = Object.create(null)
const list: Array<string> = str.split(',')
for (let i = 0; i < list.length; i++) {
map[list[i]] = true
}
return expectsLowerCase
? (val) => !!map[val.toLowerCase()]
: (val) => !!map[val]
}
const isEventOptionModifier = makeMap('passive,once,capture')
const isNonKeyModifier = makeMap(
'stop,prevent,self,' +
'ctrl,shift,alt,meta,exact,' +
'middle'
)
const maybeKeyModifier = makeMap('left,right')
const isKeyboardEvent = makeMap('onkeyup,onkeydown,onkeypress', true)
export const resolveEventModifiers = ({
eventName,
eventModifiers
}: {
eventName: string
eventModifiers: string[]
}) => {
const keyModifiers: string[] = []
const nonKeyModifiers: string[] = []
const eventOptionModifiers: string[] = []
for (let i = 0; i < eventModifiers.length; i++) {
const eventModifier = eventModifiers[i]
if (isEventOptionModifier(eventModifier)) {
eventOptionModifiers.push(eventModifier)
} else {
if (maybeKeyModifier(eventModifier)) {
if (isKeyboardEvent(eventName)) {
keyModifiers.push(eventModifier)
} else {
nonKeyModifiers.push(eventModifier)
}
} else {
if (isNonKeyModifier(eventModifier)) {
nonKeyModifiers.push(eventModifier)
} else {
keyModifiers.push(eventModifier)
}
}
}
}
return {
keyModifiers,
nonKeyModifiers,
eventOptionModifiers
}
}
export const withEventModifiers = (
eventObject: object,
modifiers: string[]
) => {
const eventName: string = Object.keys(eventObject)[0]
const eventFunction: Function = Object.values(eventObject)[0]
const { eventOptionModifiers, keyModifiers, nonKeyModifiers } =
resolveEventModifiers({
eventName,
eventModifiers: modifiers
})
let outputEventName = eventName
let outputEventFunction = eventFunction
if (nonKeyModifiers.includes('right')) {
outputEventName = 'onContextmenu'
}
if (nonKeyModifiers.includes('middle')) {
outputEventName = 'onMouseup'
}
if (nonKeyModifiers.length > 0) {
outputEventFunction = withModifiers(outputEventFunction, nonKeyModifiers)
}
if (
keyModifiers.length > 0 &&
isKeyboardEvent(eventName)
) {
outputEventFunction = withKeys(outputEventFunction, keyModifiers)
}
if (eventOptionModifiers.length > 0) {
const modifierPostfix = eventOptionModifiers.map(capitalize).join('')
outputEventName = `${outputEventName}${modifierPostfix}`
}
const outputEventObject = {
[outputEventName]: outputEventFunction
}
return outputEventObject
}
2、使用
import withEventModifiers '@/utils/withEventModifiers'
<input
{...withEventModifiers({
onKeyup: () => {
console.log('enter event');
}
}, ['enter']
)}
/>