zoukankan      html  css  js  c++  java
  • vue 父组件监听子组件生命周期

    一、生命周期

    生命周期是指vue实例从创建到销毁所经历的一系列过程。vue官网生命周期如下图所示:

     上图一共描述了8个生命周期钩子函数,即:

     'beforeCreate',
      'created',
      'beforeMount',
      'mounted',
      'beforeUpdate',
      'updated',
      'beforeDestroy',
      'destroyed',

    思考一个问题,vue实例中一共就这8个生命周期钩子函数吗?

    答案是,vue生命周期钩子函数不止这8个。

    (1)动态组件钩子函数

    vue实例若是动态组件(即keep-alive)时,还有2个钩子函数:

      'activated',
      'deactivated',

    (2)errorCaptured

    errorCaptured是vue 2.5.0版本新增的一个钩子函数,它主要用来捕获一个来自子孙组件的错误,即可以应用在前端监控中。

    结论:vue一共有11个说明周期钩子函数。

    二、父组件如何监听子组件生命周期钩子函数

    1、使用$on和$emit

    子组件$emit触发一个事件,父组件$on监听相应事件。

    // Parent.vue
    <Child @mounted="doSomething"/>
        
    // Child.vue
    mounted() {
      this.$emit("mounted");
    }

    2、hook钩子函数

    使用vue hook生命周期钩子函数。

    //  Parent.vue
    <Child @hook:mounted="doSomething" ></Child>
    
    doSomething() {
       console.log('父组件监听到 mounted 钩子函数 ...');
    },
        
    //  Child.vue
    mounted(){
       console.log('子组件触发 mounted 钩子函数 ...');
    },    
        
    // 以上输出顺序为:
    // 子组件触发 mounted 钩子函数 ...
    // 父组件监听到 mounted 钩子函数 ...     

    下面阐述vue hook生命周期原理:

    (1)vue源码生命周期描述

    vm._self = vm
    initLifecycle(vm) // 初始化生命周期
    initEvents(vm) // 初始化事件
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')

    即生命周期钩子函数(如beforeCreate、created等)都会调用callHook函数。

    (2)callHook函数源码

    export function callHook (vm: Component, hook: string) {
      // #7573 disable dep collection when invoking lifecycle hooks
      pushTarget()
      const handlers = vm.$options[hook] // 选项当中的生命周期函数
      const info = `${hook} hook`
      if (handlers) {
        for (let i = 0, j = handlers.length; i < j; i++) {
          invokeWithErrorHandling(handlers[i], vm, null, vm, info)
        }
      }
      if (vm._hasHookEvent) {
        vm.$emit('hook:' + hook)
      }
      popTarget()
    }

    即每个生命周期钩子函数执行函数为:vm.$emit('hook:' + hook),前提条件是_hasHookEvent值为true

    (3)_hasHookEvent标志位源码

    const hookRE = /^hook:/ // 以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
    }

    当使用了$on方法监听事件时,如果事件名以 hooks: 作为前缀,那么这个事件会被当做hookEvent,注册事件回调的同时,vm._hasHookEvent会被置为true。当使用callHook调用生命周期函数时,由于_hasHookEventtrue,所以会$emit('hooks:xxx'),注册的生命周期函数就会执行。

      三、生命周期钩子函数调用方法汇总

    (1)Vue组件选项中添加钩子函数

    <script>
    export default {
      components: {},
      data () {
        return {
        }
      },
      computed: {
      },
      created () {
    
      },
      mounted () {
    
      },
      beforeDestroy () {}
    }
    </script>

    (2)在模板中添加@hooks:created

    //  Parent.vue
    <Child @hook:mounted="doSomething" ></Child>

    (3)js代码

    vm.$on('hooks:created', cb);
    vm.$once('hooks:created', cb);//只执行一次
  • 相关阅读:
    《30天自制操作系统》06_day_学习笔记
    《30天自制操作系统》05_day_学习笔记
    《30天自制操作系统》04_day_学习笔记
    ugui Event.current.mousePosition获取的坐标原点在左上角
    场景中GameObject无法用代码隐藏问题(setActive为false)
    让camera实现类似cs第一人称视角旋转和位移
    itunesconnect如何提交被决绝过了的相同版本号
    mac下安装libpng环境
    golang实现模拟键盘按键
    cocos2d3.x在android下屏蔽多点触控
  • 原文地址:https://www.cnblogs.com/mengfangui/p/12546866.html
Copyright © 2011-2022 走看看