模仿vue的mvvm實現方式,實現數據渲、改變data以及v-model
源碼地址vue
script src="Tvue.js"></script>
<body>
<div id="app">
{{message}}
<p>{{message}}</p>
</div>
</body>
<script>
let vm = new Tvue({
el: "#app",
data: {
message: '測試'
}
})
</script>
複製代碼
先實現數據替換功能node
class Tvue {
constructor(options) { // new Tvue裏的值
this.$options = options
this._data = options.data // 參考源碼,避免與data重名
this.compile(options.el) // 查找替換
}
compile(el) {
// 做用域 範圍內查找
let element = document.querySelector(el) // 獲取<div id="app"></div>
let childNodes = element.childNodes // 獲取子節點
Array.from(childNodes).forEach((node) => {
// console.log(node, 'nodeType 屬性可用來區分不一樣類型的節點,好比 元素, 文本 和 註釋。')
if (node.nodeType === 3) {
// 文本替換
let nodeContent = node.textContent
let reg = /\{\{\s*(\S*)\s*\}\}/ // 考慮插值表達式的先後空格
if (reg.test(nodeContent)) {
node.textContent = this._data[RegExp.$1]
}
} else {
}
})
}
}
複製代碼
打開瀏覽器mvvm模式已經實現,有個問題是git
{{message}}github
尚未被替換,還須要使用遞歸實現多層嵌套查找替換compileNode(element) { // 遞歸實現多層嵌套查找替換
let childNodes = element.childNodes // 獲取子節點
Array.from(childNodes).forEach((node) => {
// console.log(node, 'nodeType 屬性可用來區分不一樣類型的節點,好比 元素, 文本 和 註釋。')
if (node.nodeType === 3) {
// 文本替換
let nodeContent = node.textContent
let reg = /\{\{\s*(\S*)\s*\}\}/ // 考慮插值表達式的先後空格
if (reg.test(nodeContent)) {
node.textContent = this._data[RegExp.$1]
}
} else if (node.nodeType === 1) { // 處理標籤
}
if (node.childNodes.length > 0) {
this.compileNode(node)
}
})
}
複製代碼
OK,截止目前能夠實現多層數據嵌套vuex
接下來實現v-modellet attrs = node.attributes;
Array.from(attrs).forEach(attr => {
let attrName = attr.name;
let attrValue = attr.value;
if (attrName.indexOf("t-") == 0) {
attrName = attrName.substr(2);
if (attrName == "model") {
node.value = this._data[attrValue];
}
node.addEventListener("input", e => {
this._data[attrValue] = e.target.value;
})
new Watcher(this, attrValue, newValue => {
node.value = newValue;
});
}
})
複製代碼
下一篇