一、手写类Vue框架:zue
class Zue{
constructor(options){
}
}
1、在zue实例下创建$el,并指向挂载点
this.$el = document.querySelector(options.el);
2、在zue实例下创建$options,指向zue实例时的选项
this.$options = options || {};
3、在zue实例下创建$data,指向Vue实例的数据区内容
this.$data = options.data || {};
4、将data数据区中的所有变量变为具有访问器特性的变量
class Zue{
constructor(options){
this.$options = options || {};
this.$el = document.querySelector(options.el);
this.$data = options.data || {};
this.proxyData(this.$data);
}
proxyData(data){
Object.keys(data).forEach(key=>{
Object.defineProperty(this,key,{
enumberable:true,
configurable:true,
get:function(){
return data[key];
},
set:function(newValue){
if(data[key] === newValue) return;
data[key] = newValue;
}
})
})
}
}
var zm = new Zue({
el:'#app',
data:{
cont:100,
isOk:true,
message:'zanilia'
}
})
二、将注入到实例下$data中的数据编程具备访问器特性的数据(如上图所示):
- Vue实例中从数据区data中得到的$data中的变量也是具备访问器特性的变量。
- 为了完成这个功能,需要创建一个新类:Observer
class Zue{
constructor(options){
this.$options = options || {};
this.$el = document.querySelector(options.el);
this.$data = options.data || {};
this.proxyData(this.$data);
new Observer(this.$data)
}
proxyData(data){
console.log(Object.keys(data))
Object.keys(data).forEach(key=>{
Object.defineProperty(this,key,{
enumberable:true,
configurable:true,
get:function(){
return data[key];
},
set:function(newValue){
if(data[key] === newValue) return;
data[key] = newValue;
}
})
})
}
}
class Observer{
constructor(data){
this.walk(data)
}
walk(data){
if(typeof data !== 'object'){
return;
}
Object.keys(data).forEach(key=>{
this.defineReactive(data,key,data[key])
})
}
defineReactive(obj,key,val){
let _this = this;
this.walk(val);
Object.defineProperty(obj,key,{
enumberable:true,
configurable:true,
get(){
return val
},
set(newValue){
if(val === newValue) return;
val = newValue;
_this.walk(newValue);
}
})
}
}
var zm = new Zue({
el:'#app',
data:{
cont:100,
isOk:true,
message:'zanilia',
obj:{
a:10,
b:20,
c:30
}
}
})