逻辑 -> 数据 <—>视图
/*** 1. 数据 -> 响应式数据 Object.defineProperty Proxy* 2. input -> input/keyup -> 事件处理函数的绑定 -> 改变数据* 3. 相关的DOM & 数据 => 绑定在一起* 操作数据的某个属性 -> 对应DOM就改变* {* 'name': [span节点]* }****/const reg_var = /\{\{(.*?)\}\}/;// eslint-disable-next-lineclass MVVM {constructor(el, data){this.el = document.querySelector(el);// this._data = data;this.data = data;this.domPool = {};//dom池this.init();}init(){this.initData();this.initDom();}initData(){const _this = this;// this.data = {};// for(const key in this._data){// if(typeof key === 'object'){// //递归// }// Object.defineProperty(this.data, key, {// get(){// console.log("获取数据: ", key, _this._data[key]);// return _this._data[key];// },// set(newValue){// if(newValue===_this._data[key]){// return;// }// console.log("设置数据: ", key, _this._data[key]);// _this.domPool[key].innerText = newValue;// _this._data[key] = newValue;// }// });// }//Proxy写法this.data = new Proxy(this.data, {get(target, key){return Reflect.get(target, key);},set(target, key, value){_this.domPool[key].innerText = value;return Reflect.set(target, key, value);}})}initDom(){this.bindDom(this.el);//这应该先执行console.log("看看dom池子:",this.domPool);this.bindInput(this.el);}//数据与DOM节点绑定--解析出{{name}}绑定到对应节点上bindDom(el){if(!el){return;}const childNodes = el.childNodes;// console.log("el.childNodes: ", childNodes);childNodes.forEach(item => {//如果是文本节点if(item.nodeType===3){const _value = item.nodeValue;// console.log(_value);if(_value.trim().length){let _isValid = reg_var.test(_value);//捕获组&懒惰模式if(_isValid){const _key = _value.match(reg_var)[1].trim();console.log("匹配到的属性:", _key);this.domPool[_key] = item.parentNode;//其实应该是个set集合,这里简化为1v1了//再设置DOMitem.parentNode.innerText = this.data[_key] || undefined;}}}item.childNodes && this.bindDom(item);//递归});}//input--绑定事件处理函数bindInput(el){if(!el){return;}const _allInputs = el.querySelectorAll('input');_allInputs.forEach(input=>{const _vModel = input.getAttribute('v-model');if(_vModel){input.addEventListener('keyup', this.handleInput.bind(this, _vModel, input));}})}handleInput(key, input){const _value = input.value;this.data[key] = _value;}setData(key, value){this.data[key] = value;}}
