JSFiddle - React, Tailwind, and code Playground
by sj82516
HTML
<h1>
使用Proxy 產生 One-way data binding
</h1>
<div id="app">
<h2>{{title}}</h2>
<p>
{{message.title}}
</p>
<p>
{{message.content}}
</p>
<ul>
<li v-for="item in arr">{{item.arr}}</li>
</ul>
</div>
JavaScript
class Vue {
constructor({el, data}){
this.data = Object.assign({}, data);
this.data = new Proxy(data, {
set: (target, property, value) => {
Reflect.set(target, property, value);
// update view
}
})
this._rootEl = document.querySelector('el');
this._constructComponent();
}
//渲染頁面
_constructComponent(){
if(!this.rootEl){
throw("根物件不存在");
}
let children = this.rootEl.children;
for(let i=0; i < children.length; i++){
let child = children[i];
let mustacheExec = /^\{{2}(.*)\}{2}$/.exec(child.textContent);
if(mustacheExec){
this._handleMustache(mustacheExec[1], child);
}
if(child.hasAttribute('v-model')){
this._handleVModel(child.getAttribute('v-model'), child)
}
if(child.hasAttribute('v-for')){
this._handleVFor(child.getAttribute('v-model'), child)
}
}
}
// string interpolation : {{ ... }}
_handleMustache(propertyName, el){
if(!this.dataStored[propertyName]){
throw("資料不存在,你綁錯人囉")
}
el.textContent = this.dataStored[propertyName].value;
console.log(el.textContent)
this.dataStored[propertyName].elements.push(el);
}
// 處理v-model雙向綁定
_handleVModel(propertyName, el){
let vm = this;
if(!this.dataStored[propertyName]){
throw("資料不存在,你綁錯人囉")
}
el.value = vm.dataWithSetter[propertyName];
el.addEventListener("keyup", function(){
vm.dataWithSetter[propertyName] = el.value;
});
}
_handleVFor(propertyName, el){
}
}