Vue2.X和Vue3.0数据响应原理变化的区别
defineProperty定义对象的属性,只不过属性里的get和set实现了响应式。
常用:
- value属性值
- get
- set
- writeable是否可写
- enumrable可遍历
Vue2.X数据响应原理
创建页面,实现延时2s修改对象的值。
LearnVue3.0
defineProperty实现:
functionvue(){
this.$data={
a:1
};
this.el=document.getElementById('app');
this._html="";
this.observe(this.$data);
this.render();
}
vue.prototype.observe=function(obj){
letself=this;
letvalue;
for(letkeyinobj){
value=obj[key];
if(typeofvalue==='object'){
this.observe(value);
}else{
Object.defineProperty(this.$data,key,{
get:function(){
returnvalue;
},
set:function(newvalue){
value=newvalue;
self.render()
}
})
}
}
}
vue.prototype.render=function(){
this._html="Iam"+this.$data.a;
this.el.innerHTML=this._html;
}
在Chrome中console运行,结果页面显示:Iam444
针对数组特性化处理:
letarraypro=Array.prototype;
//为什么要create再次创建对象,create是深拷贝,不影响之前的arraypro
letarrayob=Object.create(arraypro);
//定义哪些方法触发更新
letarr=["push","pop","shift"];
//arr里的方法,既能保持原有方法,又能触发更新
//装饰者模式
arr.forEach(function(method,index){
//对自己的push方法重写
arrayob[method]=function(){
letret=arraypro[method].apply(this,arguments);
//self.render();
console.log('检测到数组变化,触发更新');
returnret;
}
});
在Chrome中console运行示例:
letarr=[]; arr.__proto__=arrayob; arr.push(1);
结果显示:
Vue3.0数据响应原理
Vue3.0数据响应原理
创建页面,实现延时2s修改对象的值。代码同上。
Proxy实现:
functionvue(){
this.$data={
a:1
};
this.el=document.getElementById('app');
this._html="";
this.observe(this.$data);
this.render();
}
vue.prototype.observe=function(obj){
letself=this;
this.$data=newProxy(this.$data,{
get:function(target,key){
returntarget[key];
},
set:function(target,key,newvalue){
target[key]=newvalue;
self.render();
}
})
}
vue.prototype.render=function(){
this._html="Iam"+this.$data.a;
this.el.innerHTML=this._html;
}
在Chrome中console运行,结果页面显示:Iam444
为什么改用Proxy
- defineProperty只能监听某个属性,不能对全对象监听
- 可以省去forin循环提升效率
- 可以监听数组,不用再去单独的对数组做特异性操作
Proxy还能做什么
校验类型
functioncreateValidator(target,validator){
returnnewProxy(target,{
_validator:validator,
set(target,key,value,proxy){
if(target.hasOwnProperty(key)){
letvalidator=this._validator[key];
if(validator(value)){
returnReflect.set(target,key,value,proxy);
}else{
throwError('typeerror');
}
}
}
})
}
letpersonValidator={
name(val){
returntypeofval==='string';
},
age(val){
returntypeofval==='number'&&val>18;
}
}
classperson{
constructor(name,age){
this.name=name;
this.age=age;
returncreateValidator(this,personValidator);
}
}
在Chrome中console运行示例:
lettmp=newperson('张三',30);
结果显示:
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。