Vue响应原理 definedProperty与proxy实现数据双向绑定
Vue中从改变一个数据到发火说呢过改变的过程Vue2 利用definedProperty实现数据绑定definedProperty 基础使用:var ob={a:1,b:2}var _value=ob.aObject.defineProperty(ob,'a',{//writable:true,//可否修改//enumerable:false,//是否...
·
Vue中从改变一个数据到页面渲染改变的过程
Vue2 利用definedProperty实现数据绑定
definedProperty 基础使用:
var ob={
a:1,
b:2
}
var _value=ob.a
Object.defineProperty(ob,'a',{
//writable:true,//可否修改
//enumerable:false,//是否可被枚举
//configurable:false,//是否可被delete
get(){//获取时触发函数
console.log('取值')
return _value
},
set(a){//修改时触发函数,参数为修改的值
console.log('存值')
_value=a
return _value
},
})
实现Vue2 双向数据绑定
function vue(){
this.$data={a:1};
this.el=document.getElementById('add');
this.virtualdom="";
this.observe(this.$data);
this.render;
}
vue.prototype.observe=function(obj){//数据监听
var value;
var self=this;
for(var key in obj){
vaule=obj[key];
if(typeof vaue=='object'){
this.observe(value)
}else{
Object.defineProperty(obj,key,{
get(){//依赖收集
return value
},
set(newValue){//触发更新
value=newValue
self.render()
},
})
}
}
}
vue.prototype.render=function(){//数据渲染
this.virtualdom="I am "+this.$data.a
this.el.innerHTML=this.virtualdom
}
//数组监听~思想(未具体实现)
var arrPro=Array.prototype;
var arrayob=Object.create(arrayPro)
var arr=['push','pop','shift'];
arr.forEach((method,index)=>{
arrayob[methods]=function(){
var ret=arrayPro[methods].apply(this,arguments);
dep.notify();//vue源码中体现
return ret;
}
})
let num=0
let vm=new vue()
setInterval(()=>{
console.log('修改')
vm.$data.a=num++
},2000)
Vue3 利用proxy实现数据绑定
和defineProperty类似,功能几乎一样,用法不同
- defineProperty是改变原有对象
- proxy是新建一个代理对象
- defineProperty只能监听某一属性不能设置去全对象监听;如果需要全对象监听则需要递归修改原对象相关属性,且defineProperty是对象的方法 数组无法监听;proxy可以对数组进行监听
Proxy用于修改某些操作的默认行为,也可以理解为在目标对象之前架设一层拦截,外部所有的访问都必须先通过这层拦截,因此提供了一种机制,可以对外部的访问进行过滤和修改。这个词的原理为代理,在这里可以表示由它来“代理”某些操作,译为“代理器”。
实现Vue3双向数据绑定
function vue(){
this.$data={a:1};
this.el=document.getElementById('add');
this.virtualdom="";
this.observe(this.$data);
this.render;
}
vue.prototype.observe=function(obj){//数据监听
var self=this;
this.$data=new Proxy(this.$data,{
get(target,key){
return target[key]
},
set(target,key,newValue){//触发更新
target[key]=newValue
self.render()
},
})
}
vue.prototype.render=function(){//数据渲染
this.virtualdom="I am "+this.$data.a
this.el.innerHTML=this.virtualdom
}
let num=0
let vm=new vue()
setInterval(()=>{
console.log('修改')
vm.$data.a=num++
},2000)
更多推荐
已为社区贡献17条内容
所有评论(0)