摘要:用創建好的實例調用守衛中傳給的回調函數。注冊一個全局守衛。這和類似,區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用僅代表個人見解,能力有限,如有錯誤會誤人子弟的地方歡迎留言指出謝謝
原文地址
vue(前端框架)解決了什么問題?現在的前端頁面元素越來越多,結構也變得越來越復雜,當數據和視圖混合在一起的時候對它們的處理會十分復雜,同時也很容易出現錯誤,而現代框架使用聲明式語法,描述組件對象的嵌套關系,并自動生成與dom對象的對應關系
參考1
vue生命周期 | 描述 |
---|---|
beforeCreate | 組件實力被創建,el和數據對象都為undefined,還未初始化 |
create | 數據已經被初始化,并且初始化了Vue內部事件,但是DOM還未生成 |
befroeMount | 完成了模板的編譯。把data對象里面的數據和vue的語法寫的模板編譯成了虛擬DOM |
mouted | 執行了render函數,將渲染出來的內容掛載到了DOM節點上 |
beforeUpdate | 組件更新之前:數據發生變化時,會調用beforeUpdate,然后經歷DOM diff |
updated | 組件更新后 |
actived | keep-alive組件被激活 |
deactivated | keep-alive移除 |
beforeDestroy | 組件銷毀前 |
destroyed | 組件銷毀后 |
可以問數據變動如何和視圖聯系在一起?
Vue是采用數據劫持結合發布者-訂閱者模式的方式, Vue相應系統有三大核心:observe,dep,watcher;精簡版Vue代碼參考
Observe:當一個Vue實例創建時,initData階段,vue會遍歷data選項的屬性(observe),用 Object.defineProperty 將它們轉為 getter/setter并且在內部追蹤相關依賴(dep),在屬性被訪問和修改時通知變化。
Compite:調用compile方法解析模版,當視圖中有用到vue.data中數據的時候,會調用實例化watcher方法進行依賴收集
Watcher:是Observer和Compile之間通信的橋梁,當視圖中遇到綁定的數據時,在watcher方法中會獲取這個數據,此時會觸發observe中的getter方法,
Dep:發布訂閱模式,observe中數據的getter被觸發時會收集依賴的watcher(dep.depend方法)
當有數據被改動時會觸發observe中數據的setter,此時會調用dep.notify方法給所有訂閱的watcher發通知(通過回掉方式)進行視圖更新,此時會進行diff流程:
vue中data為什么必須要是一個函數vue中的data為對象,是引用類型,當重用組件時,一個組件對data做了更改,那么另一個組件也會跟著改,而使用返回一個函數返回數據,則每次返回都是一個新對象,引用地址不用,所以就不會出現問題Virtual DOM 是什么
虛擬DOM是一個JavaScript對象,包含了當前DOM的基本結構和信息,它的存在是為了減少對操作無用DOM所帶來的性能消耗,在大量的、頻繁的數據更新下能夠對視圖進行合理的高效的更新(細粒度的精準修改),同時也抽象了原來的渲染過程,實現了跨平臺的能力
簡述vue中的DOM DIFF算法精簡源碼;當數據發生改變時,set方法會讓調用Dep.notify通知所有訂閱者Watcher,訂閱者就會調用patch給真實的DOM打補丁(兩個重要函數patchVnode和updateChildren):
先判斷根結點及變化后的節點是否是sameVnode,如果不是的化,就會創建新的根結點并進行替換
如果是sameVnode,則進入patchVnode函數,其基本判斷
如果兩個節點是相等oldVnode === vnode則直接return
如果新節點是文本節點,則判斷新舊文本節點是否一致,不一致(oldVnode.text !== vnode.text)則替換
如果新節點不是文本節點,則開始比較新舊節點的子節點oldCh和ch:
如果子節點都存在,則進行updateChildren計算(稍后講)
如果只有新子節點存在,則如果舊節點有文本節點,則移除文本節點,然后將新子節點拆入
如果只有舊子節點存在,則移除所有子節點
如果均無子節點且舊節點是文本節點,則移除文本節點(此時新節點一定不是文本節點)
updateChildren函數做細致對比
start && oldStart對比
end && oldEnd對比
start && oldEnd對比
end && oldStart 對比
生成map映射,(key:舊子節點上的key,value:舊子節點在自己點中的位置),根據key記錄下老節點在新節點的位置(idxInOld)
1) 如果找到了idxInOld,如果是相同節點則移動舊節點到新的對應的地方,否則雖然key相同但元素不同,當作新元素節點去創建
2) 如果沒有找到idxInOld,則創建節點
如果老節點先遍歷完,則新節點比老節點多,將新節點多余的插入進去
如果新節點先遍歷完,則就節點比新節點多,將舊節點多余的刪除
vue中key的作用主要是為了復用節點,高效的更新虛擬DOM,另外,在使用標簽元素過渡效果時也會用到key
computed的原理vue對象初始化的同時對計算屬性進行初始化initComputed,
computed會對初始化的Watcher傳入lazy: true就會觸發Watcher中的watcher.dirty=true(dirty決定了當前屬性是否更新),
當視圖中有對computed引用的時候會第一次執行計算屬性,并將dirty設置為false,并將結果保存在this.value中進行緩存,
如果依賴沒有更改,則下次獲取computed會這直接返回this.value,只有當computed所依賴的屬性發生變化時會將dirty設置為true,并重新計算
class Watcher{ …… evaluate () { this.value = this.get() this.dirty = false } …… } class initComputed{ …… //計算屬性的getter 獲取計算屬性的值時會調用 createComputedGetter (key) { return function computedGetter () { //獲取到相應的watcher const watcher = this._computedWatchers && this._computedWatchers[key] if (watcher) { //watcher.dirty 參數決定了計算屬性值是否需要重新計算,默認值為true,即第一次時會調用一次 if (watcher.dirty) { /*每次執行之后watcher.dirty會設置為false,只要依賴的data值改變時才會觸發 watcher.dirty為true,從而獲取值時從新計算*/ watcher.evaluate() } //獲取依賴 if (Dep.target) { watcher.depend() } //返回計算屬性的值 return watcher.value } } } …… }計算屬性computed和watch的區別
計算屬性顧名思義就是通過其他變量計算得來的,它的值是基于其所依賴的屬性來進行緩存的,只有在其所依賴的屬性發生變化時才會從新求值
watch是監聽一個變量,當變量發生變化時,會調用對應的方法
vue實現響應式并不是數據一更新就立刻觸發dom變化,而是按照一定的策略對dom進行更新,源碼位置,原理:
首先會將所有的nextTick放到一個函數中,然后放在callbacks數組中,$nextTick沒有傳cb回掉,則返回一個promise
接下來就是callbacks的執行時機
首先如果瀏覽器是否兼容promise,則用promise.resolve().then來執行callbacks
如果瀏覽器兼容MutationObserver,則用實例化的MutationObserver監聽文本變化來執行回掉,
如果兼容setImmediate,則用setImmediate(cb)來執行回掉
最后降級為用setTimeout(fn,0)來執行
在vue2.5.X版本中對于像v-on這樣的DOM交互事件,默認走macroTimerFunc,也就是,跳過第一步promise的判斷,
子組件為何不可以修改父組件傳遞的 Prop,是如何監控并給出錯誤提示的單向數據流,易于監測數據的流動,出現了錯誤可以更加迅速的定位到錯誤發生的位置
在initProps時,會對props進行defineReactive操作,傳入的第四個參數是自定義的set報錯判斷函數,該函數會在觸發props的set方法時執行
// src/core/instance/state.js 源碼路徑 function initProps (vm: Component, propsOptions: Object) { ... for (const key in propsOptions) { if (process.env.NODE_ENV !== "production") { ... defineReactive(props, key, value, () => { // 如果不是跟元素并且不是更新子元素 if (!isRoot && !isUpdatingChildComponent) { warn( `Avoid mutating a prop directly since the value will be ` + `overwritten whenever the parent component re-renders. ` + `Instead, use a data or computed property based on the prop"s ` + `value. Prop being mutated: "${key}"`, vm ) } })} ... } } // src/core/observer/index.js export function defineReactive (obj,key,val,customSetter,shallow) { const property = Object.getOwnPropertyDescriptor(obj, key) const getter = property && property.get const setter = property && property.set Object.defineProperty(obj, key, { ... set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val if (newVal === value || (newVal !== newVal && value !== value)) { return } if (process.env.NODE_ENV !== "production" && customSetter) { customSetter() } if (getter && !setter) return if (setter) { setter.call(obj, newVal) } else { val = newVal } childOb = !shallow && observe(newVal) dep.notify() } }) }父子組件的生命周期執行順序
加載過程:父組件beforeCreate => 父組件created => 父組件beforeMount => 子組件beforeCreate => 子組件created => 子組件 beforeMount => 子組件mounted => 父組件mounted
更新過程:父組件beforeUpdate => 子組件beforeUpdate => 子組件updated => 父組件updated
銷毀過程:父組件beforeDestroy => 子組件 beforeDestroy => 子組件 destoryed => 父組件 destoryed
官網
導航被觸發。
在失活的組件里調用離開守衛。
調用全局的 beforeEach 守衛。
在重用的組件里調用 beforeRouteUpdate 守衛 (2.2+)。
在路由配置里調用 beforeEnter。
解析異步路由組件。
在被激活的組件里調用 beforeRouteEnter。
調用全局的 beforeResolve 守衛 (2.5+)。
導航被確認。
調用全局的 afterEach 鉤子。
觸發 DOM 更新。
用創建好的實例調用 beforeRouteEnter 守衛中傳給 next 的回調函數。
router.beforeResolve 注冊一個全局守衛。這和 router.beforeEach 類似,區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用
僅代表個人見解,能力有限,如有錯誤會誤人子弟的地方歡迎留言指出;謝謝文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/105599.html
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:前言用有一段時間了,從用搭建項目一步步配置,到之后的研究動效這些,一直想寫些東西記錄一下做個總結,剛好趁著有空就整理一下。結語有新的知識點會更新到知識體系中,總結和心得體會會單獨寫文章詳述,努力填坑 前言 用vue有一段時間了,從用vue-cli搭建項目、一步步配置axios、vuex、vue-router,到之后的研究canvas、動效這些,一直想寫些東西記錄一下、做個總結,剛好趁著...
摘要:本文只是對官方文檔和對官方的個人學習總結,說得不夠完整的請見諒本文主要對以下幾方面內容對的內容進行分析總結出現的原因的總體原理當中的數據預取在編寫代碼時候的限制的構建原理出現的原因單頁應用有一個很大的缺點就是問題,搜索引擎目前只能對同步的進 本文只是對Vue.js官方SSR文檔和對官方hackernews demo的個人學習總結,說得不夠完整的請見諒 本文主要對以下幾方面內容對Vue....
摘要:天王蓋地虎鉤子事件得到的結果是小總結實例創建完成后,我們能讀取到數據的值,但是還沒生成,掛載屬性還不存在。此時的階段解讀為掛載完畢階段我們再打印下此時看看鉤子事件得到的結果是可見,已經成功渲染成里面對應的值天王蓋地虎了。 你不需要立馬弄明白所有的東西,不過隨著你的不斷學習和使用,它的參考價值會越來越高。 現在項目中遇到了,好好回頭總結一波Vue生命周期,以后用到的時候再來翻翻。 啥叫V...
摘要:寫在前面其實最開始不是特意來研究的源碼,只是想了解下的命令,如果想要了解命令的話,那么繞不開寫的。通過分析發現與相比,變化太大了,通過引入插件系統,可以讓開發者利用其暴露的對項目進行擴展。 showImg(https://segmentfault.com/img/bVboijb?w=1600&h=1094); 寫在前面 其實最開始不是特意來研究 vue-cli 的源碼,只是想了解下 n...
閱讀 2517·2021-09-09 09:33
閱讀 2877·2019-08-30 15:56
閱讀 3162·2019-08-30 14:21
閱讀 913·2019-08-30 13:01
閱讀 876·2019-08-26 18:27
閱讀 3596·2019-08-26 13:47
閱讀 3467·2019-08-26 10:26
閱讀 1600·2019-08-23 18:38