vue源码一

这篇博客主要探讨Vue.js的源码,从源码下载到学习内容的总结,包括编译过程、关键模块如compiler、core、observer等,以及debug工具的使用。文章提到了Vue封装了许多函数以提高复用性和维护性,并应用了多种设计模式如观察者、状态模式等。此外,还介绍了源码中广泛使用的闭包和标志位,揭示了Vue的内部工作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue源码

运行时报错:

源码下载

参考文章下载:https://blog.csdn.net/qq_36198515/article/details/107935298
参考文章使用:https://blog.csdn.net/weixin_37517329/article/details/121861019

简短总结

参考文章: https://zhuanlan.zhihu.com/learn-vue-source-code

源码学习内容

在这里插入图片描述

├─ src // 主要源码所在位置,核心内容
│ ├─ compiler // 模板编译相关文件,将 template 编译为 render 函数
│ ├─ codegen // 把AST(抽象语法树)转换为Render函数
│ ├─ directives // 生成Render函数之前需要处理的东西
│ ├─ parser // 模板编译成AST
│ ├─ core // Vue核心代码,包括了内置组件、全局API封装、Vue实例化、响应式原理、vdom(虚拟DOM)、工具函数等等。
│ ├─ components // 组件相关属性,包含抽象出来的通用组件 如:Keep-Alive
│ ├─ global-api // Vue全局API,如Vue.use(),Vue.nextTick(),Vue.config()等,包含给Vue构造函数挂载全局方法(静态方法)或属性的代码。 链接:https://012-cn.vuejs.org/api/global-api.html
│ ├─ instance // 实例化相关内容,生命周期、事件等,包含Vue构造函数设计相关的代码
│ ├─ observer // 响应式核心目录,双向数据绑定相关文件。包含数据观测的核心代码
│ ├─ util // 工具方法
│ └─ vdom // 虚拟DOM相关的代码,包含虚拟DOM创建(creation)和打补丁(patching)的代码
│ ├─ platforms // vue.js和平台构建有关的内容 不同平台的不同构建的入口文件也在这里 (Vue.js 是一个跨平台的MVVM框架)
│ ├── web // web端 (渲染,编译,运行时等,包括部分服务端渲染)
│ │ ├── compiler // web端编译相关代码,用来编译模版成render函数basic.js
│ │ ├── entry-compiler.js // vue-template-compiler 包的入口文件
│ │ ├── entry-runtime-with-compiler.js // 独立构建版本的入口,它在 entry-runtime 的基础上添加了模板(template)到render函数的编译器
│ │ ├── entry-runtime.js // 运行时构建的入口,不包含模板(template)到render函数的编译器,所以不支持 template 选项,我们使用vue默认导出的就是这个运行时的版本。
│ │ ├── entry-server-basic-renderer.js // 输出 packages/vue-server-renderer/basic.js 文件
│ │ ├── entry-server-renderer.js // vue-server-renderer 包的入口文件
│ │ ├── runtime // web端运行时相关代码,用于创建Vue实例等
│ │ ├── server // 服务端渲染(ssr)
│ │ └── util // 工具类相关内容
│ └─ weex // 混合运用 weex框架 (一端开发,三端运行: Android、iOS 和 Web 应用) 2016年9月3日~4日 尤雨溪正式宣布以技术顾问的身份加盟阿里巴巴Weex团队, 做Vue和Weex的整合 让Vue的语法能跨三端
│ ├─ server // 服务端渲染相关内容(ssr)
│ ├─ sfc // 转换单文件组件(*.vue)
│ └─ shared // 共享代码 全局共享的方法和常量

debug使用

在这里插入图片描述

  • 图标1:resume script execution - 恢复脚本执行,也就是跳过断点(debugger)继续执行脚本的意思
  • 图标2:step over next function call - 遇到函数,会直接执行完这个函数,进入下一步,不显示具体执行函数的细节。
  • 图标3:step into next function call - 遇到函数,不会直接运行完这个函数,而是进入函数内部,一步一步地执行,显示具体执行函数的细节。
  • 图标4:step out of current function - 利用图标3进入函数内部,我们可以通过此图标功能来执行完函数内部剩下的代码。
  • 图标5:step - 一步一步的来且遇到函数进入,可理解为图标2 图标3 的结合
  • 图标6:deactivate breakpoints - 停用断点,就是debugger不起作用了😉
  • 图标7:don’t pause on exceptions - 不暂停异常,就是取消谷歌浏览器的异常捕获,需要勾选☑️ Pasue on caught exceptions

学习过程

  • 一个组件渲染到页面中的过程包括这几个步骤
    Template ——> AST(抽象语法树) ——> Render ——> VDom(虚拟Dom) ——> 真实的Dom ——> 最终页面
  • Compiler-Runtime 需要编译器(Compiler)把Vue中的模板最终渲染成真实DOM, 也就是上面的整个流程:
    Template ——> AST ——> Render ——> VDom ——> 真实的Dom ——> 最终页面
  • Runtime-only 指定render函数,通常借助webpack的vue-loader工具,在构建时进行了预编译(将.vue文件编译为js),所以只包含运行时的 Vue.js 代码。
    Render ——> VDom ——> 真实的Dom ——> 最终页面

封装了许多函数,为了复用且易维护

有常用的类型判断,类型转换,数据格式转换

function isObject(obj) {    return obj !== null && typeof obj === 'object'}
function isUndef(v) {    return v === undefined || v === null}
function isDef(v) {    return v !== undefined && v !== null}
function toString(val) {    
    return val == null ?    '' :    
    typeof val === 'object' ?    
    JSON.stringify(val, null, 2) :    String(val)
}
function toObject(arr) {    
    var res = {};    
    for (var i = 0; i < arr.length; i++) {        
        if (arr[i]) {
            extend(res, arr[i]);
        }
    }    return res
}

节点操作兼容函数:addClass ,removeClass,createElement,appendChild,removeChild

function addClass(el, cls) {    
    if (!cls || !(cls = cls.trim())) return
    if (el.classList) {        
        if (cls.indexOf(' ') > -1) {
            cls.split(/\s+/).forEach(function(c) { return el.classList.add(c); });
        } else {
            el.classList.add(cls);
        }

    } else {        
       var cur = " " + (el.getAttribute('class') || '') + " ";        
       if (cur.indexOf(' ' + cls + ' ') < 0) {
            el.setAttribute('class', (cur + cls).trim());
       }
    }
}

设计模式

观察者模式、状态模式、节流模式、 参与者模式、备忘录模式、单例模式 装饰者模式、组合继承模式、链模式。

使用很多闭包

1、解析组件模板 使用了闭包作为缓存,为了重复解析

2、cached 函数,一个专门使用闭包 为缓存的函数

3、上面所讲到 的 柯里化所有涉及的函数,makeMap,parthPath,

4、createPatchFunction 当属篇幅最大的使用闭包的函数了,把一堆函数作为闭包,然后返回 一个函数。他最大的作用是 比较更新DOM 节点

使用很多标志位

表明是否已经做了某件事

_isMounted:// dom 是否已经挂载
_isDestroyed // 组件是否已经摧毁
pending //表明更新回调的 setTimeout 已经执行
waiting //是否已经初始化更新队列,在等待新的成员进入对垒
flushing //更新队列是否已经开始逐个更新成员

指明当前东西的身份

isStatic// 是否是静态节点
isComment// 是否是注释节点
isClone:// 是否是克隆节点
isOnce// 是否有v-once 指令(如果有当前指令,会跳过编译)
_isComponent// 是否是组件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值