2019 年 1 月 - 关于此问题答案的警告 - 我在使用此代码添加动态侦听器时发现了一个微妙的问题。
this.$options.beforeDestroy.push(() => {
console.log(txt)
});
当没有定义静态beforeDestroy 时,它可以正常工作。在这种情况下,处理程序数组是$options 的直接属性。
但是如果你在组件上定义一个静态的beforeDestroy钩子,handlers数组是$options.__proto__的属性,这意味着组件的多个实例继承之前实例的动态处理程序(实际上,上面的代码修改了使用的模板创建连续的实例)。
这是一个多大的实际问题,我不确定。它看起来很糟糕,因为当您浏览应用程序时,处理程序数组会变得更大(例如,每次切换页面都会添加一个新函数)。
添加动态处理程序的一种更安全的方法是使用此 injectHook 代码,Vue 使用该代码进行热模块重新加载(您可以在正在运行的 Vue 应用程序的 index.js 中找到它)。注意,我使用的是 Vue CLI 3。
function injectHook(options, name, hook) {
var existing = options[name]
options[name] = existing
? Array.isArray(existing) ? existing.concat(hook) : [existing, hook]
: [hook]
}
...
injectHook(this.$options, 'beforeDestroy', myHandler)
这里发生的是在实例上创建一个新数组,其中包含来自__proto__ 的所有处理程序以及新的处理程序。旧数组仍然存在(未修改),并且新数组与实例一起被销毁,因此__proto__ 处理程序数组中没有处理程序的构建。