从 Vue 2 迁移到 Vue 3 后,SVG 动画 endEvent 未触发

SVG animation endEvent not firing after migrating from Vue 2 to Vue 3

我目前正在将一个 vue 2 / Quasar 1 项目迁移到 vue 3 / Quasar 2,我正在努力处理 SVG 动画元素上的事件,该事件似乎不会在新版本中触发... .

<animateTransform
    begin="startAnimation.begin"
    attributeName="transform"
    attributeType="XML"
    type="rotate"
    from="-18 150 380"
    to="0 150 380"
    dur="0.6s"
    repeatCount="1"
    fill="freeze"
    calcMode="spline"
    keySplines="0.3 0.7 0.3 0.7"
    keyTimes="0;1"
    @endEvent="animationEndHandler()"
/>

endEvent 事件 (https://developer.mozilla.org/en-US/docs/Web/API/SVGAnimationElement/endEvent_event) 在旧版本中运行良好,但在新版本中没有任何反应。其他一切都是一样的,我尝试将 animationEndHandler 方法减少为 console.log('hello')

我已经在 Chrome 和 Mac 上的 Safari 中尝试过,并使用 Cordova 为 iOS 构建,所以我相信这不是浏览器问题,因为旧版本可以正常工作在相同的浏览器中。

只是因为我 运行 没有其他尝试,所以我也尝试了以下所有方法...

@endEvent="animationEndHandler"
@endevent="animationEndHandler"
@end-event="animationEndHandler"
@endevent="animationEndHandler()"
@end-event="animationEndHandler()"
v-on:endEvent="animationEndHandler()"
v-on:endEvent="animationEndHandler"
v-on:endevent="animationEndHandler()"
v-on:endevent="animationEndHandler"
v-on:end-event="animationEndHandler()"
v-on:end-event="animationEndHandler"

当我检查 chrome 开发工具中的 <animateTransform> 元素并查看右侧的“事件侦听器”选项卡时,我可以在其中看到“endevent”,而我的 animationEndHandler 在处理程序中引用,但它似乎从未被调用。

如果有人能就为什么这在 Vue 3 下不再有效提供任何建议,我将不胜感激!

我不清楚原因(可能是 Vue 3 错误),但您可以通过声明自己的 custom directive that mimics v-on@ 是 shorthand)来解决它.

比如本地注册一个指令,命名为on2:

export default {
  directives: {
    on2(el, binding) {
      // <div v-on2:foo="bar">  ->  binding = { arg: 'foo', value: this.bar }
      el.addEventListener(binding.arg, binding.value);
    },
  },
}

或者全局注册指令:

createApp(...)
  .directive('on2', (el, binding) => {
    el.addEventListener(binding.arg, binding.value);
  })
  .mount('#app')

并在您的模板中使用它:

<animateTransform v-on2:endEvent="animationEndHandler" />

Vue 3 demo

尝试:endEvent="animationEndHandler()"

运行 同样的问题,我想我知道为什么了。 SVG 元素不使用标准的 addEventListener 方法,而是使用设置的属性。您可以使用标准属性 setter.

进行设置

这里是要演示的 fiddle:https://jsfiddle.net/L5om97dr/1/