前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最佳实践:vue2 父组件监听子组件生命周期钩子

最佳实践:vue2 父组件监听子组件生命周期钩子

作者头像
奋飛
发布2021-08-31 16:49:32
1.5K0
发布2021-08-31 16:49:32
举报
文章被收录于专栏:Super 前端Super 前端

HookEvent

源码地址:https://github.com/vuejs/vue/blob/master/src/core/instance/lifecycle.js#L314

代码语言:javascript
复制
export function callHook (vm: Component, hook: string) {
  const handlers = vm.$options[hook]
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      try {
        handlers[i].call(vm)
      } catch (e) {
        handleError(e, vm, `${hook} hook`)
      }
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
}
  • 对外的生命周期函数需要主动捕获其过程发生的错误,避免整个Vue实例生成过程终止
  • 生命周期函数存放位置 const handlers = vm.$options[hook]
  • 可以通过 on 进行监听事件 vm.emit('hook:' + hook)

vm._hasHookEvent

  • 初始化事件相关initEvents函数中赋值为 false
  • 事件注册实例方法 $on 中赋值为 true
  • callHoook函数中判断_hasHookEvent是否为true

源码地址:https://github.com/vuejs/vue/blob/master/src/core/instance/events.js#L52

代码语言:javascript
复制
export function eventsMixin (Vue: Class<Component>) {
  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++) {
        this.$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
}

const hookRE = /^hook:/ 注册事件以 hook: 开头

实现方式

常规方式

子组件修改;

代码语言:javascript
复制
mounted() {
  this.$emit("mounted");
}

父组件中调用:

代码语言:javascript
复制
<Child @mounted="doSomething">Child>

缺点: 需要修改子组件源码,增加相关 $emit 事件

$options方式

通过 refs 获取相关组件实例,然后增加相应的 lifecycle hook

代码语言:javascript
复制
mounted () {
  const HelloWorldVmOption = this.$refs['HelloWorldRef'].$options
  if (!HelloWorldVmOption['updated']) HelloWorldVmOption['updated'] = []
  HelloWorldVmOption['updated'].push(() => {
    ...
  })
}

缺点: 由于 refs 只能在 mounted 及以后的生命周期中获取,因此这种方式只能监听子组件 mounted 以后的 lifecycle hook。

@hook:event

代码语言:javascript
复制
<Child @hook:mounted="doSomething">Child>

在 vue2 中,完美解决!不需要修改源码~~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-12-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HookEvent
    • vm._hasHookEvent
    • 实现方式
      • 常规方式
        • $options方式
          • @hook:event
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档