vnode 生命周期事件使用时候出现内存溢出
Version
3.2.26
Reproduction link
Steps to reproduce
将vnode生命周期事件 @vnodeMounted 改为 onVnodeMounted,则会出现内存溢出
What is expected?
事件传递,或者正常触发生命周期事件
What is actually happening?
Uncaught RangeError: Maximum call stack size exceeded
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8082)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
at callWithAsyncErrorHandling (runtime-dom.esm-browser.js:8094)
根据目前对文档的熟悉,我发现所有的@event定义的事件都会被转为onEvent进行事件传递,并且,直接传递onEvent和@event表现是一致的,都能够触发原生事件以及被注册为Vue自定义事件。但是当我将vnode生命周期事件进行更改后则出现了内存溢出
直接传递onEvent和@event表现是一致的,都能够触发原生事件以及被注册为Vue自定义事件
不是这样的,请使用@vnodeMounted,直接使用onVnodeMounted作为prop名字会命中这个特殊逻辑从而导致错误
// onVnodeMounted
if (
!isAsyncWrapperVNode &&
(vnodeHook = props && props.onVnodeMounted)
) {
const scopedInitialVNode = initialVNode
queuePostRenderEffect(
() => invokeVNodeHook(vnodeHook!, parent, scopedInitialVNode),
parentSuspense
)
}
直接使用onVnodeMounted作为prop名字会命中这个特殊逻辑从而导致错误
是的,这里逻辑错误确实是因为这里作为prop名字(测试的时候忘记了:冒号),命中了这个特殊逻辑。 不过我传递onVnodeMounted确实得到的结果和@vnode-mounted是一致的。
<template>
<!-- 这两者结果一致 -->
<custom-component :onVnodeMounted="onVnodeMounted"></custom-component>
<custom-component @vnode-mounted="onVnodeMounted"></custom-component>
<template>
请问这两者区别在哪儿呢?我没有找到相应的代码逻辑。但是确实当onVnodeMounted为非函数时,:onVnodeMounted="onVnodeMounted"
报内存溢出,而@vnode-mounted="onVnodeMounted"
不会报错,只是被忽略了
直接使用onVnodeMounted作为prop名字会命中这个特殊逻辑从而导致错误
是的,这里逻辑错误确实是因为这里作为prop名字(测试的时候忘记了:冒号),命中了这个特殊逻辑。 不过我传递onVnodeMounted确实得到的结果和@vnode-mounted是一致的。
<template> <!-- 这两者结果一致 --> <custom-component :onVnodeMounted="onVnodeMounted"></custom-component> <custom-component @vnode-mounted="onVnodeMounted"></custom-component> <template>
请问这两者区别在哪儿呢?我没有找到相应的代码逻辑。但是确实当onVnodeMounted为非函数时,
:onVnodeMounted="onVnodeMounted"
报内存溢出,而@vnode-mounted="onVnodeMounted"
不会报错,只是被忽略了
这两种方式的底层的指令不同 @vnode-mounted="onVnodeMounted" 这种是 v-on:vnodeMounted="onChildMounted"的缩写 :onVnodeMounted="onVnodeMounted" 是 v-bind:onVnodeMounted="onVnodeMounted"的缩写 而v-bind, v-on是两种指令,一种是绑定数据,一种是监听事件。 https://v3.cn.vuejs.org/guide/template-syntax.html#v-bind-%E7%BC%A9%E5%86%99 https://v3.cn.vuejs.org/guide/events.html#%E7%9B%91%E5%90%AC%E4%BA%8B%E4%BB%B6 https://v3.cn.vuejs.org/guide/component-custom-events.html