Vue原始碼學習(八):生命週期呼叫

養肥胖虎發表於2023-09-28

好傢伙,

 

Vue原始碼學習(七):合併生命週期(混入Vue.Mixin)

書接上回,在上一篇中,我們已經實現了合併生命週期

現在,我們要在我們的初始化過程中,註冊生命週期

 

1.專案目錄

 紅框為本篇涉及到的.js檔案

 

2.先來看 /utils/index.js

export const HOOKS =[
    "beforeCreated",
    "created",
    "beforeMount",
    "mounted",
    "beforeUpdate",
    "updated",
    "beforeDestory",
    "destroyed",
]

//遍歷生命週期
HOOKS.forEach(hooks=>{
    starts[hooks] = mergeHook
})

function mergeHook(parentVal,childVal){
    if(childVal){
        if(parentVal){
            //把子元素合併進去
            return parentVal.concat(childVal)
        }else{
            return [childVal] //[a]
        }
    }else{
        return parentVal
    }
}

(此處僅為與hook相關的部分程式碼)

此處,對HOOK進行定義,並將合併方法mergeHook傳給Hook中的starts陣列

 

3.lifecycle.js中

的callHook方法

//生命週期呼叫
export function callHook(vm, hook) {
    // console.log(vm.options,"||this is vm.options")
    console.log(hook,"||this is hook")
    console.log(vm.$options,"||this is vm.$options")
    const handlers = vm.$options[hook]
    if (handlers) {
        for (let i = 0; i < handlers.length; i++) {
            handlers[i].call(this) //改變生命週期中的指向 
        }
    }
}

 

 

 

首先,它會在控制檯輸出 hook 的值,用於除錯目的。

接著,它會從 vm.$options 中獲取與 hook 相對應的處理函式陣列 handlers。

若存在 handlers,它會遍歷 handlers 陣列,並透過 call 方法呼叫每個處理函式。

注意,在呼叫處理函式時,使用了 call 方法改變了 this 指向,確保處理函式在正確的上下文中執行。

 

 

4.呼叫callHook方法

在init.js檔案中

export function initMixin(Vue) {
    Vue.prototype._init = function (options) {
        // console.log(options)
        let vm = this
        //options為
        vm.$options = mergeOptions(Vue.options, options)
        callHook(vm,'beforeCreated')
        //初始化狀態
        initState(vm)
        callHook(vm,'created')

        // 渲染模板 el
        if (vm.$options.el) {
            vm.$mount(vm.$options.el)
        }
    }

(僅為init.js中的部分程式碼)

lifecycle.js檔案

export function mounetComponent(vm, el) {
    //原始碼
    callHook(vm, "beforeMounted")
    //(1)vm._render() 將 render函式變成vnode
    //(2)vm.updata()將vnode變成真實dom
    let updataComponent = () => {
        vm._updata(vm._render())
    }
    new watcher(vm, updataComponent,()=>{},true)
    callHook(vm, "mounted")
}

 

按順序呼叫我們的生命週期函式

你會問,不是還有四個嗎?

"beforeUpdate",
    "updated",
    "beforeDestory",
    "destroyed",

這裡還沒寫完,後面還有一系列的處理

這幾個方法後面會加上的

 

 

 

 

 

相關文章