原文出處: wclimb
vue的使用相信大家都很熟練了,使用起來簡單。但是大部分人不知道其內部的原理是怎麼樣的,今天我們就來一起實現乙個簡單的vue
實現之前我們得先看一下object.defineproperty的實現,因為vue主要是通過資料劫持來實現的,通過get
、set
來完成資料的讀取和更新。
var obj =
var age = 24
object.defineproperty(obj,'age',,
set (newval)
})> obj.age
> 24
> obj.age = 25;
> 我改變了 24 -> 25
> 25
從上面可以看到通過get
獲取資料,通過set
監聽到資料變化執行相應操作,還是不明白的話可以去看看object.defineproperty文件。
改變值 }
new vue(,
methods:}})
class vue
proxydata(){}
observer(){}
compile(){}
compiletext(){}
}class watcher
update(){}
}
class vue));
this.methods = obj.methods // 事件方法
this.watchertask = {}; // 需要監聽的任務列表
this.observer(data); // 初始化劫持監聽所有資料
this.compile(this.$el); // 解析dom}}
上面主要是初始化操作,針對傳過來的資料進行處理
class vue)
proxydata(key),
set (newval)
});}
}
上面主要是**data
到最上層,this.***
的方式直接訪問data
class vue)
proxydata(key)
observer(data),
set(newvalue))}}
})})}}
同樣是使用object.defineproperty
來監聽資料,初始化需要訂閱的資料。
把需要訂閱的資料到push
到watchertask
裡,等到時候需要更新的時候就可以批量更新資料了。?下面就是;
遍歷訂閱池,批量更新檢視。
set(newvalue))}}
class vue)
proxydata(key)
observer(data)
compile(el)else if(node.nodetype === 1)
if(node.hasattribute('v-model') && (node.tagname === 'input' || node.tagname === 'textarea'))
})())
}if(node.hasattribute('v-html'))
this.compiletext(node,'innerhtml')
if(node.hasattribute('@click')))}}
}},
compiletext(node,type)\}/g, txt = node.textcontent;
if(reg.test(txt)))
return v
}else})}
}}
這裡**比較多,我們拆分看你就會覺得很簡單了
首先我們先遍歷el
元素下面的所有子節點,node.nodetype === 3
的意思是當前元素是文字節點,node.nodetype === 1
的意思是當前元素是元素節點。因為可能有的是純文字的形式,如純雙花括號
就是純文字的文字節點,然後通過判斷元素節點是否還存在子節點,如果有的話就遞迴呼叫compile
方法。下面重頭戲來了,我們拆開看:
if(node.hasattribute('v-html'))
上面這個首先判斷node節點上是否有v-html
這種指令,如果存在的話,我們就發布訂閱,怎麼發布訂閱呢?只需要把當前需要訂閱的資料push
到watchertask
裡面,然後到時候在設定值的時候就可以批量更新了,實現雙向資料繫結,也就是下面的操作
that.watchertask[key].foreach(task => )
然後push
的值是乙個watcher
的例項,首先他new的時候會先執行一次,執行的操作就是去把純雙花括號
-> 1,也就是說把我們寫好的模板資料更新到模板檢視上。
最後把當前元素屬性剔除出去,我們用vue
的時候也是看不到這種指令的,不剔除也不影響
至於watcher
是什麼,看下面就知道了
class watcher
update()
}
之前發布訂閱之後走了這裡面的操作,意思就是把當前元素如:node.innerhtml = '這是data裡面的值'、node.value = '這個是表單的資料'
那麼我們為什麼不直接去更新呢,還需要update
做什麼,不是多此一舉嗎?
其實update
記得嗎?我們在訂閱池裡面需要批量更新,就是通過呼叫watcher
原型上的update
方法。
完整**已經放到github
上了 -> myvue
JavaScript之實現乙個簡單的Vue
vue的使用相信大家都很熟練了,使用起來簡單。但是大部分人不知道其內部的原理是怎麼樣的,今天我們就來一起實現乙個簡單的vue object.defineproperty 實現之前我們得先看一下object.defineproperty的實現,因為vue主要是通過資料劫持來實現的,通過get set來...
自學QT之實現乙個使用者資訊視窗
使用者資訊視窗如果用設計師介面來做當然是非常簡單了,但是為了鍛鍊自己的開發能力和對qt以及c 的深入理解,有必要用 來進行操作。其實,比設計師介面更加靈活。看到 多,不要害怕,其實 中的大部分單詞只需要輸入開頭就可以自動補全的。新建乙個專案,基於對話方塊,取消介面選項。標頭檔案如下 ifndef d...
java學習之 實現乙個簡單的ArrayList
package thread1 實現乙個簡單的arraylist title uminton public class arraylist 有引數構造,建立容器,設定陣列大小 param arraycapacity public arraylist integer arraycapacity arr...