标签:rip window 定义 selector sel 方式 type 设置 log
Object.defineProperty介绍-- let obj = {}; Object.defineProperty(obj,‘school‘,{ configurable : true, // 属性能否被删除 //writable : true, // 属性能否被修改 enumerable : true, // 属性能否枚举 //value : ‘zfpx‘, // 设置属性值 set : function(value){ console.log(value); // obj.school赋值时, 调用set() 方法 }, get : function(){ return ‘zfpx‘; // 获取 obj.school 的值时,调用 get() 方法 } })
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<p>{{a.a}}</p>
<div>{{b}}
<div>{{b}}</div>
</div>
</div>
</body>
<!-- mvvm 双向数据绑定
vue 数据劫持+发布订阅模式
不兼容低版本 Object.defineProperty -->
<script>
(function(window,document){
function ZF(options = {}){
this.$options = options; // 将所有的属性挂载在 $options 上
let data = this._data = this.$options.data;
this.observe(data);
for(let key in data){ // 把data属性通过Object.defineProperty的方式定义属性
// 数据代理
// this代理了this._data
Object.defineProperty(this,key,{
enumerable : true, // 可枚举
get: function(){
return this._data[key];
},
set: function(newVal){ // 更改值的时候
this._data[key] = newVal;
}
});
}
this.Compile(options.el,this);
}
// 编译
ZF.prototype.Compile = function(el,vm){
vm.$el = document.querySelector(el);
let fragment = document.createDocumentFragment();
while(child = vm.$el.firstChild){ // 将app中的内容 移入内存中
fragment.appendChild(child);
}
// 循环每一层
Array.from(fragment.childNodes).forEach(function(node){
let text = node.textContent;
let reg = /\{\{(.*)\}\}/;
if( reg.test(text)){
let arr = RegExp.$1.split(‘.‘);
let val = vm;
console.log(node.childNodes)
console.log(arr)
arr.forEach(function(k){
val = val[k];
})
// 替换
node.textContent = text.replace(/\{\{(.*)\}\}/,val)
}
//node.textContent.textContent(12)
})
vm.$el.appendChild(fragment);
}
// 观察对象给对象增加ObjectDefineProperty;
ZF.prototype.observe = function(data){
//console.log(data)
return new Observe(data);
}
function Observe(data){
for(let key in data){ // 把data属性通过Object.defineProperty的方式定义属性
let val = data[key];
// 递归
if(typeof val === ‘object‘){
Observe(val);
}
Object.defineProperty(data,key,{
enumerable : true, // 可枚举
get: function(){
return val;
},
// 数据劫持
set: function(newVal){ // 更改值的时候
if(newVal === val){
return;
}
if(typeof newVal === ‘object‘){
Observe(newVal);
}
val = newVal; //
}
});
}
}
window.ZF = ZF;
})(window,document);
let zf = new ZF({
el : "#app",
data : {a:{a:‘是a‘},b:‘是b‘},
})
</script>
</html>
标签:rip window 定义 selector sel 方式 type 设置 log
原文地址:https://www.cnblogs.com/cl94/p/12235968.html