Jan 2019 - A warning about the answer to this question - I found a subtle problem when using this code to add dynamic listeners.
this.$options.beforeDestroy.push(() => {
console.log(txt)
});
It works ok when there is no static beforeDestroy defined. In this case the handlers array is a direct property of $options.
But if you define a static beforeDestroy hook on the component, the handlers array is property of $options.__proto__, which means multiple instances of the component inherit dynamic handlers of previous instances (effectively, the above code modifies the template used to create successive instances).
How much of a practical problem this is, I'm not sure. It looks bad because the handler array gets bigger as you navigate the app (e.g switching pages adds a new function each time).
A safer way of adding dynamic handlers is to use this injectHook code, which is used by Vue for hot module reload (you can find it in index.js of a running Vue app). Note, I am using 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)
What happens here is a new array is created on the instance which contains all the handlers from __proto__, plus the new one. The old array still exists (unmodified), and the new array is destroyed along with the instance, so there is no build-up of handlers in __proto__ handler array.