vuejs/vue

Please explain that "hook:<>" events exist and they allow to subscribe to the Vue component lifecycle events

WillAvudim opened this issue · 2 comments

What problem does this feature solve?

I've just recently learned from the 3rd sources that

vue_component.$once('hook:beforeDestroy', function () { ... } )

can be used to subscribe to the lifecycle events of individual components.

In my case this is very convenient, it enables me to automatically shut down the no longer necessary websocket connection that is used to receive real-time updates on a certain page of my SPA.

Would it be possible to mention this great fact in the official documentation? I couldn't find any reference to it anywhere. There are several mentioning of the word hook in the documentation and they all seem to connote some other unrelated things.

What does the proposed API look like?

A documentation enhancement.

It' true. Well i have finded that on code (core/instance/events.js):

const hookRE = /^hook:/
  Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
    const vm: Component = this
    if (Array.isArray(event)) {
      for (let i = 0, l = event.length; i < l; i++) {
        vm.$on(event[i], fn)
      }
    } else {
      (vm._events[event] || (vm._events[event] = [])).push(fn)
      // optimize hook:event cost by using a boolean flag marked at registration
      // instead of a hash lookup
      if (hookRE.test(event)) {
        vm._hasHookEvent = true
      }
    }
    return vm
  }

  Vue.prototype.$once = function (event: string, fn: Function): Component {
    const vm: Component = this
    function on () {
      vm.$off(event, on)
      fn.apply(vm, arguments)
    }
    on.fn = fn
    vm.$on(event, on)
    return vm
  }

Then i can use hook: with $on or $once. I can put a simple string or use a array with Array.isArray(event) like:

this.$on([ 'hook:mounted' , 'hook:beforeDestroy' ], () => {
  console.log('hi')
})

and when i print the hooks i have finded:

export function callHook (vm: Component, hook: string) {
  // #7573 disable dep collection when invoking lifecycle hooks
  console.log('[hook]:', hook)
  • [hook]: beforeUpdate
  • [hook]: updated
  • [hook]: beforeCreate
  • [hook]: created
  • [hook]: beforeMount
  • [hook]: mounted
  • [hook]: beforeDestroy
  • [hook]: destroyed

but truly i finded tests just to:

this.$on('hook:created', created)
this.$on('hook:mounted', mounted)
this.$on('hook:destroyed', destroyed)
posva commented

I'm not sure if this hasn't been documented because it's not considered public API. In any case, it should be in Vuejs/vuejs.org repo. I couldn't find any open issue there