1、Vue中的修飾符有哪些?
修飾符是用于限定類型以及類型成員的聲明的一種符號。Vue中修飾符分為如下五種:表單修飾符、事件修飾符、鼠標(biāo)按鍵修飾符、鍵值修飾符和v-bind修飾符。
1)表單修飾符
我們在填寫表單時用到最多的就是input標(biāo)簽,指令用的最多的是v-model,關(guān)于表單修飾符有l(wèi)azy、trim、number。
使用.lazy 可以讓val1的變化由input事件轉(zhuǎn)化為change事件的時機觸發(fā),也就是說用戶在輸入的時候不會觸發(fā),只有在blur的時候才會觸發(fā);
使用.trim 默認會對事件的event.target.value 調(diào)用一次trim方法,自動過濾用戶輸入的首空格字符,而中間的空格不會過濾;
使用.number 默認會對值進行一個parseFloat的轉(zhuǎn)換,如果轉(zhuǎn)換失敗,保留原來的值。
2)事件修飾符
事件修飾符是對事件捕獲以及目標(biāo)進行了處理。
stop 阻止了事件冒泡,相當(dāng)于調(diào)用了event.stopPropagation方法。
prevent 阻止了事件的默認行為,相當(dāng)于調(diào)用了event.preventDefault方法
self 只當(dāng)在event.target是當(dāng)前元素自身時觸發(fā)處理函數(shù)。
once 綁定了事件以后只能觸發(fā)一次,第二次就不會觸發(fā)。
passive 當(dāng)我們在監(jiān)聽元素滾動事件的時候,會一直觸發(fā)onscroll事件會讓我們的網(wǎng)頁變卡,因此我們使用這個修飾符的時候,相當(dāng)于給onscroll事件整了一個.lazy修飾符。
3)鼠標(biāo)修飾符
left 左鍵點擊;right 右鍵點擊;middle 中鍵點擊。
4)鍵盤修飾符
鍵盤修飾符是用來修飾鍵盤事件。
普通鍵(enter、tab、delete、space、esc、up...);系統(tǒng)修飾鍵(ctrl、alt、meta、shift...)
5)v-bind修飾
async 能對props進行一個雙向綁定。使用sync的時候,子組件傳遞的事件名格式必須為update:value,其中value必須與子組件中props中聲明的名稱完全一致。
props 設(shè)置自定義標(biāo)簽屬性,避免暴露數(shù)據(jù),防止污染HTML結(jié)構(gòu)。
camel 將命名變?yōu)轳劮迕?,如將view-Box屬性名轉(zhuǎn)換為viewBox
2、nextTick 的原理
Vue 在更新 DOM 時是異步執(zhí)行的。當(dāng)數(shù)據(jù)發(fā)生變化,Vue將開啟一個異步更新隊列,視圖需要等隊列中所有數(shù)據(jù)變化完成之后,再統(tǒng)一進行更新。NextTick就是在DOM更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。
如果沒有nextTick 更新機制,那么數(shù)據(jù)每次更新都會觸發(fā)視圖更新(若改變10萬次就是會更新10萬次視圖),有了nextTick機制,只需要更新一次,所以nextTick本質(zhì)是一種優(yōu)化策略。
使用場景:如果想要在修改數(shù)據(jù)后立刻得到更新后的DOM結(jié)構(gòu),可以使用Vue.nextTick()。
3、new Vue()過程
1)首先找到vue的構(gòu)造函數(shù),包含一個options參數(shù)。options是用戶傳遞過來的配置項,如data、methods等常用的方法。
2)vue構(gòu)建函數(shù)調(diào)用_init方法。
initLifecycle(vm):初始化組件生命周期標(biāo)志位;
initEvents(vm):初始化組件事件偵聽;
initRender(vm):初始化渲染方法;
initInjections(vm):初始化依賴注入內(nèi)容,在初始化data、props之前;
initState(vm):初始化props/data/method/watch/methods;
vm.$mount(vm.$options.el):掛載元素。????
調(diào)用beforeCreate之前,數(shù)據(jù)初始化并未完成,像data、props這些屬性無法訪問到;
created階段,數(shù)據(jù)已經(jīng)初始化完成,能夠訪問data、props這些屬性,但這時候并未完成dom的掛載,因此無法訪問到dom元素;
3)掛載方法是調(diào)用vm.$mount方法。
initState(vm)
initState方法是完成props/data/method/watch/methods的初始化。
vm.$mount(vm.$options.el)
獲取或查詢掛載元素。vue 不允許直接掛載到body或頁面文檔上;
獲取template模板,解析vue模板文件;
將temmplate解析ast tree;
將ast tree轉(zhuǎn)換成render語法字符串;
生成render方法,掛載到vm上后,會再次調(diào)用mount方法渲染組件。
監(jiān)聽組件數(shù)據(jù),一旦發(fā)生變化,觸發(fā)beforeUpdate生命鉤子。
updateComponent方法主要執(zhí)行在vue初始化時聲明的render,update方法。
render的作用主要是生成vnode。調(diào)用patch,將vnode轉(zhuǎn)換為真實DOM,并且更新到頁面
4、Vue編譯原理
Vue編譯原理主要分三個部分,也可以說是分三步:
第一步:將模板字符串轉(zhuǎn)換成element ASTs(解析器);
第二步:對AST進行靜態(tài)節(jié)點標(biāo)記(跳過此節(jié)點),主要用來做虛擬DOM的渲染優(yōu)化(優(yōu)化器);
第三步:使用element ASTs生成render函數(shù)代碼字符串(代碼生成器)。通過調(diào)用這個函數(shù)就可以得到模板對應(yīng)的虛擬DOM。
解析器分為HTML解析器、文本解析器以及過濾器解析器。
HTML解析器是主線,先用HTML解析器進行解析整個模板,在解析過程中如果碰到文本內(nèi)容,那就調(diào)用文本解析器來解析文本,如果碰到文本中包含過濾器那就調(diào)用過濾器解析器來解析。
模板解析的過程就是不斷調(diào)用鉤子函數(shù)的處理過程。有如下鉤子函數(shù):
每當(dāng)解析到標(biāo)簽的開始位置時,觸發(fā)該函數(shù)start (tag, attrs, unary, start, end),
每當(dāng)解析到標(biāo)簽的結(jié)束位置時,觸發(fā)該函數(shù)end(tag, start, end),
每當(dāng)解析到文本時,觸發(fā)該函數(shù)chars(text: string, start: number, end: number),
每當(dāng)解析到注釋時,觸發(fā)該函數(shù)comment(text: string, start, end)
整個過程,讀取template字符串,使用不同的正則表達式,匹配到不同的內(nèi)容,然后觸發(fā)對應(yīng)不同的鉤子函數(shù)處理匹配到的截取片段,比如開始標(biāo)簽正則匹配到開始標(biāo)簽,觸發(fā)start鉤子函數(shù),鉤子函數(shù)處理匹配到的開始標(biāo)簽片段,生成一個標(biāo)簽節(jié)點添加到抽象語法樹上。解析到{{xxx}}這行文本,此時觸發(fā)了文本鉤子函數(shù)chars,處理匹配片段,生成一個帶變量文本標(biāo)簽節(jié)點并作為上一個節(jié)點的子節(jié)點添加到AST上;然后解析到結(jié)束標(biāo)簽,觸發(fā)了標(biāo)簽結(jié)束的鉤子函數(shù)end。
5、Vue.use()
Vue.use()是全局注冊一個組件或者插件的方法。原理如下:
第一,判斷這個插件是否被注冊過,如果已經(jīng)注冊了,不允許重復(fù)注冊。如果插件沒有被注冊過,那么注冊成功之后會給插件添加一個installed的屬性,其值為true。Vue.use方法內(nèi)部會檢測插件的installed屬性,從而避免重復(fù)注冊插件.
第二,接收的plugin參數(shù)的限制是Function | Object兩種類型之一。
自己來實現(xiàn)一個插件也是超級簡單,只要對外暴露一個install方法即可,在使用Vue.use的時候,會調(diào)用這個方法。
6、keep-alive
keep-alive是Vue的一個內(nèi)置組件。它能夠不活動的組件實例保存在內(nèi)存中,而不是直接將其銷毀,它是一個抽象組件,不會被渲染到真實DOM中,也不會出現(xiàn)在父組件鏈中。它提供了include與exclude兩個屬性,允許組件有條件地進行緩存。keep-alive組件的緩存也是基于VNode節(jié)點的而不是直接存儲DOM結(jié)構(gòu)
created鉤子會創(chuàng)建一個cache對象,用來作為緩存容器,保存vnode節(jié)點。
destroyed鉤子則在組件被銷毀的時候清除cache緩存中的所有組件實例。
Render函數(shù)首先通過getFirstComponentChild獲取第一個子組件,獲取該組件的name。接下來會將這個name通過include與exclude屬性進行匹配,匹配不成功(說明不需要進行緩存)則不進行任何操作直接返回vnode。
根據(jù)key在this.cache中查找,如果存在則說明之前已經(jīng)緩存過了,直接將緩存的vnode的componentInstance(組件實例)覆蓋到目前的vnode上面。否則將vnode存儲在cache中。
用watch來監(jiān)聽pruneCache與pruneCache這兩個屬性的改變,在改變的時候修改cache緩存中的緩存數(shù)據(jù)。
keep-alive提供了兩個生命鉤子,分別是activated與deactivated。
因為keep-alive會將組件保存在內(nèi)存中,并不會銷毀以及重新創(chuàng)建,所以不會重新調(diào)用組件的created等方法,需要用activated與deactivated這兩個生命鉤子來得知當(dāng)前組件是否處于活動狀態(tài)。