mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
fix(directives): [repeat-click] click handler is fired correctly (#8828)
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import sleep from '@element-plus/test-utils/sleep'
|
||||
import RepeatClick from '../repeat-click'
|
||||
|
||||
const handler = vi.fn()
|
||||
let handler: ReturnType<typeof vi.fn>
|
||||
|
||||
const _mount = () =>
|
||||
mount(
|
||||
{
|
||||
setup() {
|
||||
handler = vi.fn()
|
||||
return () => (
|
||||
<div id="block" v-repeat-click={handler}>
|
||||
TEST
|
||||
@@ -25,14 +27,40 @@ const _mount = () =>
|
||||
)
|
||||
|
||||
describe('Directives.vue', () => {
|
||||
test('Click test', async () => {
|
||||
it('click test', async () => {
|
||||
const wrapper = _mount()
|
||||
const block = wrapper.find('#block')
|
||||
|
||||
block.trigger('mousedown')
|
||||
const testTime = 330
|
||||
await sleep(testTime)
|
||||
block.trigger('mouseup')
|
||||
const expectResult = Math.floor(testTime / 100)
|
||||
expect(handler).toHaveBeenCalledTimes(expectResult)
|
||||
await sleep(330)
|
||||
document.dispatchEvent(new MouseEvent('mouseup'))
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('time interval between mousedown and mouseup is slightly less than 100ms', async () => {
|
||||
const wrapper = _mount()
|
||||
const block = wrapper.find('#block')
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
block.trigger('mousedown')
|
||||
await sleep(99)
|
||||
document.dispatchEvent(new MouseEvent('mouseup'))
|
||||
}
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(10)
|
||||
})
|
||||
|
||||
it('time interval between mousedown and mouseup is slightly more than 100ms', async () => {
|
||||
const wrapper = _mount()
|
||||
const block = wrapper.find('#block')
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
block.trigger('mousedown')
|
||||
await sleep(101)
|
||||
document.dispatchEvent(new MouseEvent('mouseup'))
|
||||
}
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(10)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,22 +6,30 @@ import type { DirectiveBinding, ObjectDirective } from 'vue'
|
||||
export default {
|
||||
beforeMount(el: HTMLElement, binding: DirectiveBinding) {
|
||||
let interval = null
|
||||
let startTime: number
|
||||
let isHandlerCalled = false
|
||||
|
||||
const handler = () => binding.value && binding.value()
|
||||
|
||||
const clear = () => {
|
||||
if (Date.now() - startTime < 100) {
|
||||
handler()
|
||||
}
|
||||
clearInterval(interval)
|
||||
interval = null
|
||||
|
||||
if (!isHandlerCalled) {
|
||||
handler()
|
||||
}
|
||||
isHandlerCalled = false
|
||||
}
|
||||
|
||||
on(el, 'mousedown', (e: MouseEvent) => {
|
||||
if ((e as any).button !== 0) return
|
||||
startTime = Date.now()
|
||||
|
||||
once(document as any, 'mouseup', clear)
|
||||
|
||||
clearInterval(interval)
|
||||
interval = setInterval(handler, 100)
|
||||
interval = setInterval(() => {
|
||||
isHandlerCalled = true
|
||||
handler()
|
||||
}, 100)
|
||||
})
|
||||
},
|
||||
} as ObjectDirective
|
||||
|
||||
Reference in New Issue
Block a user