Subscribe on changes!

.once event emit repetitive execution bug

avatar
Jun 8th 2021

Version

3.1.1

Reproduction link

https://jsfiddle.net/liyu1988/7pjdktvb/11/

Steps to reproduce

  test('.once', () => {
    const Foo = defineComponent({
      render() {},
      emits: {
        foo: null,
        bar: null
      },
      created() {
        this.$emit('foo')
        this.$emit('foo')
        this.$emit('bar')
        this.$emit('bar')
      }
    })
    const fn = jest.fn()
    const fn2 = jest.fn()
    render(
      h(Foo, {
        onFooOnce: fn,
        onBarOnce: fn2
      }),
      nodeOps.createElement('div')
    )
    document.createElement('#app')
    expect(fn).toHaveBeenCalledTimes(1)
    expect(fn2).toHaveBeenCalledTimes(2) // Should be equal to,this is 2
  })

What is expected?

expect(fn2).toHaveBeenCalledTimes(1)

What is actually happening?

expect(fn2).toHaveBeenCalledTimes(2)


  const onceHandler = props[handlerName   `Once`]
  if (onceHandler) {
    if (!instance.emitted) {
      ;(instance.emitted = {} as Record<string, boolean>)[handlerName] = true
    } else if (instance.emitted[handlerName]) {
      return
    }
   // 初次执行once事件不会有问题,执行不同的once事件,则会重复执行,需要加上 instance.emitted[handlerName] = true
    callWithAsyncErrorHandling(
      onceHandler,
      instance,
      ErrorCodes.COMPONENT_EVENT_HANDLER,
      args
    )
  }