Vue源码学习(八):生命周期调用

vue,源码,学习,生命周期,调用 · 浏览次数 : 12

小编点评

**1.项目目录** ``` /utils/index.js /lifecycle.js /init.js ``` **2.先看 /utils/index.jsexport const HOOKS =[ \"beforeCreated\", \"created\", \"beforeMount\", \"mounted\", \"beforeUpdate\", \"updated\", \"beforeDestory\", \"destroyed\",]//遍历生命周期HOOKS.forEach(hooks=>{ starts[hooks] = mergeHook}) ``` * `HOOKS` 数组中包含各个生命周期回调函数的名字。 * `mergeHook` 函数用于将多个生命周期回调函数合并为一个回调函数。 * `starts` 对象存储每个生命周期回调函数的处理函数。 * `mergeHook` 函数根据回调函数的名称从 `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) //改变生命周期中的指向 } } } ``` * `callHook` 函数用于在生命周期回调函数中调用处理函数。 * `vm` 是生命周期实例。 * `hook` 是生命周期回调函数名称。 * `handlers` 是生命周期回调函数的数组。 * `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中的部分代码) ``` * `initMixin` 函数用于初始化生命周期实例。 * `_init` 方法调用 `beforeCreated`、`created`、`beforeMount`、`mounted`、`beforeUpdate`、`updated`、`beforeDestory` 和 `destroyed` 等生命周期回调函数。 * `callHook` 函数在每个生命周期回调函数中调用 `this` 指向生命周期实例的处理函数。

正文

好家伙,

 

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",

这里还没写完,后面还有一系列的处理

这几个方法后面会加上的

 

 

 

 

 

与Vue源码学习(八):生命周期调用相似的内容:

Vue源码学习(八):生命周期调用

好家伙, Vue源码学习(七):合并生命周期(混入Vue.Mixin) 书接上回,在上一篇中,我们已经实现了合并生命周期 现在,我们要在我们的初始化过程中,注册生命周期 1.项目目录 红框为本篇涉及到的.js文件 2.先来看 /utils/index.js export const HOOKS =[

Vue源码学习(七):合并生命周期(混入Vue.Mixin)

好家伙, 1.使用场景 现在来,来想一下,作为一个使用Vue的开发者,假设现在我们要使用created(),我们会如何使用 1.1. .vue文件中使用 {{ message }}

Vue源码学习(十一):计算属性computed初步学习

好家伙, 1.Computed实现原理 if (opts.computed) { initComputed(vm,opts.computed); } function initComputed(vm, computed) { // 存放计算属性的watcher const watchers = vm

Vue源码学习(一):数据劫持(对象类型)

好家伙,了解一下Vue如何实现数据劫持 1.Vue中data的使用 首先,我得搞清楚这玩意的概念,我们先从vue的使用开始吧 想想看,我们平时是如何使用vue的data部分的? 无非是这两种情况 (你可千万不要带着惊讶的表情说"啊!原来有两种写法的吗") //函数写法 data() { return

Vue源码学习(二):渲染第一步,模板解析

好家伙, 1.去哪了 在正式内容之前,我们来思考一个问题, 当我们使用vue开发页面时,中的内容是如何变成我们网页中的内容的? 它会经历四步: 解析模板:Vue会解析中的内容,识别出其中的指令、插值表达式({{}}),以及其他元素和属性。

Vue源码学习(三):渲染第二步,创建ast语法树

好家伙,书接上回 在上一篇Vue源码学习(二):渲染第一步,模板解析中,我们完成了模板解析 现在我们继续,将模板解析的转换为ast语法树 1.前情提要 代码已开源https://github.com/Fattiger4399/analytic-vue.git手动调试一遍, 胜过我

Vue源码学习(四):渲染第三步,将ast语法树转换为渲染函数

好家伙, Vue源码学习(三):渲染第二步,创建ast语法树, 在上一篇,我们已经成功将 我们的模板 转换为ast语法树 接下来我们继续进行操作 1.方法封装 由于代码太多,为了增加代码的可阅读性 我们先将代码进行封装 index.js import { generate } f

Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考

好家伙, 昨天,在学习vue源码的过程中,看到了这个玩意 嘶,看不太懂,研究一下 1.上下文 这段出现vue模板编译的虚拟node部分 export function renderMixin(Vue) { Vue.prototype._c = function () { //创建标签 return

Vue源码学习(五):渲染第四步,生成虚拟dom并将其转换为真实dom

好家伙, 前情提要: 在上一篇我们已经成功将ast语法树转换为渲染函数 现在我们继续 1.项目目录 代码已开源https://github.com/Fattiger4399/analytic-vue.git手动调试一遍, 胜过我解释给你听一万遍 新增文件:vnode/index.js vnode/p

Vue源码学习(十):关于dep和watcher使用的一些思考

好家伙, 前面想了好久,都没想明白为什么要dep和watcher打配合才能实现数据-视图同步 为什么要多一个依赖管理这样的东西 给每个数据绑个watcher(xxfunction),然后,数据变了,调set,然后调xxfunction,不就行了, 然后今天突然想明白了,不是为什么要这么干,而是必须这