1.首先新建一個html在建立一個Kvue.js
<div id="app">
{{ message }}
<p>{{message}}</p>
<input type="text" k-model="name">{{name}}
<textarea k-model="age" name="" id="" cols="30" rows="10"></textarea>{{age}}
</div>
<script>
let vm = new Kvue({
el:'#app',
data:{
message: '數據展現',
name: '李四',
age: 20
}
})
</script>
複製代碼
2.而後在Kvue.js新建一個class類
class Kvue {
constructor(options){
this.$options = options;
this._data = options.data;
this.observer(this._data)
this.compile(options.el)
}
observer (data){
Object.keys(data).forEach(key=>{
let value = data[key];
let dep = new Dep();
Object.defineProperty(data,key,{
enumerable: true,
configurable: true,
get (){
if (Dep.target){
dep.addSub(Dep.target);
}
return value
},
set (newValue){
if (newValue !== value)
value = newValue
dep.notify(newValue);
}
})
})
}
compile (el){
let element = document.querySelector(el);
this.compileNdoe(element)
}
compileNdoe(element){
let node = element.childNodes;
Array.from(node).forEach(node=>{
if (node.nodeType == 3){
// 處理文本
let nodeContext = node.textContent;
let reg = /\{\{\s*(\S*)\s*\}\}/;
if (reg.test(nodeContext)){
node.textContent = this._data[RegExp.$1];
new Watcher(this,RegExp.$1,newValue=>{
// 視圖更新
node.textContent = newValue;
});
}
} else if (node.nodeType == 1){
let attrs = node.attributes;
Array.from(attrs).forEach(attr=>{
let attrName = attr.name;
let attrValue = attr.value;
if (attrName.indexOf('k-') == 0){
attrName = attrName.substr(2);
if (attrName == 'model'){
node.value = this._data[attrValue]
console.log(node.value)
}
node.addEventListener('input',e=>{
this._data[attrValue] = e.target.value;
})
new Watcher(this,attrValue,newValue =>{
node.value = newValue;
})
}
})
// 處理標籤
}
if (node.childNodes.length > 0){
this.compileNdoe(node);
}
})
}
}
// 發佈者
class Dep {
constructor(){
this.subs = []
}
addSub(sub){
this.subs.push(sub)
}
notify(newValue){
this.subs.forEach(v=>{
v.update(newValue);
})
}
}
//訂閱者
class Watcher {
constructor(vm,exp,cb){
Dep.target = this;
vm._data[exp];
this.cb = cb;
Dep.target = null;
}
update(newValue){
this.cb(newValue);
}
}
複製代碼
3.經過Object.defineProperty來監聽數據變化,經過獲取dom元素來實現數據綁定,最後經過發佈者和訂閱者來驅動視圖更新。