vue核心模块源码解析

news2024/11/18 9:36:57

响应式原理

  1. Object.defineProperty
  2. setter
  3. Proxy
var count = 1
var state = {}
Object.defineProperty(state , 'count',{
	get(){
		return count
	},
	set(val){
		count = val
	}
})
//弊端:不能主动监听到对象属性的新增或者删除,add/delete
ref和reactive 声明响应式数据
  • ref:用于定义string、number、boolean --> set/get
function ref(value){
	let _value = vlaue
	let count = {
		get value(){
			return _value
		},
		set value(val){
			_value = val
		}	
	}
}
  • reactive:用于复杂数据类型(array、object、Map、Set) --> proxy数据劫持、代理
let proxy = new Proxy(state,{
	get:function(target,prop){
		return target[prop]
	},
	set:function(target,prop,value){
		target[prop] = value
	},
	deletePropety(target,prop){
		delete target[prop]
	}
})
vue文件在浏览器是怎么运行起来的?
  1. react -> jsx渲染函数
  2. vue -> template -> render 函数

模板的本质就是对HTML的增强 :增加了一些指令 v-if 、 {{}}
渲染函数本质就是js,注入了一些context

模板vs渲染函数
1、本质不同
2、表现能力不同,vue语法糖比react多很多
3、vue代码一致性比较弱(实现同一个功能方法路径太多)
4、性能,compiler优化

compiler编译时->

template -> AST抽象语法树 -> render => VNode
script  -> js
style -> less/scss  , scoped  <style></style>

vue3源码结构

在这里插入图片描述

  • compiler-core 编译器核心代码,且与平台无关,这个包主要功能是将代码解析成ast、然后转换成codegenNode对象、再编译生成可执行代码(render渲染函数)在这里插入图片描述
  • compiler-dom 针对浏览器(或DOM环境)的编译器。她在compiler-core基础上添加了一些特定于DOM的特性
  • compiler-sfc 负责处理vue文件,将其分解为模板、脚本、样式等部分,并对这些部分进行相应的处理
  • compiler-ssr 针对服务器渲染(SSR)的编译器。她在compiler-core基础上添加了一些特定与SSR的特性,如生成服务器渲染的代码
  • reactivity 这个是vuejs的响应式系统,提供了一些基础API
  • runtime-core 这是vuejs运行时核心,包括vuejs的主要功能。如响应式系统、组件系统、生命周期钩子等。这个包是平台无关的
  • runtime-dom 这个是针对浏览器(或DOM环境)的运行时。它在@vue/runtime-core的基础上添加了一些特定与DOM的特性
  • server-renderer 服务端渲染相关
  • shared 共享常量、工具函数
  • vue 人口包,整合各个子包
核心结构

在这里插入图片描述

结构之一: reactivity 响应式

在这里插入图片描述

响应式核心

在这里插入图片描述

在这里插入图片描述

手写实现一个简单的响应式
let object = {
	msg : 'hello world',
	age: 18
}
const render = (el)=>{
	el.innerHTML = 'msg:' + object.msg
}
let activeEffect = null
const effect = (fn)=>{
	const effectFn = ()=>{
		fn()
	}
}
effect(render)

//副作用函数集合,用Set数据结构进行管理
var bucket = new Set()

var trackMap = new WeakMap() 
//为什么不使用new Map而是new WeakMap。 new WeakMap数据不能进行枚举,键只能是对象,值可以是任何类型
//在 JavaScript 里,map API 可以通过四个 API 方法共用两个数组(一个存放键,一个存放值)来实现。
//这样在给这种 map 设置值时会同时将键和值添加到这两个数组的末尾。从而使得键和值的索引在两个数组中相对应。当从该 map 取值的时候,需要遍历所有的键,然后使用索引从存储值的数组中检索出相应的值。
//但这样的实现会有两个很大的缺点,首先赋值和搜索操作都是 O(n) 的时间复杂度(n 是键值对的个数),因为这两个操作都需要遍历整个数组来进行匹配。
//另外一个缺点是可能会导致 内存泄漏,因为数组会一直引用着每个键和值。这种引用使得 垃圾回收算法不能回收处理他们,即使没有其他任何引用存在了。
//reactive api返回的响应式对象
function track(target,key){
	const depsMap = trackMap.get(target)
	if(!depsMap){
		// target.set(target,key)
		
		//获取target的key对应的Map
		const targetKeyMap = trackMap.set(target,key)
		//key -> 依赖对象数组
		let detSet = targetKeyMap.get(key)
		//detSet 新增副作用函数
		detSet.add(activeEffect) 
	}
}


const reactiveObject = new Proxy(object,{
	get(target,key){
		// bucket.add(render)
		track(target,key)
		return target[key]
	},
	set(target,key,newvalue){
		target[key] = newvalue
		bucket.forEach(fn=>fn())
	}
})
渲染器
  1. 渲染器初次渲染 createApp().mount()
    在这里插入图片描述

  2. 二次更新:patch函数—dom diff

      1、n1===n2,不更新
      2、n1不存在,n2存在,挂载(mount)n2
      3、n1和n2类型不一样,卸载(unmount)n1,挂载(mount)n2
      4、根据不同的节点类型,调用不同的process函数
      5、有点比较n1和n2的props变化,调用patchProps函数
      6、比较n1和n2的子节点的变化,调用patchChildren函数
         1、patchFlag和dynamicChildren优化
    

在这里插入图片描述

编译器

编译原理:从模板到渲染函数===> 源代码->词法分析->语义分析->AST->transform->目标代码
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1683870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang net/http标准库常用方法(二)

大家好&#xff0c;针对Go语言 net/http 标准库&#xff0c;将梳理的相关知识点分享给大家~~ 围绕 net/http 标准库相关知识点还有许多章节&#xff0c;请大家多多关注。 文章中代码案例只有关键片段&#xff0c;完整代码请查看github仓库&#xff1a;https://github.com/hltfa…

K8S认证|CKA题库+答案| 1. 权限控制RBAC

1、权限控制RBAC 您必须在以下Cluster/Node上完成此考题&#xff1a; Cluster Master node Worker node k8s master …

【云原生】Kubernetes 核心概念

什么是 Kubernetes Kubernetes&#xff0c;从官方网站上可以看到&#xff0c;它是一个工业级的容器编排平台。Kubernetes 这个单词是希腊语&#xff0c;它的中文翻译是“舵手”或者“飞行员”。在一些常见的资料中也会看到“ks”这个词&#xff0c;也就是“k8s”&#xff0c;它…

2024年信息素养大赛图形化编程、Python、算法创真题汇总

2024年信息素养大赛编程赛道初赛&#xff08;Scratch图形化编程、Python、C算法创意&#xff09;已经结束&#xff0c;根据Scratch实验室的了解全国青少年信息素养大赛初赛晋级及初赛成绩内容如下&#xff1a; 1.参赛选手将在 5 个工作日(节假日不计在内)内&#xff0c;通过信…

开源的数据标注工具--Label-Studio

最近在了解构建知识图谱的相关知识&#xff0c;收集了一些数据&#xff0c;对数据进行标注时尝试了下Label-Studio这个工具&#xff0c;它是开源的数据标注工具&#xff0c;个人觉得还是挺好用的。 Label-studio的安装 我是直接在服务器上用pip安装的&#xff0c;命令如下&am…

【刷题篇】位运算

文章目录 1、判定字符是否唯一2、丢失的数字3、两整数之和4、只出现一次的数字 II5、 消失的两个数字 1、判定字符是否唯一 class Solution { public:bool isUnique(string astr) {int nastr.size();if(n>26)//鸽巢原理return false;int bitMap0;for(auto& e : astr){in…

echart 折线图tooltip

运行结果 代码 import { truncate, merge } from lodash; import { getBasePieOptions, getTooltipFormatter } from "*/money/utils";const colorArray [#1F8BFF, #EDBE75, #26E3F0, #AF8FFF, #61DDAA, #FD996A, #8367E0, #1AAF87]export function getLineOptions…

大数据运维学习笔记之Ambari——筑梦之路

原则&#xff1a;分布式存储和分布式计算分开 今天就到这里啦。

以色列人Andi Gutmans开发的php zend

虽然目前php语言不行了【相关的文章前几年已经有人发过】&#xff0c;但这不是重点&#xff0c;重点是zend引擎的东西具有极大的技术价值&#xff0c;负责zend引擎实现的大佬都现在差不多都是40&#xff0c;50岁左右了&#xff0c;从1997&#xff0c;1998&#xff0c;2000到202…

记录centos中操作(查找、结束、批量)进程以及crontab定时写法的知识

环境&#xff1a;vps&#xff0c;centos7&#xff0c;python3。 近期写了个python程序&#xff0c;用青龙面板在centos上运行。程序中有while无限循环&#xff0c;但是我在青龙中设置了定时任务&#xff08;每隔半小时运行一次&#xff09;&#xff0c;于是造成了进程中有多个…

一个用Java编写的屏幕测距工具,包括游戏地图测量功能

该程序提供了一个简单便捷的方式&#xff0c;在屏幕上测量距离&#xff0c;包括游戏地图分析在内。它允许用户准确确定屏幕上两点之间的距离&#xff0c;帮助游戏过程中的战略规划、资源管理和决策制定。 特点&#xff1a; 简单易用的界面&#xff1a;直观的控制使测量距离变得…

C++的红黑树

目录 基本概念 插入结点的颜色 判断性质是否破坏 调整方式 u为g的右孩子 u存在且为红 u存在且为黑 u不存在 结论 红黑树结点定义 代码实现 基本概念 1、红黑树是一种特殊的二叉搜索树&#xff0c;每个结点会增加一个存储位表示结点的颜色&#xff08;红或黑&#x…

如何将老板的游戏机接入阿里云自建K8S跑大模型(下)- 安装nvidia/gpu-operator支持GPU在容器中共享

文章目录 安装nvidia/gpu-operator支持GPU在容器中共享 安装nvidia/gpu-operator支持GPU在容器中共享 安装 nvidia/gpu-operator遇到两个问题&#xff1a; 由于我们都懂的某个原因&#xff0c;导致某些镜像一直现在不成功。 解决办法&#xff0c;准备一个&#x1fa9c;&#…

如何理解kmp的套娃式算法啊?

概念 KMP算法&#xff0c;全称Knuth Morris Pratt算法 。文章大部分内容出自《数据结构与算法之美》 核心思想 假设主串是a&#xff0c;模式串是b 在模式串与主串匹配的过程中&#xff0c;当遇到不可匹配的字符的时候&#xff0c;对已经对比过的字符&#xff0c;是否能找到…

FME学习之旅---day27

我们付出一些成本&#xff0c;时间的或者其他&#xff0c;最终总能收获一些什么。 教程&#xff1a;Excel 入门 查看和检查 Excel 数据 1.读模块读取EXCEL文件 2.对源数据进行预览 Excel Reader 参数 |将 Excel 转换为 CSV 阅读 2020 年和平均值工作表&#xff0c;然后计算降…

运行Android项目时,提示错误: 程序包javax.annotation.processing不存在

今天在运行项目时提示错误: 错误: 程序包javax.annotation.processing不存在 import javax.annotation.processing.Generated; 最后是修改了Android Studio的JDK的路径修改为你安装的JDK路径&#xff0c;完成的修复&#xff1a;

thinkphp 多条件查询 不起作用 = like

不起作用的代码&#xff1a; &#xff08; where([category_id > $item[id]]) 没起作用 &#xff09; 传递参数 $model->where(product_name, like, "%$productName%") 不起作用 public function cateProductPage() {$builder new Builder(new CategoryMod…

基于transformers框架实践Bert系列4-文本相似度

本系列用于Bert模型实践实际场景&#xff0c;分别包括分类器、命名实体识别、选择题、文本摘要等等。&#xff08;关于Bert的结构和详细这里就不做讲解&#xff0c;但了解Bert的基本结构是做实践的基础&#xff0c;因此看本系列之前&#xff0c;最好了解一下transformers和Bert…

利用神经网络学习语言(一)——自然语言处理的基本要素

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch10_rnn/tokenizer.ipynb 本系列文章将深入探讨一种应用广泛的神经…

hcia datacom学习(8):静态NAT、动态NAT、NAPT、Easy IP、NAT server

1.私网地址 在现实环境中&#xff0c;企业、家庭使用的网络是私网地址&#xff08;内网&#xff09;&#xff0c;运营商维护的网络则是公网地址&#xff08;外网&#xff09;。私网地址是在局域网&#xff08;LAN&#xff09;内使用的&#xff0c;因此无法被路由&#xff0c;不…