Vue源码方向

数据劫持的用法

使用Object.defineProperty(params1,params2,params3)

  1. params1:需要劫持的对象
  2. params2:需要劫持的对象的具体的属性
  3. 劫持后需要写的get、set方法
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Simple HTML Template</title>
	<!-- Add some style to the page -->
	<style>
		body {
			background-color: lightblue;
		}
		h1 {
			color: white;
			text-align: center;
		}
	</style>
</head>
<body>
	<h1>This is a simple HTML template</h1>
	<p>Here's some text to fill the page.</p>
	
	<h1>Vue 双向绑定的原理</h1>
	<input type="text" id="myInput"></input>
	<div> 显示值:<span id="mySpan"></span> </div>

	<!-- Add some functionality to the page with JavaScript -->
	<script>
		// Vue 双向绑定的原理,丐版。即(数据劫持)
		let obj = {};
		// defineProperty() 需要三个参数:1.需要劫持的对象;2.劫持对象的具体属性;3.劫持后的get、set方法
		Object.defineProperty(obj,'username',{
		     get(){
			    console.log('执行了get方法')
			 },
			 set(val){
			     console.log('执行了set方法',val)
				 document.getElementById("mySpan").innerText = val
			 }
		})
		
		document.getElementById("myInput").addEventListener("keyup",function(){
		   // event是当前的事件,即keyup方法
		   obj.username = event.target.value
		})
	</script>
</body>
</html>

数据响应式的原理:数据劫持 + 发布-订阅模式

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Simple HTML Template</title>
	<!-- Add some style to the page -->
	<style>
		body {
			background-color: lightblue;
		}
		h1 {
			color: white;
			text-align: center;
		}
	</style>
</head>
<body>
	<h1>This is a simple HTML template</h1>
	<p>Here's some text to fill the page.</p>
	
	<h1>Vue 响应式的原理</h1>
	<div> 响应式的值 <span class="mySpan2"></span></div>
	<!-- Add some functionality to the page with JavaScript -->
	<script>
		// Vue 相应式原理,丐版。本质是使用  发布-订阅模式 + 数据劫持 = 响应式
		
		// 发布-订阅模式
		class myWatcher{
		   constructor(){
		      this.message = {};
		   }
		   
		   on(key,fn){
		      if(!this.message[key]){
			     this.message[key] = [];
			  }
			  this.message[key].push(fn);
		   }
		   
		   off(key,fn){
		      if (!this.message[key]){
					return;
			  } 
              if (!fn) { 
					this.message[key] = undefined;
			   }
			   
			   this.message[key] = this.message[key].filter((item) => item !== fn);
		   }
		   
		   emit(key,...args){
		      this.message[key].forEach(item=>{
					item.apply(this,[...args]);
				})
		   }
		}	
			
		// 实现响应式    mydataObj:数据    mytag: 劫持数据具体的值      myWatcherKey:发布订阅模式用      myselector:选择器
		const myw2 = new myWatcher();
		function mvvmLow({mydataObj, mytag , myWatcherKey, myselector}){
		
		     let value = "";
			 el = document.querySelector(myselector);
			 
			 Object.defineProperty(mydataObj,mytag,{
				get(){
					return value
				},
				set(val){
					value = val;
					// 使用发布订阅模式,当执行到set方法以后,发布消息,当页面接收到消息后,会改变值
					myw2.emit(myWatcherKey,val);
				}
			})

			myw2.on(myWatcherKey, function changeHandler(val){
			    el.innerText =  val
			});
		}
		
		
		var mydataObj = {};
		let mytag = 'username';
		let myWatcherKey = 'changeMethods';
		let myselector = '.mySpan2';
		// 执行这个的时候,会把'myw2.on'先给添加到'message'队列里面。
		mvvmLow({mydataObj, mytag , myWatcherKey, myselector})
		// 修改后,通过劫持,执行'myw2.emit',通过'myw2.emit'里面的逻辑,执行'myw2.on',注册进去的方法。
		mydataObj.username = 22222
		setTimeout(()=>{
				mydataObj.username = 3333333
	    },2000)
	</script>
</body>
</html>

Vue 代码层面的优化

  1. object.freeze() 不让数据双向绑定,性能提升。比如渲染10万条数据的时候,vue会给这10万条数据加上get、set。使用freeze以后,这10万条数据的get、set就不用加了。提升了性能
  2. 为了优化css性能,可以尽量把css封装到common.css中,尽量不使用页面的<style scoped></style>,影响css渲染性能。
  3. 大型项目页面缓存。使用<keep-alive>进行缓存,但是不能全部都缓存,如果有1000个页面的话,内存就卡爆炸了。推荐使用<keep-alive include>,进行部分缓存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值