㈠ vue的設計思想
vue是一個MVVM框架,將視圖View的狀態和行為抽象化成ViewModal層,讓我們將視圖 UI 和業務邏輯分開。
重點在ViewModal層,要實現數據綁定,數據綁定的核心是響應式,所以
MVVM的三要素是:數據響應式、模板引擎及渲染;
以上圖片中的內容就是vue的實現思想,只不過是vue1中的實現思想;
vue2中的改變是
通過以上源碼觀察,尤其:
可以看出vue2中的 Object.defineProperty 消耗是非常大的,不僅要遍歷自身的key,去添加響應式,並且還要去遍歷子屬性的key。
vue1中watcher顆粒度太小了,所以改成一個組件一個watcher;
使用vnode最重要的原因是:只有一個watcher,我改了值很多foo,bar,界面受影響很多,沒辦法精確知道誰負責誰,所以只能兩個VNode進行遍歷;
帶來的好處:
規避真是dom操作,
如何針對不同平台實現不同patch的呢:
拿出核心的createPatchFunction工廠函數邏輯,根據傳參返回一個真的patch函數
參數nodeOps是節點操作,
參數moles是屬性更新操作,針對平台的platformMoles操作
簡單說就是 把平台特有的 { nodeOps, moles } 節點操作和節點屬性傳進去,會得到平台特有的patch函數
㈡ Vue 組件創建的流程源碼分析
注冊組件第二個參數默認會調用extend,Vue.extend 使用Vue基礎構造器 產生子類
Vue.extend() 中data必須是一個函數,繼承與Vue,可以new和掛載
Vue.component("",Vue.extend({})) //傳入的是對象
這樣復用了同一個對象所以改寫為,這樣new的時候可以拿到全新的對象
因為new Fn的constructor指向的是Parent,所以Sub.prototype需要重寫
———————————————— 分割線 ————————————————————
所以在createElement,需要對組件進行處理(要區分組件和普通元素去創建虛擬節點)
判斷是不是原始的標簽 還是組件的方法
㈢ 這種VUE代碼 是怎麼寫的
應該是打包工具自動生成的吧。
像這種代碼類似庫源碼,是挺難閱讀的。
㈣ vuejs源碼用了什麼設計模式,具體點的
最簡單的訂閱者模式
// Observer
class Observer {
constructor (data) {
this.walk(data)
}
walk (data) {
// 遍歷
let keys = Object.keys(data)
for(let i = 0; i < keys.length; i++){
defineReactive(data, keys[i], data[keys[i]])
}
}
}
function defineReactive (data, key, val) {
observer(val)
// dep 為什麼要在這里實例化, 就是為了實現, 對象每一層的 每一個key都有自己的一個訂閱實例, 比如 a.b 對應 dep1, a.c 對應dep2, 這里雖然都是let dep = new Dep()
// 但每次來到這個方法, dep都是獨立的, 會一直保留在內存. 這樣在每次調用set方法都能找到這個a.b對應的dep
// dep 這里會一直保存, 是因為閉包的關系, Object這個全局的函數, 引用了上層的作用域, 這個作用域包含了 dep, 除非Object = null, 或者退出瀏覽器, dep才會消失
//實例化之後, dep就有了被訂閱, 和發布消息的功能, dep不寫在這里也是可以的, 多定義一個全局函數, 每次obser的時候增加一個dep
let dep = new Dep()
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function () {
//每次new Watch('a.b'), 都會先執行get方法, 進而來到這里, 觸發 dep.depend(), 這個dep就是 a.b 對應的 訂閱,
dep.depend()
return val
},
set: function (newVal) {
if(val === newVal){
return
㈤ vue源碼 (1.初始化過程_init)
1.在init階段inject 是比 provide更早,比initState(initProps、initMethods、initComputed、initWatch) 都要早,因為vue的組件層級創建父組件created後再去創建子組件,一層一層向下創建的模式,那麼inject如果有在上級組件定義provide,那麼都會拿得到,而methods、computed、watch也有可能會用到 inject的值,所以需要放在最先初始化。
2.initInjections 原理
3.beforeCreate生命周期為什麼不能訪問數據,能訪問到什麼
4.initEvents 事件是掛在父組件執行還是當前組件this.$emit的組件
5.有el選項為什麼可以不需要$mount