继上回 Vue 的初体验之后,这一回上了 Vue 的钩。

这里说的“钩”是指 Vue 的生命周期钩子。Vue 实例在创建的时候会有一系列初始化的步骤——建立数据观察、编译模板、创建必要的数据绑定等等。在实例创建的过程中会触发一些生命周期钩子,让自定义的逻辑可以运行。例如 created 钩子会在实例创建之后调用:

var vm = new vue({
  data: {
    obj: 'Tay',
  },
  created: function () {
    console.log('Mars loves ' + this.obj); // this 指向 vm 实例
  },
})

// Mars loves Tay

Vue 还有其它钩子,它们会在实例生命周期的不同阶段调用。Vue 的生命周期如下:

Life Cycle

Vue 的钩子用法如下:

  • init:在实例初始化时同步调用。此时 Observe DataEventsWatcher 都没有初始化
  • created:在实例创建之后同步调用。此时实例已经解析完毕,意味着已经建立 Data Binding、计算属性、方法和 Watcher。但是还没有开始 DOM 编译,$el 还不存在
  • beforeCompile:在 DOM 编译开始前调用
  • compiled:在 DOM 编译结束后调用。此时所有的指令已经生效,意味着数据的更新将会触发 DOM 的更新。但是不担保 $el 已插入 DOM
  • ready:在 DOM 编译结束和 $el 第一次插入 DOM 之后调用(例如在第一次 attached 钩子之后调用)。注意必须是由实例方法(例如 vm.$appendTo())插入才能触发 ready 钩子
  • attached:在 $el 插入 DOM 的时候调用。注意必须是由指令或实例方法插入,直接操作 $el 不会触发这个钩子
  • detached:在 $el 从 DOM 中删除的时候调用。注意必须是由指令或实例方法删除,直接操作 $el 不会触发这个钩子
  • beforeDestroy:在开始销毁实例的时候调用。此时实例仍然有功能
  • destroyed:在实例被销毁之后调用。此时所有的绑定和实例的指令已经解绑,所有的子实例也已经被销毁。如果有离开过渡,destroyed 钩子将在过渡之后调用

在了解 Vue 的钩子之后,是不是觉得 Vue 很强大。那问题来了:钩子从何而来?

钩子来源于 windows(在 linux 和 Mac OS 如日中天的年代里,是不是觉得 windows 瞬间逼格十足了)。它是 windows 消息处理机制的一部分,通过安装各种钩子, 应用程序能够设置相应的子例程(子程序)来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。

钩子实际上是一个处理消息的程序段(例如 Vue.init),通过系统(例如 Chrome)调用,把它挂入系统。每当特定的消息(Data)发出,在没有到达目的窗口(View)前,钩子程序(vm.init)就先捕获这消息,亦即钩子函数先得到控制权(此时 BrowserProcesscaller 将唤醒 vm.init 服务)。这时钩子函数即可以加工处理(改变)该消息(执行 vm.init),也可以不作处理而继续传递该消息(进入到 Vue 生命周期的下一个阶段),还可以强制结束消息的传递(执行 Vue.destroyed)。

到这里我们对 Vue 生命周期钩子的工作原理已经一清二楚了。最后我们再来了解一下原始的 Hook 原理。

每一个 Hook 都有一个与之相关联的指针列表——HookList,由系统来维护。这个列表的指针指向指定的、应用程序定义的、被 Hook 子程调用的回调函数,也就是该钩子的各个处理子程。当与指定的 Hook 类型关联的消息发生时,系统就把这个消息传递到 Hook 子程。一些 Hook 子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个 Hook 子程或者目的窗口。最新安装的钩子放在 HookList->head,而最早安装的钩子放在 HookList->tail,也就是后加入的先获得控制权。

Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个 HookList。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。

钩子子程是一个应用程序定义的回调函数(Callback Function),不能定义成某个类的成员函数,只能定义为普通的 C 函数。用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可以是系统中所有线程的事件。

钩子让复杂的消息传播成为了可能,它让多方消息传播得以稳定进行,并保证了通信平台的稳定性。Evan You 确实慧中秀外,期待 Vue 的演 进,也期待更多的精品。