您好,登錄后才能下訂單哦!
這篇文章主要介紹了Vue.js面試題及答案有哪些的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Vue.js面試題及答案有哪些文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
核心實(shí)現(xiàn)類:
Observer : 它的作用是給對(duì)象的屬性添加 getter 和 setter,用于依賴收集和派發(fā)更新
Dep : 用于收集當(dāng)前響應(yīng)式對(duì)象的依賴關(guān)系,每個(gè)響應(yīng)式對(duì)象包括子對(duì)象都擁有一個(gè) Dep 實(shí)例(里面 subs 是 Watcher 實(shí)例數(shù)組),當(dāng)數(shù)據(jù)有變更時(shí),會(huì)通過(guò) dep.notify()通知各個(gè) watcher。
Watcher : 觀察者對(duì)象 , 實(shí)例分為渲染 watcher (render watcher),計(jì)算屬性 watcher (computed watcher),偵聽(tīng)器 watcher(user watcher)三種
Watcher 和 Dep 的關(guān)系:
watcher 中實(shí)例化了 dep 并向 dep.subs 中添加了訂閱者,dep 通過(guò) notify 遍歷了 dep.subs 通知每個(gè) watcher 更新。
依賴收集:
initState 時(shí),對(duì) computed 屬性初始化時(shí),觸發(fā) computed watcher 依賴收集
initState 時(shí),對(duì)偵聽(tīng)屬性初始化時(shí),觸發(fā) user watcher 依賴收集
render()的過(guò)程,觸發(fā) render watcher 依賴收集
re-render 時(shí),vm.render()再次執(zhí)行,會(huì)移除所有 subs 中的 watcer 的訂閱,重新賦值。
派發(fā)更新:
組件中對(duì)響應(yīng)的數(shù)據(jù)進(jìn)行了修改,觸發(fā) setter 的邏輯
調(diào)用 dep.notify()
遍歷所有的 subs(Watcher 實(shí)例),調(diào)用每一個(gè) watcher 的 update 方法。
原理:
當(dāng)創(chuàng)建 Vue 實(shí)例時(shí),vue 會(huì)遍歷 data 選項(xiàng)的屬性,利用 Object.defineProperty 為屬性添加 getter 和 setter 對(duì)數(shù)據(jù)的讀取進(jìn)行劫持(getter 用來(lái)依賴收集,setter 用來(lái)派發(fā)更新),并且在內(nèi)部追蹤依賴,在屬性被訪問(wèn)和修改時(shí)通知變化。
每個(gè)組件實(shí)例會(huì)有相應(yīng)的 watcher 實(shí)例,會(huì)在組件渲染的過(guò)程中記錄依賴的所有數(shù)據(jù)屬性(進(jìn)行依賴收集,還有 computed watcher,user watcher 實(shí)例),之后依賴項(xiàng)被改動(dòng)時(shí),setter 方法會(huì)通知依賴與此 data 的 watcher 實(shí)例重新計(jì)算(派發(fā)更新),從而使它關(guān)聯(lián)的組件重新渲染。
一句話總結(jié):
vue.js 采用數(shù)據(jù)劫持結(jié)合發(fā)布-訂閱模式,通過(guò) Object.defineproperty 來(lái)劫持各個(gè)屬性的 setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)響應(yīng)的監(jiān)聽(tīng)回調(diào)
易用: 簡(jiǎn)單,易學(xué),上手快
靈活: (漸進(jìn)式)不斷繁榮的生態(tài)系統(tǒng),可以在一個(gè)庫(kù)和一套完整框架之間自如伸縮。
高效: 20kB min+gzip 運(yùn)行大?。怀焯摂M DOM;最省心的優(yōu)化
雙向綁定:開(kāi)發(fā)效率高
基于組件的代碼共享
Web項(xiàng)目工程化,增加可讀性、可維護(hù)性
Vue.js 2.0 采用數(shù)據(jù)劫持(Proxy 模式)結(jié)合發(fā)布者-訂閱者模式(PubSub 模式)的方式,通過(guò) Object.defineProperty()來(lái)劫持各個(gè)屬性的 setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽(tīng)回調(diào)。
每個(gè)組件實(shí)例都有相應(yīng)的watcher程序?qū)嵗?,它?huì)在組件渲染的過(guò)程中把屬性記錄為依賴,之后當(dāng)依賴項(xiàng)的setter被調(diào)用時(shí),會(huì)通知watcher重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新。
Vue.js 3.0, 放棄了Object.defineProperty ,使用更快的ES6原生 Proxy (訪問(wèn)對(duì)象攔截器, 也稱代理器)
步驟:
1.需要observe的數(shù)據(jù)對(duì)象進(jìn)行遞歸遍歷,包括子屬性對(duì)象的屬性,都加上setter和getter這樣的話,給這個(gè)對(duì)象的某個(gè)值賦值,就會(huì)觸發(fā)setter,那么就能監(jiān)聽(tīng)到了數(shù)據(jù)變化
2.compile解析模板指令,將模板中的變量替換成數(shù)據(jù),然后初始化渲染頁(yè)面視圖,并將每個(gè)指令對(duì)應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽(tīng)數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動(dòng),收到通知,更新視圖
3.Watcher訂閱者是Observer和Compile之間通信的橋梁,主要做的事情是: ①在自身實(shí)例化時(shí)往屬性訂閱器(dep)里面添加自己 ②自身必須有一個(gè)update()方法 ③待屬性變動(dòng)dep.notice()通知時(shí),能調(diào)用自身的update()方法,并觸發(fā)Compile中綁定的回調(diào),則功成身退。
4.MVVM作為數(shù)據(jù)綁定的入口,整合Observer、Compile和Watcher三者,通過(guò)Observer來(lái)監(jiān)聽(tīng)自己的model數(shù)據(jù)變化,通過(guò)Compile來(lái)解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 -> 視圖更新;視圖交互變化(input) -> 數(shù)據(jù)model變更的雙向綁定效果。
比如現(xiàn)在需要監(jiān)控data中, obj.a 的變化。Vue中監(jiān)控對(duì)象屬性的變化你可以這樣:
watch: { obj: { handler (newValue, oldValue) { console.log('obj changed') }, deep: true }
deep屬性表示深層遍歷,但是這么寫會(huì)監(jiān)控obj的所有屬性變化,并不是我們想要的效果,所以做點(diǎn)修改:
watch: { 'obj.a': { handler (newName, oldName) { console.log('obj.a changed') } } }
還有一種方法,可以通過(guò)computed 來(lái)實(shí)現(xiàn),只需要:
computed: { a1 () { return this.obj.a } }
利用計(jì)算屬性的特性來(lái)實(shí)現(xiàn),當(dāng)依賴改變時(shí),便會(huì)重新計(jì)算一個(gè)新值。
Object.defineProperty缺陷
1.監(jiān)控到數(shù)組下標(biāo)的變化時(shí),開(kāi)銷很大。所以Vue.js放棄了下標(biāo)變化的檢測(cè);
2.Object.defineProperty只能劫持對(duì)象的屬性,而Proxy是直接代理對(duì)象。3.Object.defineProperty需要遍歷對(duì)象的每個(gè)屬性,如果屬性值也是對(duì)象,則需要深度遍歷。而 Proxy 直接代理對(duì)象,不需要遍歷操作。
4.Object.defineProperty對(duì)新增屬性需要手動(dòng)進(jìn)行Observe。vue2時(shí)需要使用 vm.$set 才能保證新增的屬性也是響應(yīng)式
5.Proxy支持13種攔截操作,這是defineProperty所不具有的
6.Proxy 作為新標(biāo)準(zhǔn),長(zhǎng)遠(yuǎn)來(lái)看,JS引擎會(huì)繼續(xù)優(yōu)化 Proxy,但 getter 和 setter 基本不會(huì)再有針對(duì)性優(yōu)化
視圖并未刷新。這是因?yàn)樵赩ue實(shí)例創(chuàng)建時(shí),新屬性并未聲明,因此就沒(méi)有被Vue轉(zhuǎn)換為響應(yīng)式的屬性,自然就不會(huì)觸發(fā)視圖的更新,這時(shí)就需要使用Vue的全局 api $set():
this.$set(this.obj, 'new_property', 'new_value')
computed 計(jì)算屬性 : 依賴其它屬性值,并且 computed 的值有緩存,只有它依賴的 屬性值發(fā)生改變,下一次獲取 computed 的值時(shí)才會(huì)重新計(jì)算 computed 的值。
watch 偵聽(tīng)器 : 更多的是觀察的作用,無(wú)緩存性,類似于某些數(shù)據(jù)的監(jiān)聽(tīng)回調(diào),每 當(dāng)監(jiān)聽(tīng)的數(shù)據(jù)變化時(shí)都會(huì)執(zhí)行回調(diào)進(jìn)行后續(xù)操作。
運(yùn)用場(chǎng)景:
1.當(dāng)我們需要進(jìn)行數(shù)值計(jì)算,并且依賴于其它數(shù)據(jù)時(shí),應(yīng)該使用 computed,因?yàn)榭梢岳?computed 的緩存特性,避免每次獲取值時(shí),都要重新計(jì)算。
2.當(dāng)我們需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或開(kāi)銷較大的操作時(shí),應(yīng)該使用 watch,使用 watch 選項(xiàng)允許我們執(zhí)行異步操作 ( 訪問(wèn)一個(gè) API ),限制我們執(zhí)行該操作的頻率, 并在我們得到最終結(jié)果前,設(shè)置中間狀態(tài)。這些都是計(jì)算屬性無(wú)法做到的。
3.多個(gè)因素影響一個(gè)顯示,用Computed;一個(gè)因素的變化影響多個(gè)其他因素、顯示,用Watch;
1.computed: 計(jì)算屬性是基于它們的依賴進(jìn)行緩存的,只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值對(duì)于 method ,只要發(fā)生重新渲染,
2.method 調(diào)用總會(huì)執(zhí)行該函數(shù)
1.讓我們不用直接操作DOM元素,只操作數(shù)據(jù)便可以重新渲染頁(yè)面
2.虛擬dom是為了解決瀏覽器性能問(wèn)題而被設(shè)計(jì)出來(lái)的
當(dāng)操作數(shù)據(jù)時(shí),將改變的dom元素緩存起來(lái),都計(jì)算完后再通過(guò)比較映射到真實(shí)的dom樹上
3.diff算法比較新舊虛擬dom。如果節(jié)點(diǎn)類型相同,則比較數(shù)據(jù),修改數(shù)據(jù);如果節(jié)點(diǎn)不同,直接干掉節(jié)點(diǎn)及所有子節(jié)點(diǎn),插入新的節(jié)點(diǎn);如果給每個(gè)節(jié)點(diǎn)都設(shè)置了唯一的key,就可以準(zhǔn)確的找到需要改變的內(nèi)容,否則就會(huì)出現(xiàn)修改一個(gè)地方導(dǎo)致其他地方都改變的情況。比如A-B-C-D, 我要插入新節(jié)點(diǎn)A-B-M-C-D,實(shí)際上改變的了C和D。但是設(shè)置了key,就可以準(zhǔn)確的找到B C并插入
1.具備跨平臺(tái)的優(yōu)勢(shì)
2.操作 DOM 慢,js運(yùn)行效率高。我們可以將DOM對(duì)比操作放在JS層,提高效率。
3.提升渲染性能
在Vue中使用filters來(lái)過(guò)濾(格式化)數(shù)據(jù),filters不會(huì)修改數(shù)據(jù),而是過(guò)濾(格式化)數(shù)據(jù),改變用戶看到的輸出(計(jì)算屬性 computed ,方法 methods 都是通過(guò)修改數(shù)據(jù)來(lái)處理數(shù)據(jù)格式的輸出顯示。
使用場(chǎng)景: 比如需要處理時(shí)間、數(shù)字等的的顯示格式;
1)
.stop
:等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡;
2).prevent
:等同于 JavaScript 中的 event.preventDefault() ,防止執(zhí)行預(yù)設(shè)的行為(如果事件可取消,則取消該事件,而不停止事件的進(jìn)一步傳播);
3).capture
:當(dāng)元素發(fā)生冒泡時(shí),先觸發(fā)帶有該修飾符的元素。若有多個(gè)該修飾符,則由外而內(nèi)觸發(fā)。如 p1中嵌套p2中嵌套p3.capture中嵌套p4,那么執(zhí)行順序?yàn)椋簆3=》p4=》p2=》p1
4).self
:只會(huì)觸發(fā)自己范圍內(nèi)的事件,不包含子元素;
5).once
:只會(huì)觸發(fā)一次。
v-show 僅僅控制元素的顯示方式,將 display 屬性在 block 和 none 來(lái)回切換;而v-if會(huì)控制這個(gè) DOM 節(jié)點(diǎn)的存在與否。當(dāng)我們需要經(jīng)常切換某個(gè)元素的顯示/隱藏時(shí),使用v-show會(huì)更加節(jié)省性能上的開(kāi)銷;當(dāng)只需要一次顯示或隱藏時(shí),使用v-if更加合理。
作用在表單元素上v-model="message"等同于v-bind:value=“message” v-on:input="message=e v e n t . t a r g e t . v a l u e " 作 用 在 組 件 上 , 本 質(zhì) 是 一 個(gè) 父 子 組 件 通 信 的 語(yǔ) 法 糖 ,通過(guò)prop和.emit實(shí)現(xiàn), 等同于:value="message" @input=" $emit('input', $event.target.value)"
JavaScript中的對(duì)象是引用類型的數(shù)據(jù),當(dāng)多個(gè)實(shí)例引用同一個(gè)對(duì)象時(shí),只要一個(gè)實(shí)例對(duì)這個(gè)對(duì)象進(jìn)行操作,其他實(shí)例中的數(shù)據(jù)也會(huì)發(fā)生變化。
而在Vue中,我們更多的是想要復(fù)用組件,那就需要每個(gè)組件都有自己的數(shù)據(jù),這樣組件之間才不會(huì)相互干擾。
所以組件的數(shù)據(jù)不能寫成對(duì)象的形式,而是要寫成函數(shù)的形式。數(shù)據(jù)以函數(shù)返回值的形式定義,這樣當(dāng)我們每次復(fù)用組件的時(shí)候,就會(huì)返回一個(gè)新的data,也就是說(shuō)每個(gè)組件都有自己的私有數(shù)據(jù)空間,它們各自維護(hù)自己的數(shù)據(jù),不會(huì)干擾其他組件的正常運(yùn)行。
1.調(diào)用parse方法將template轉(zhuǎn)化為ast(抽象語(yǔ)法樹, abstract syntax tree)
2.對(duì)靜態(tài)節(jié)點(diǎn)做優(yōu)化。如果為靜態(tài)節(jié)點(diǎn),他們生成的DOM永遠(yuǎn)不會(huì)改變,這對(duì)運(yùn)行時(shí)模板更新起到了極大的優(yōu)化作用。
3.生成渲染函數(shù). 渲染的返回值是VNode,VNode是Vue的虛擬DOM節(jié)點(diǎn),里面有(標(biāo)簽名,子節(jié)點(diǎn),文本等等)
調(diào)用parse方法將template轉(zhuǎn)化為ast(抽象語(yǔ)法樹, abstract syntax tree)
對(duì)靜態(tài)節(jié)點(diǎn)做優(yōu)化。如果為靜態(tài)節(jié)點(diǎn),他們生成的DOM永遠(yuǎn)不會(huì)改變,這對(duì)運(yùn)行時(shí)模板更新起到了極大的優(yōu)化作用。
生成渲染函數(shù). 渲染的返回值是VNode,VNode是Vue的虛擬DOM節(jié)點(diǎn),里面有(標(biāo)簽名,子節(jié)點(diǎn),文本等等)
易用、簡(jiǎn)潔且高效的http庫(kù), 支持node端和瀏覽器端,支持Promise,支持?jǐn)r截器等高級(jí)配置。
sass是一種CSS預(yù)編譯語(yǔ)言安裝和使用步驟如下。
1.用npm安裝加載程序( sass-loader、 css-loader等加載程序)。
2.在 webpack.config.js中配置sass加載程序。
Vue. js提供了一個(gè)v-cloak
指令,該指令一直保持在元素上,直到關(guān)聯(lián)實(shí)例結(jié)束編譯。當(dāng)和CSS一起使用時(shí),這個(gè)指令可以隱藏未編譯的標(biāo)簽,直到實(shí)例編譯結(jié)束。用法如下
在開(kāi)發(fā)業(yè)務(wù)時(shí),經(jīng)常會(huì)岀現(xiàn)異步獲取數(shù)據(jù)的情況,有時(shí)數(shù)據(jù)層次比較深,如以下代碼: <span 'v-text=“a.b.c.d”>, 可以使用vm.$set手動(dòng)定義一層數(shù)據(jù):
vm.$set("demo",a.b.c.d)
config/ index.js內(nèi)對(duì) proxyTable項(xiàng)配置代理。
Vue 在修改數(shù)據(jù)后,視圖不會(huì)立刻更新,而是等同一事件循環(huán)中的所有數(shù)據(jù)變化完成之后,再統(tǒng)一進(jìn)行視圖更新。
換句話說(shuō),只要觀察到數(shù)據(jù)變化,就會(huì)自動(dòng)開(kāi)啟一個(gè)隊(duì)列,并緩沖在同一個(gè)事件循環(huán)中發(fā)生的所以數(shù)據(jù)改變。在緩沖時(shí)會(huì)去除重復(fù)數(shù)據(jù),從而避免不必要的計(jì)算和 DOM 操作。
1.vue 用異步隊(duì)列的方式來(lái)控制 DOM 更新和 nextTick 回調(diào)先后執(zhí)行
2.microtask 因?yàn)槠涓邇?yōu)先級(jí)特性,能確保隊(duì)列中的微任務(wù)在一次事件循環(huán)前被執(zhí)行完畢
因?yàn)榻M件是可以復(fù)用的,JS 里對(duì)象是引用關(guān)系,如果組件 data 是一個(gè)對(duì)象,那么子組件中的 data 屬性值會(huì)互相污染。
所以一個(gè)組件的 data 選項(xiàng)必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝。
由于v-for的優(yōu)先級(jí)比v-if高,所以導(dǎo)致每循環(huán)一次就會(huì)去v-if一次,而v-if是通過(guò)創(chuàng)建和銷毀dom元素來(lái)控制元素的顯示與隱藏,所以就會(huì)不停的去創(chuàng)建和銷毀元素,造成頁(yè)面卡頓,性能下降。
解決辦法:
1.在v-for的外層或內(nèi)層包裹一個(gè)元素來(lái)使用v-if
2.用computed處理
1.v-model 多用于表單元素實(shí)現(xiàn)雙向數(shù)據(jù)綁定(同angular中的ng-model)
2.v-bind 動(dòng)態(tài)綁定 作用: 及時(shí)對(duì)頁(yè)面的數(shù)據(jù)進(jìn)行更改
3.v-on:click 給標(biāo)簽綁定函數(shù),可以縮寫為@,例如綁定一個(gè)點(diǎn)擊函數(shù) 函數(shù)必須寫在methods里面
4.v-for 格式: v-for=“字段名 in(of) 數(shù)組json” 循環(huán)數(shù)組或json(同angular中的ng-repeat)
5.v-show 顯示內(nèi)容 (同angular中的ng-show)
6.v-hide 隱藏內(nèi)容(同angular中的ng-hide)
7.v-if 顯示與隱藏 (dom元素的刪除添加 同angular中的ng-if 默認(rèn)值為false)
8.v-else-if 必須和v-if連用
9.v-else 必須和v-if連用 不能單獨(dú)使用 否則報(bào)錯(cuò) 模板編譯錯(cuò)誤
10.v-text 解析文本
11.v-html 解析html標(biāo)簽
12.v-bind:class 三種綁定方法 1、對(duì)象型 ‘{red:isred}’ 2、三元型 ‘isred?“red”:“blue”’ 3、數(shù)組型 ‘[{red:“isred”},{blue:“isblue”}]’
13.v-once 進(jìn)入頁(yè)面時(shí) 只渲染一次 不在進(jìn)行渲染
14.v-cloak 防止閃爍
15.v-pre 把標(biāo)簽內(nèi)部的元素原位輸出
1.父?jìng)髯樱鹤咏M件通過(guò)props[‘xx’] 來(lái)接收父組件傳遞的屬性 xx 的值
2.子傳父:子組件通過(guò) this.$emit(‘fnName’,value) 來(lái)傳遞,父組件通過(guò)接收 fnName 事件方法來(lái)接收回調(diào)
3.其他方式:通過(guò)創(chuàng)建一個(gè)bus,進(jìn)行傳值
4.使用Vuex
當(dāng) Vue.js 用 v-for 正在更新已渲染過(guò)的元素列表時(shí),它默認(rèn)用“就地復(fù)用”策略。如果數(shù)據(jù)項(xiàng)的順序被改變,Vue 將不會(huì)移動(dòng) DOM 元素來(lái)匹配數(shù)據(jù)項(xiàng)的順序, 而是簡(jiǎn)單復(fù)用此處每個(gè)元素,并且確保它在特定索引下顯示已被渲染過(guò)的每個(gè)元素。key的作用主要是為了高效的更新虛擬DOM
Object.defineProperty
本身有一定的監(jiān)控到數(shù)組下標(biāo)變化的能力,但是在 Vue 中,從性能/體驗(yàn)的性價(jià)比考慮,尤大大就棄用了這個(gè)特性(Vue 為什么不能檢測(cè)數(shù)組變動(dòng) )。為了解決這個(gè)問(wèn)題,經(jīng)過(guò) vue 內(nèi)部處理后可以使用以下幾種方法來(lái)監(jiān)聽(tīng)數(shù)組
push();
pop();
shift();
unshift();
splice();
sort();
reverse();
由于只針對(duì)了以上 7 種方法進(jìn)行了 hack 處理,所以其他數(shù)組的屬性也是檢測(cè)不到的,還是具有一定的局限性。
Object.defineProperty 只能劫持對(duì)象的屬性,因此我們需要對(duì)每個(gè)對(duì)象的每個(gè)屬性進(jìn)行遍歷。Vue 2.x 里,是通過(guò) 遞歸 + 遍歷 data 對(duì)象來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)的監(jiān)控的,如果屬性值也是對(duì)象那么需要深度遍歷,顯然如果能劫持一個(gè)完整的對(duì)象是才是更好的選擇。
Proxy 可以劫持整個(gè)對(duì)象,并返回一個(gè)新的對(duì)象。Proxy 不僅可以代理對(duì)象,還可以代理數(shù)組。還可以代理動(dòng)態(tài)增加的屬性。
JS 運(yùn)行機(jī)制
JS 執(zhí)行是單線程的,它是基于事件循環(huán)的。事件循環(huán)大致分為以下幾個(gè)步驟:
所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。
主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開(kāi)始執(zhí)行。
主線程不斷重復(fù)上面的第三步。
主線程的執(zhí)行過(guò)程就是一個(gè) tick,而所有的異步結(jié)果都是通過(guò) “任務(wù)隊(duì)列” 來(lái)調(diào)度。 消息隊(duì)列中存放的是一個(gè)個(gè)的任務(wù)(task)。 規(guī)范中規(guī)定 task 分為兩大類,分別是 macro task 和 micro task,并且每個(gè) macro task 結(jié)束后,都要清空所有的 micro task。
for (macroTask of macroTaskQueue) { // 1. Handle current MACRO-TASK handleMacroTask(); // 2. Handle all MICRO-TASK for (microTask of microTaskQueue) { handleMicroTask(microTask); }}
在瀏覽器環(huán)境中 :
常見(jiàn)的 macro task 有 setTimeout、MessageChannel、postMessage、setImmediate
常見(jiàn)的 micro task 有 MutationObsever 和 Promise.then
異步更新隊(duì)列
可能你還沒(méi)有注意到,Vue 在更新 DOM 時(shí)是異步執(zhí)行的。只要偵聽(tīng)到數(shù)據(jù)變化,Vue 將開(kāi)啟一個(gè)隊(duì)列,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)變更。
如果同一個(gè) watcher 被多次觸發(fā),只會(huì)被推入到隊(duì)列中一次。這種在緩沖時(shí)去除重復(fù)數(shù)據(jù)對(duì)于避免不必要的計(jì)算和 DOM 操作是非常重要的。
然后,在下一個(gè)的事件循環(huán)“tick”中,Vue 刷新隊(duì)列并執(zhí)行實(shí)際 (已去重的) 工作。
Vue 在內(nèi)部對(duì)異步隊(duì)列嘗試使用原生的 Promise.then、MutationObserver 和 setImmediate,如果執(zhí)行環(huán)境不支持,則會(huì)采用 setTimeout(fn, 0) 代替。
在 vue2.5 的源碼中,macrotask 降級(jí)的方案依次是:setImmediate、MessageChannel、setTimeout
vue 的 nextTick 方法的實(shí)現(xiàn)原理:
vue 用異步隊(duì)列的方式來(lái)控制 DOM 更新和 nextTick 回調(diào)先后執(zhí)行
microtask 因?yàn)槠涓邇?yōu)先級(jí)特性,能確保隊(duì)列中的微任務(wù)在一次事件循環(huán)前被執(zhí)行完畢
考慮兼容問(wèn)題,vue 做了 microtask 向 macrotask 的降級(jí)方案
Vue 事件機(jī)制 本質(zhì)上就是 一個(gè) 發(fā)布-訂閱 模式的實(shí)現(xiàn)。
class Vue { constructor() { // 事件通道調(diào)度中心 this._events = Object.create(null); } $on(event, fn) { if (Array.isArray(event)) { event.map(item => { this.$on(item, fn); }); } else { (this._events[event] || (this._events[event] = [])).push(fn); } return this; } $once(event, fn) { function on() { this.$off(event, on); fn.apply(this, arguments); } on.fn = fn; this.$on(event, on); return this; } $off(event, fn) { if (!arguments.length) { this._events = Object.create(null); return this; } if (Array.isArray(event)) { event.map(item => { this.$off(item, fn); }); return this; } const cbs = this._events[event]; if (!cbs) { return this; } if (!fn) { this._events[event] = null; return this; } let cb; let i = cbs.length; while (i--) { cb = cbs[i]; if (cb === fn || cb.fn === fn) { cbs.splice(i, 1); break; } } return this; } $emit(event) { let cbs = this._events[event]; if (cbs) { const args = [].slice.call(arguments, 1); cbs.map(item => { args ? item.apply(this, args) : item.call(this); }); } return this; }}
三種:
一種是全局導(dǎo)航鉤子:router.beforeEach(to,from,next),作用:跳轉(zhuǎn)前進(jìn)行判斷攔截。第二種:組件內(nèi)的鉤子;第三種:?jiǎn)为?dú)路由獨(dú)享組件
vue框架中狀態(tài)管理。在main.js引入store,注入。新建了一個(gè)目錄store,…… export 。
場(chǎng)景有:?jiǎn)雾?yè)應(yīng)用中,組件之間的狀態(tài)。音樂(lè)播放、登錄狀態(tài)、加入購(gòu)物車
MVVM和MVC都是一種設(shè)計(jì)思想,主要就是MVC中的Controller演變成ViewModel,,MVVM主要通過(guò)數(shù)據(jù)來(lái)顯示視圖層而不是操作節(jié)點(diǎn),解決了MVC中大量的DOM操作使頁(yè)面渲染性能降低,加載速度慢,影響用戶體驗(yàn)問(wèn)題。主要用于數(shù)據(jù)操作比較多的場(chǎng)景。
場(chǎng)景:數(shù)據(jù)操作比較多的場(chǎng)景,更加便捷
簡(jiǎn)而言之,就是先轉(zhuǎn)化成AST樹,再得到的渲染函數(shù)返回VNODE(Vue公司的虛擬DOM節(jié)點(diǎn))
詳情步驟:
首先,通過(guò)編譯編譯器把模板編譯成AST語(yǔ)法樹(抽象語(yǔ)法樹即源代碼的抽象語(yǔ)法結(jié)構(gòu)的樹狀表現(xiàn)形式),編譯是createCompiler的返回值,createCompiler是用以創(chuàng)建編譯器的。負(fù)責(zé)合并選項(xiàng)。
然后,AST會(huì)經(jīng)過(guò)生成(將AST語(yǔ)法樹轉(zhuǎn)化成渲染功能字符串的過(guò)程)得到渲染函數(shù),渲染的返回值是VNode,VNode是Vue的虛擬DOM節(jié)點(diǎn),里面有(標(biāo)簽名,子節(jié)點(diǎn),文本等等)
答:包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,主要用于保留組件狀態(tài)或避免重新渲染;
使用:簡(jiǎn)單頁(yè)面時(shí)
緩存: < keep-alive include=”組件名”>< /keep-alive>
不緩存: < keep-alive exclude=”組件名”>< /keep-alive>
相同點(diǎn):都鼓勵(lì)組件化,都有’props’的概念,都有自己的構(gòu)建工具,Reat與Vue只有框架的骨架,其他的功能如路由、狀態(tài)管理等是框架分離的組件。
不同點(diǎn):React:數(shù)據(jù)流單向,語(yǔ)法—JSX,在React中你需要使用setState()方法去更新?tīng)顟B(tài)。Vue:數(shù)據(jù)雙向綁定,語(yǔ)法–HTML,state對(duì)象并不是必須的,數(shù)據(jù)由data屬性在Vue對(duì)象中進(jìn)行管理。適用于小型應(yīng)用,但對(duì)于對(duì)于大型應(yīng)用而言不太適合。
參照大神文章:vue筆記 - 生命周期第二次學(xué)習(xí)與理解
beforeCreate
是new Vue()之后觸發(fā)的第一個(gè)鉤子,在當(dāng)前階段data、methods、computed以及watch上的數(shù)據(jù)和方法都不能被訪問(wèn)。
created
在實(shí)例創(chuàng)建完成后發(fā)生,當(dāng)前階段已經(jīng)完成了數(shù)據(jù)觀測(cè),也就是可以使用數(shù)據(jù),更改數(shù)據(jù),在這里更改數(shù)據(jù)不會(huì)觸發(fā)updated函數(shù)??梢宰鲆恍┏跏紨?shù)據(jù)的獲取,在當(dāng)前階段無(wú)法與Dom進(jìn)行交互,如果非要想,可以通過(guò)vm.$nextTick來(lái)訪問(wèn)Dom。
beforeMount
發(fā)生在掛載之前,在這之前template模板已導(dǎo)入渲染函數(shù)編譯。而當(dāng)前階段虛擬Dom已經(jīng)創(chuàng)建完成,即將開(kāi)始渲染。在此時(shí)也可以對(duì)數(shù)據(jù)進(jìn)行更改,不會(huì)觸發(fā)updated。
mounted
在掛載完成后發(fā)生,在當(dāng)前階段,真實(shí)的Dom掛載完畢,數(shù)據(jù)完成雙向綁定,可以訪問(wèn)到Dom節(jié)點(diǎn),使用$refs屬性對(duì)Dom進(jìn)行操作。
beforeUpdate發(fā)生在更新之前,也就是響應(yīng)式數(shù)據(jù)發(fā)生更新,虛擬dom重新渲染之前被觸發(fā),你可以在當(dāng)前階段進(jìn)行更改數(shù)據(jù),不會(huì)造成重渲染。
updated
發(fā)生在更新完成之后,當(dāng)前階段組件Dom已完成更新。要注意的是避免在此期間更改數(shù)據(jù),因?yàn)檫@可能會(huì)導(dǎo)致無(wú)限循環(huán)的更新。
beforeDestroy
發(fā)生在實(shí)例銷毀之前,在當(dāng)前階段實(shí)例完全可以被使用,我們可以在這時(shí)進(jìn)行善后收尾工作,比如清除計(jì)時(shí)器。
destroyed
發(fā)生在實(shí)例銷毀之后,這個(gè)時(shí)候只剩下了dom空殼。組件已被拆解,數(shù)據(jù)綁定被卸除,監(jiān)聽(tīng)被移出,子實(shí)例也統(tǒng)統(tǒng)被銷毀。
簡(jiǎn)單來(lái)說(shuō),diff算法有以下過(guò)程
1.同級(jí)比較,再比較子節(jié)點(diǎn)
2.先判斷一方有子節(jié)點(diǎn)一方?jīng)]有子節(jié)點(diǎn)的情況(如果新的children沒(méi)有子節(jié)點(diǎn),將舊的子節(jié)點(diǎn)移除)
3.比較都有子節(jié)點(diǎn)的情況(核心diff)
3.遞歸比較子節(jié)點(diǎn)
正常Diff兩個(gè)樹的時(shí)間復(fù)雜度是O(n^3)
,但實(shí)際情況下我們很少會(huì)進(jìn)行跨層級(jí)的移動(dòng)DOM,所以Vue將Diff進(jìn)行了優(yōu)化,從O(n^3) -> O(n)
,只有當(dāng)新舊children都為多個(gè)子節(jié)點(diǎn)時(shí)才需要用核心的Diff算法進(jìn)行同層級(jí)比較。
Vue2的核心Diff算法采用了雙端比較的算法,同時(shí)從新舊children的兩端開(kāi)始進(jìn)行比較,借助key值找到可復(fù)用的節(jié)點(diǎn),再進(jìn)行相關(guān)操作。相比React的Diff算法,同樣情況下可以減少移動(dòng)節(jié)點(diǎn)次數(shù),減少不必要的性能損耗,更加的優(yōu)雅。
Vue3.x借鑒了
ivi算法和 inferno算法
在創(chuàng)建VNode時(shí)就確定其類型,以及在 mount/patch 的過(guò)程中采用位運(yùn)算來(lái)判斷一個(gè)VNode的類型,在這個(gè)基礎(chǔ)之上再配合核心的Diff算法,使得性能上較Vue2.x有了提升。(實(shí)際的實(shí)現(xiàn)可以結(jié)合Vue3.x源碼看。)
該算法中還運(yùn)用了動(dòng)態(tài)規(guī)劃的思想求解最長(zhǎng)遞歸子序列。
編碼階段
1.盡量減少data中的數(shù)據(jù),data中的數(shù)據(jù)都會(huì)增加getter和setter,會(huì)收集對(duì)應(yīng)的2.watcher
3.v-if和v-for不能連用
4.如果需要使用v-for給每項(xiàng)元素綁定事件時(shí)使用事件代理
5.SPA 頁(yè)面采用keep-alive緩存組件
6.在更多的情況下,使用v-if替代v-show
7.key保證唯一
8.使用路由懶加載、異步組件
9.防抖、節(jié)流
10.第三方模塊按需導(dǎo)入
11.長(zhǎng)列表滾動(dòng)到可視區(qū)域動(dòng)態(tài)加載
12.圖片懶加載
SEO優(yōu)化
1.預(yù)渲染
2.服務(wù)端渲染SSR
打包優(yōu)化
1.壓縮代碼
2.Tree Shaking/Scope Hoisting
3.使用cdn加載第三方模塊
4.多線程打包happypack
5.splitChunks抽離公共文件
6.sourceMap優(yōu)化
用戶體驗(yàn)
1.骨架屏
2.PWA
還可以使用緩存(客戶端緩存、服務(wù)端緩存)優(yōu)化、服務(wù)端開(kāi)啟gzip壓縮等。
location.hash
的值實(shí)際就是URL中#后面的東西。
history
實(shí)際采用了HTML5中提供的API來(lái)實(shí)現(xiàn),主要有history.pushState()
和history.replaceState()
。
SPA( single-page application )僅在 Web 頁(yè)面初始化時(shí)加載相應(yīng)的 HTML、JavaScript 和 CSS
一旦頁(yè)面加載完成,SPA 不會(huì)因?yàn)橛脩舻牟僮鞫M(jìn)行頁(yè)面的重新加載或跳轉(zhuǎn)
取而代之的是利用路由機(jī)制實(shí)現(xiàn) HTML 內(nèi)容的變換, UI 與用戶的交互,避免頁(yè)面的重新加載
優(yōu)點(diǎn):
1、用戶體驗(yàn)好、快,內(nèi)容的改變不需要重新加載整個(gè)頁(yè)面,避免了不必要的跳轉(zhuǎn)和重復(fù)渲染
2、基于上面一點(diǎn),SPA 相對(duì)對(duì)服務(wù)器壓力小
3、前后端職責(zé)分離,架構(gòu)清晰,前端進(jìn)行交互邏輯,后端負(fù)責(zé)數(shù)據(jù)處理
缺點(diǎn):
1、初次加載耗時(shí)多:為實(shí)現(xiàn)單頁(yè) Web 應(yīng)用功能及顯示效果,
需要在加載頁(yè)面的時(shí)候?qū)?JavaScript、CSS 統(tǒng)一加載,部分頁(yè)面按需加載
2、前進(jìn)后退路由管理:由于單頁(yè)應(yīng)用在一個(gè)頁(yè)面中顯示所有的內(nèi)容,
所以不能使用瀏覽器的前進(jìn)后退功能,所有的頁(yè)面切換需要自己建立堆棧管理
3、SEO 難度較大:由于所有的內(nèi)容都在一個(gè)頁(yè)面中動(dòng)態(tài)替換顯示,所以在 SEO 上其有著天然的弱勢(shì)
第一步:在components目錄新建你的組件文件(indexPage.vue),script一定要
export default {}
第二步:在需要用的頁(yè)面(組件)中導(dǎo)入:import indexPage from ‘@/components/indexPage.vue’
第三步:注入到vue的子組件的components屬性上面,components:{indexPage}
第四步:在template視圖view中使用,
例如有indexPage命名,使用的時(shí)候則index-page
webpack中提供了
require.ensure()
來(lái)實(shí)現(xiàn)按需加載。以前引入路由是通過(guò)import 這樣的方式引入,改為const定義的方式進(jìn)行引入。
不進(jìn)行頁(yè)面按需加載引入方式:import home from '../../common/home.vue'
進(jìn)行頁(yè)面按需加載的引入方式:const home = r => require.ensure( [], () => r (require('../../common/home.vue')))
以組件功能命名
只負(fù)責(zé)ui的展示和交互動(dòng)畫,不要在組件里與服務(wù)器打交道(獲取異步數(shù)據(jù)等)
可復(fù)用組件不會(huì)因組件使用的位置、場(chǎng)景而變化。盡量減少對(duì)外部條件的依賴。
在每一個(gè)Vue.js組件中都可以定義各自的CSS、 JavaScript代碼。如果希望組件內(nèi)寫的CSS只對(duì)當(dāng)前組件起作用,只需要在Style標(biāo)簽添加Scoped屬性即可
如果需要在組件切換的時(shí)候,保存一些組件的狀態(tài)防止多次渲染,就可以使用 keep-alive 組件包裹需要保存的組件。
兩個(gè)重要屬性,include 緩存組件名稱,exclude 不需要緩存的組件名稱。
對(duì)“src”屬性插值將導(dǎo)致404請(qǐng)求錯(cuò)誤。應(yīng)使用 v-bind:src (簡(jiǎn)寫:src)格式代替。
加載渲染過(guò)程:
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
子組件更新過(guò)程:父beforeUpdate->子beforeUpdate->子updated->父updated
父組件更新過(guò)程:父beforeUpdate->父updated
銷毀過(guò)程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
1.state => 基本數(shù)據(jù)
2.getters => 從基本數(shù)據(jù)派生的數(shù)據(jù)
3.mutations => 修改數(shù)據(jù),同步
4.actions => 修改數(shù)據(jù),異步 (Action 提交的是 mutation,而不是直接變更狀態(tài))
5.modules => 模塊化Vuex
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理器,采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),主要是為了多頁(yè)面、多組件之間的通信。
Vuex有5個(gè)重要的屬性,分別是 State、Getter、Mutation、Action、Module,由 view 層發(fā)起一個(gè) Action 給 Mutation,在 Mutation 中修改狀態(tài),返回新的狀態(tài),通過(guò) Getter暴露給 view層的組件或者頁(yè)面,頁(yè)面監(jiān)測(cè)到狀態(tài)改變于是更新頁(yè)面。如果你的項(xiàng)目很簡(jiǎn)單,最好不要使用 Vuex,對(duì)于大型項(xiàng)目,Vuex 能夠更好的幫助我們管理組件外部的狀態(tài),一般可以運(yùn)用在購(gòu)物車、登錄狀態(tài)、播放等場(chǎng)景中。
1.公共的數(shù)據(jù)部分可以提升至和他們最近的父組件,由父組件派發(fā)
2.公共數(shù)據(jù)可以放到vuex中統(tǒng)一管理,各組件分別獲取
1.如果請(qǐng)求來(lái)的數(shù)據(jù)是不是要被其他組件公用,僅僅在請(qǐng)求的組件內(nèi)使用,就不需要放入vuex 的state里。
2.如果被其他地方復(fù)用,這個(gè)很大幾率上是需要的,如果需要,請(qǐng)將請(qǐng)求放入action里,方便復(fù)用,并包裝成promise返回,在調(diào)用處用async await處理返回的數(shù)據(jù)。如果不要復(fù)用這個(gè)請(qǐng)求,那么直接寫在vue文件里很方便
actions與mutations作用類似,都是可以對(duì)狀態(tài)進(jìn)行修改。不同的是actions是異步操作的。
actions是可以調(diào)用Mutations里的方法的。
const actions={ addActions(context){ context.commit('add',10);//調(diào)用mutations中的方法 setTimeout(()=>{context.commit('reduce')},5000) // setTimeOut(()=>{context.commit('reduce')},3000); console.log('我比reduce提前執(zhí)行'); }, reduceActions({commit}){ commit('reduce'); }}
Mutation 更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個(gè) mutation 都有一個(gè)字符串的 事件類型 (type) 和 一個(gè) 回調(diào)函數(shù) (handler)。這個(gè)回調(diào)函數(shù)就是我們實(shí)際進(jìn)行狀態(tài)更改的地方,并且它會(huì)接受 state 作為第一個(gè)參數(shù)
const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { // 變更狀態(tài) state.count++ } }})
Action Action 類似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接變更狀態(tài)。
Action 可以包含任意異步操作
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } }})
使用mapState
輔助函數(shù), 利用對(duì)象展開(kāi)運(yùn)算符將state混入computed對(duì)象中
import {mapState} from 'vuex' export default{ computed:{ ...mapState(['price','number']) } }
對(duì)象是引用類型,復(fù)制后改變屬性還是會(huì)影響原始數(shù)據(jù),這樣會(huì)改變state里面的狀態(tài),是不允許,所以先用深度克隆復(fù)制對(duì)象,再修改。
1.Hash: 使用 URL 的 hash 值來(lái)作為路由。支持所有瀏覽器。 帶#。如:http://localhost:8080/#/pageA。改變hash,瀏覽器本身不會(huì)有任何請(qǐng)求服務(wù)器動(dòng)作的,但是頁(yè)面狀態(tài)和url已經(jīng)關(guān)聯(lián)起來(lái)了。
2.History: 以來(lái) HTML5 History API 和服務(wù)器配置。參考官網(wǎng)中 HTML5 History 模式,不帶#, 如:http://localhost:8080/ 正常的而路徑,并沒(méi)有#?;贖TML5的 pushState、replaceState實(shí)現(xiàn)
3.Abstract: 支持所有 javascript 運(yùn)行模式。如果發(fā)現(xiàn)沒(méi)有瀏覽器的 API,路由會(huì)自動(dòng)強(qiáng)制進(jìn)入這個(gè)模式。
通過(guò)children 數(shù)組:
const router = new VueRouter({ routes: [ { path: "/parentPage", component: testPage, children: [ { path: "/childrenA", component: childrenComponentA, }, { path: "/childrenB", component: childrenComponentB, }, ], }, { // 其他和parentPage平級(jí)的路由 }, ],});
1.全局導(dǎo)航鉤子:
router.beforeEach(to,from,next)
2.組件內(nèi)的鉤子beforeRouteEnter (to, from, next) beforeRouteUpdate (to, from, next) beforeRouteLeave (to, from, next)
3.單獨(dú)路由獨(dú)享組件beforeEnter: (to, from, next)
參數(shù):有to(去的那個(gè)路由)、from(離開(kāi)的路由)、next(一定要用這個(gè)函數(shù)才能去到下一個(gè)路由,如果不用就攔截)最常用就這幾種
1、$route
是“路由信息對(duì)象”,包括path,params,hash,query,fullPath,matched,name
等路由信息參數(shù)。
1.
$route.path
字符串,對(duì)應(yīng)當(dāng)前路由的路徑,總是解析為絕對(duì)路徑如"/foo/bar"。
2.$route.params
一個(gè) key/value 對(duì)象,包含了 動(dòng)態(tài)片段 和 全匹配片段, 如果沒(méi)有路由參數(shù),就是一個(gè)空對(duì)象。
3.$route.query
一個(gè) key/value 對(duì)象,表示 URL 查詢參數(shù)。 例如,對(duì)于路徑/foo?user=1
,則有$route.query.user == 1
, 如果沒(méi)有查詢參數(shù),則是個(gè)空對(duì)象
4.$route.hash
當(dāng)前路由的hash值 (不帶#) ,如果沒(méi)有 hash 值,則為空字符串
5.$route.fullPath
完成解析后的 URL,包含查詢參數(shù)和hash的完整路徑。
6.$route.matched
數(shù)組,包含當(dāng)前匹配的路徑中所包含的所有片段所對(duì)應(yīng)的配置參數(shù)對(duì)象。
7.$route.name
當(dāng)前路徑名字
8.$ route.meta
路由元信息
2、$router
是“路由實(shí)例”對(duì)象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等
實(shí)例方法:
1)、push
1.字符串
this.$router.push('home')
2. 對(duì)象this.$router.push({path:'home'})
3. 命名的路由this.$router.push({name:'user',params:{userId:123}})
4.帶查詢參數(shù),變成/register?plan=123this.$router.push({path:'register',query:{plan:'123'}})
push方法其實(shí)和< router-link :to=“…”>是等同的。
注意:push方法的跳轉(zhuǎn)會(huì)向 history 棧添加一個(gè)新的記錄,當(dāng)我們點(diǎn)擊瀏覽器的返回按鈕時(shí)可以看到之前的頁(yè)面。
2)、go
頁(yè)面路由跳轉(zhuǎn)
前進(jìn)或者后退this.$router.go(-1)
// 后退
3)、replace
push方法會(huì)向 history 棧添加一個(gè)新的記錄,而replace方法是替換當(dāng)前的頁(yè)面,
不會(huì)向 history 棧添加一個(gè)新的記錄
1.聲明式(標(biāo)簽跳轉(zhuǎn))
2.編程式( js跳轉(zhuǎn))
vue-router 模塊 的router-link組件
把不同路由對(duì)應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問(wèn)時(shí)才加載對(duì)應(yīng)的組件即為路由的懶加載,可以加快項(xiàng)目的加載速度,提高效率
const router = new VueRouter({ routes: [ { path: '/home', name: 'Home', component:() = import('../views/home') } ]})
在router目錄下的index.js文件中,對(duì)path屬性加上/:id
使用router對(duì)象的params id
關(guān)于“Vue.js面試題及答案有哪些”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Vue.js面試題及答案有哪些”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。