vue源码浅析之响应式原理

vue源码浅析之响应式原理

第一次写博客。为什么会想写博客呢?在6月十几号的时候,我面试了一家公司,面试以后就和面试官聊了起来,他问我平时怎么学习的,于是我就噼里啪啦说了一大堆(我们当时都应该对对方挺满意的)。他听完以后给了我建议:以后每学习一点新知识点,积累了以后可以尝试写一写博客。因为只是对着教学视频或者书敲代码,过了一段时间你依然会忘记。
很不幸的是,关于vue的响应式原理我大概在今年3月份就已经看过了,并且当时也做了一个类似的东西。可是过了短短的几个月,我现在回想起来好像只能记得它大概的原理,利用Object.defineProperty这个方法来实现。所以我感觉写博客或许真的是有必要的。
不仅可以加深自己印象,还可以把自己踩过的各种坑分享给大家!
这是我看了两家的视频,取其精华展示出来的!
言归正传:
本文讲三点我认为在面试必要的。

  1. vue数据响应式的原理是什么
  2. 如何实现
  3. 面试中应该要怎么回答(在网上看了许多大佬回答,复制一段我认为比较容易理解的)

一、vue数据响应式的原理是什么
1.在vue2.0版本,利用了Object.defineProperty()。这个方法重新定义了对象获取属性(get)和对象设置属性(set)的操作实现。(面试官一般是问这个的)
2.在vue3.0版本,采用了ES6的proxy对象来实现。(这个是用来装逼的,因为我接触的面试官对于这个也好像是一知半解)
二、如何实现?
这个要从最基本的讲起,我们要清楚let a=new Vue()这段代码执行的时候发生了什么?
1.在执行代码vue会调用进行初始化,初始化很多如:生命周期,props,methods,data,computed,watch等等。
2.执行$mount函数:指定一个最终要挂载目标(DOM节点、对象等)。
3.执行compile():它执行了很多事情,但最重要的是对HTML模板进行了扫描,生成渲染函数以及更新函数,之后生成虚拟DOM,通过diff算法来计算出最简单的更新(就是用CPU的时间换取浏览器的时间)。

直接上图吧
在这里插入图片描述
代码实现:
首先创建两个文件myVue.js和index.html
myVue.js

class myVue{
	//构造函数
	constructor(option){//传入数据
		this.$option=option;//缓存
		this.$data=option.data;
		this.observe(this.$data);//调用函数
	}
	observe(value){
		//判断传入的值是否为对象
		if(!value||typeof value!='object'){
			return;
		}
		//遍历对象中的每个属性
		Object.keys(value).forEach(key=>{
			this.defineReactive(value,key,value[key])
		})
	}
	defineReactive(obj,key,val){
		//回调,判断是否是深层次对象
		this.observe(val);
		//响应式的重点:object.defineProperty()
		Object.defineProperty(obj,key,{
			get(){
				return val;
			},
			set(newVal){
				if(newVal==val){
					return;
				}
				val=newVal;
				//当改变时,控制台输出提示
				console.log(`'${key}'updated:${val}`);
			}
		})
	}
}

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="{CHARSET}">
		<title></title>
	</head>
	<body>
	</body>
	<script src="Kvue.js"></script>

	<script>
		const a=new myVue({
			data:{
				text:'i am A',
				func:{
					name:'i get my name'
				}
			}
			})
		a.$data.text='i am b'
		a.$data.func.name='bbbbb';
	</script>
</html>

最后的控制台的输出结果应该为
在这里插入图片描述

以上就是vue2.0版本响应式原理最基础的部分,其实还有两部分:依赖收集追踪以及编译compile
但是面试基本上说出这些应该也没问题了。

最后就要说一说装逼的vue3.0实现的原理proxy。
创建proxy.html

  <!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<h3 id="paragraph"></h3>
			<input type="text" id="input"  />
		</div>
		<script type="text/javascript">
			//获得需要的dom
			const paragraph=document.getElementById('paragraph');
			const input=document.getElementById('input');
			const data={
				text:'hello world'
			}
			const handler={
				set:function(target,prop,value){
					if(prop==='text'){
						//更新视图和值
						target[prop]=value;
						paragraph.innerHTML=value;
						input.value=value;
						return true;
					}else{
						return false;
					}
				}
			}
			//构造 proxy对象
			const myText=new Proxy(data,handler);
			//添加input监听事件
			input.addEventListener('input',function(e){
				myText.text=e.target.value;//更新myText的值
			},false)
			//初始化值
			myText.text=data.text;
		</script>
	</body>
</html>

这个就不上图片了,出来应该是一个输入框和一段文字,会有改变输入框即可改变文字的效果

三、面试中怎么回答
先回答Object.defineProperty,然后如果面试官详细问的时候,可以再详细说。或者简单粗暴一点的直接当面敲代码。
“当你把一个普通的 JavaScript 对象传给 Vue 实例的 data ,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。这里需要注意的问题是浏览器控制台在打印数据对象时 getter/setter 的格式化并不同,所以你可能需要安装 vue-devtools 来获取更加友好的检查接口。
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

总结
其实虽然我刚毕业,但是到目前为止,因为各种好的,坏的原因,面试了大概有20多家公司了(虽然大部分都是小公司,但是成功率还挺高的,骄傲一下!!)。其中很多家公司都有问到过vue数据响应式的原理。其中有两家给了比较深刻的影响,他在问完我vue的数据响应式原理以后,又问我vue的双向绑定的原理。搞的我有点懵,事实上我认为这两个是同一个东西,并且我回来以后查了一下,也确实没有什么区别。

这其实是一件小事,但是我感觉可以从中得到一些启发:面试官他对于自己的面试题其实也并不是全都了解的,并且即使会,也存在很多漏洞。所以当面试官面试一道题目,你刚好做过深入了解的,你就可以在他面前侃侃而谈,比如很多面试官确实不了解vue3.0响应式的原理,这样你就可以给面试官留下稍微深刻的影响。

最后订个小目标
订个小目标:一个月至少写一篇博客。
既然选择了程序员这条道路,那么必将是工作到老,学到老的。尤其是前端,据说以前只要会jquery就可以轻松找到工作,但是现在只是单纯的j会query啥也不是。
人有时候真的会有惰性,很多时候完全不想学习,大学4年,至少三年是这样的。所以我认为监督自己将来持续学习最大的动力,就将自己的目标广而告之,请大家一起监督自己。
从7月6号下午4点半左右开始写的,因为对于这部分知识基本已经,所以又重新学了一遍,现在是7月7号的半夜1点半,去除中间吃饭加散步的两个小时,基本上也写了有6、7个小时了,虽然很累,但是感觉还是有点成就感。
第一次写博客,写的错误或者不好的地方希望请大家指出来,愿与大家一同进步!!!

                                                                             7月7号 1点30分
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值