JavaScript之實現乙個簡單的Vue

2021-08-28 19:16:09 字數 3210 閱讀 3333

原文出處: wclimb

vue的使用相信大家都很熟練了,使用起來簡單。但是大部分人不知道其內部的原理是怎麼樣的,今天我們就來一起實現乙個簡單的vue

實現之前我們得先看一下object.defineproperty的實現,因為vue主要是通過資料劫持來實現的,通過getset來完成資料的讀取和更新。

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來監聽資料,初始化需要訂閱的資料。

把需要訂閱的資料到pushwatchertask裡,等到時候需要更新的時候就可以批量更新資料了。?下面就是;

遍歷訂閱池,批量更新檢視。

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這種指令,如果存在的話,我們就發布訂閱,怎麼發布訂閱呢?只需要把當前需要訂閱的資料pushwatchertask裡面,然後到時候在設定值的時候就可以批量更新了,實現雙向資料繫結,也就是下面的操作

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...