• Vue生命周期以及父子组件加载顺序


    lifecycle

    初始化 - beforeCreate & created

    注意:beforeCreate & created 并没有渲染 DOM,不能够访问 DOM。如果组件在加载的时候需要和后端有交互,如果是需要访问 propsdata 等数据的话,就需要使用 created 钩子函数。

    /**
    * 
    * vue2.6.X源码地址src/core/instance/init.js
    * beforeCreate 和 created 函数都是在实例化 Vue 的阶段,在 _init 方法中执行的。
    *
    **/
    
    Vue.prototype._init = function (options?: Object) {
        vm._self = vm
        initLifecycle(vm)   // 初始化生命周期相关的属性、相关属性赋值
        initEvents(vm)      // 初始化事件队列以及监听器
        
        // 通过defineProperty的set去notify()通知subscribers有值被修改,并执行watchers的update函数
        // attrs/$listeners的响应化
        initRender(vm)      
        callHook(vm, 'beforeCreate')
        
        initInjections(vm)  // resolve injections before data/props
        initState(vm)       // initState 的作用是初始化 props、data、methods、watch、computed 等属性
        initProvide(vm)     // resolve provide after data/props
        callHook(vm, 'created')
    }
    
    beforeCreate() {
        this.$data      // undefined
        this.$el        // undefined
        this.$computed  // undefined
        this.$methods   // undefined
    }
        
    created() {
        this.$data      // {__ob__: Observer}
        this.$el        // undefined
        this.$computed  // 可以访问到计算属性
        this.$methods   // 可以访问到methods中的方法
    }   
    

    挂载 - beforeMount & mounted

    /**
    *
    * vue2.6.X源码地址src/core/instance/lifecycle.js
    * beforeMount 钩子函数发生在 mount,也就是 DOM 挂载之前,它的调用时机是在 mountComponent 函数中
    *
    **/
    export function mountComponent (
      vm: Component,
      el: ?Element,
      hydrating?: boolean
    ): Component {
      vm.$el = el
      // ...
      callHook(vm, 'beforeMount')
    
      let updateComponent
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
        updateComponent = () => {
          const name = vm._name
          const id = vm._uid
          const startTag = `vue-perf-start:${id}`
          const endTag = `vue-perf-end:${id}`
    
          mark(startTag)
          const vnode = vm._render()
          mark(endTag)
          measure(`vue ${name} render`, startTag, endTag)
    
          mark(startTag)
          vm._update(vnode, hydrating)
          mark(endTag)
          measure(`vue ${name} patch`, startTag, endTag)
        }
      } else {
        updateComponent = () => {
          vm._update(vm._render(), hydrating)
        }
      }
    
      // we set this to vm._watcher inside the watcher's constructor
      // since the watcher's initial patch may call $forceUpdate (e.g. inside child
      // component's mounted hook), which relies on vm._watcher being already defined
      new Watcher(vm, updateComponent, noop, {
        before () {
          if (vm._isMounted) {
            callHook(vm, 'beforeUpdate')
          }
        }
      }, true /* isRenderWatcher */)
      hydrating = false
    
      // manually mounted instance, call mounted on self
      // mounted is called for render-created child components in its inserted hook
      if (vm.$vnode == null) {
        vm._isMounted = true
        callHook(vm, 'mounted')
      }
      return vm
    }
    
    // 在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数。
    beforeMount{
        this.$data      // {__ob__: Observer}
        this.$el        // undefined
        this.$computed  // 可以访问到计算属性
        this.$methods   // 可以访问到methods中的方法
    }
    
    // 实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。    
    mounted() {
        this.$data      // {__ob__: Observer}
        this.$el        // <div id="app"></div>
        this.$computed  // 可以访问到计算属性
        this.$methods   // 可以访问到methods中的方法
    }  
    

    更新 - beforeUpdate & updated

    /**
    * 
    * vue2.6.X源码地址src/core/observer/scheduler.js
    * update 的执行时机是在flushSchedulerQueue 函数调用的时候
    *
    **/
    

    beforeUpdate

    Vue具有响应式原理 即能够监测到数据的变化

    当视图层的数据即将被更新前,就会触发这个生命周期,这个阶段主要可以用在得知哪个组件即将发生数据改动,并且可以移除对其绑定的事件监听器。

    updated

    此阶段已经重新渲染完成数据更新后的状态,并且要注意在此期间更改状态,如果要更改官方建议使用computedwatch来进行数据更改。

    beforeUpdate与updated的区别

    beforeUpdate如上面所说,是在视图层数据更新前进行的操作,

    mounted触发数据更新后,在beforeUpdate中对数据进行操作,此时视图还未更新,所以对数据进行更改后不会再次触发beforeUpdate

    销毁 - beforeDestroy & destroyed

    beforeDestroy

    当组件销毁前会进行的操作,在这里可以注销监听事件

    destroyed

    绑定的watcherchild components以及event listeners等等已经与原本元素毫无关联了,但是父组件已经渲染在 DOM 上的视图仍然会保留在页面上,只有子组件会完全消失。

    特殊钩子函数 - activated、deactivated

    如果存在使用了keep-alive的组件,会触发activated、deactivated。

    activated:当使用keep-alive的组件渲染时触发。

    deactivated:当使用keep-alive的组件销毁时会触发。

    Vue父子组件的执行顺序

    加载渲染时

    父组件 beforeCreate
    父组件 beforeCreate
    父组件 created
    父组件 beforeMount
    子组件 beforeCreate
    子组件 created
    子组件 beforeMount
    子组件 mounted
    父组件 mounted

    更新时

    父组件 beforeUpdate
    子组件 beforeUpdate
    子组件 updated
    父组件 updated

    销毁时

    父组件 beforeDestroy
    子组件 beforeDestroy
    子组件 destroyed
    父组件 destoryed

    参考链接

    Vue.js 生命周期 https://ustbhuangyi.github.io/vue-analysis/v2/components/lifecycle.html#beforeupdate-updated

    Vue源码解析 https://blog.csdn.net/qq_46299172/article/details/107657663?spm=1001.2014.3001.5502

    Vue生命周期及父子组件生命周期的加载顺序 https://www.cnblogs.com/yyy0926/p/15654272.html

  • 相关阅读:
    LeetCode -- 最大连续乘积子序列
    openCV 和GDI画线效率对照
    java并发编程之CountDownLatch
    约瑟夫环问题
    (hdu step 7.2.1)The Euler function(欧拉函数模板题——求phi[a]到phi[b]的和)
    群“模”乱舞之简单工厂模式
    在iPad iOS8环境下打开相冊或者拍照
    js斐波那契数列求和
    cocos2d-x 显示触摸操作(显示水波点击效果,用于视频演示)
    DOM基础及DOM操作HTML
  • 原文地址:https://www.cnblogs.com/Scooby/p/16247750.html
Copyright © 2020-2023  润新知