這篇文章主要介紹了Vue面試題及答案有哪些的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Vue面試題及答案有哪些文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
十多年的金山網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營(yíng)銷網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整金山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“金山網(wǎng)站設(shè)計(jì)”,“金山網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
答題思路:
Vue
生命周期是什么?
Vue
生命周期有哪些階段?
Vue
生命周期的流程?
結(jié)合實(shí)踐
擴(kuò)展:在 Vue3
變化 Vue
生命周期的變化
回答范例:
生命周期這個(gè)詞應(yīng)該是很好理解的,在我們生活中就會(huì)常常碰到,比如談到一個(gè)人的生命周期,我們會(huì)說(shuō)人這一生會(huì)經(jīng)歷嬰兒、兒童、少年、青年、中年、老年這幾個(gè)階段。
而 Vue
的生命周期也是如此,在 Vue
中的每個(gè)組件都會(huì)經(jīng)歷從創(chuàng)建到掛載到更新再到銷毀這幾個(gè)階段,而在這些階段中,Vue
會(huì)運(yùn)行一種叫做生命周期鉤子的函數(shù),方便我們?cè)谔囟ǖ碾A段有機(jī)會(huì)添加上我們自己的代碼。
Vue 生命周期總共可以分為 8
各階段:創(chuàng)建前后、掛載前后、更新前后、銷毀前后,以及一些特殊場(chǎng)景的生命周期(keep-alive
激活時(shí)、捕獲后代組件錯(cuò)誤時(shí))。Vue3
中還新增了三個(gè)用于調(diào)試和服務(wù)端渲染場(chǎng)景。
這幾個(gè)階段對(duì)應(yīng)的鉤子函數(shù) API依次為:beforeCreate
create
beforeMount
mounted
beforeUpdate
updated
activated(keep-alive 激活時(shí)調(diào)用)
deactivated(keep-alive 停用時(shí)調(diào)用)
beforeDestory
destoryed
errorCaptured(捕獲子孫組件錯(cuò)誤時(shí)調(diào)用)
。
在 Vue3 中的變化 絕大多數(shù)只要加上前綴 on 即可,比如 mounted
變?yōu)?onMounted
,除了 beforeDestroy
和 destroyed
被重新命名為 beforeUnmount
和 unMounted
(這樣與前面的 beforeMount
和 mounted
對(duì)應(yīng),強(qiáng)迫癥表示很贊?)
beforeCreate
在組件創(chuàng)建前調(diào)用,通常用于插件開發(fā)中執(zhí)行一些初始化任務(wù);created
組件創(chuàng)建完畢調(diào)用,可以訪問(wèn)各種數(shù)據(jù),請(qǐng)求接口數(shù)據(jù)等;mounted
組件掛載時(shí)調(diào)用 可以訪問(wèn)數(shù)據(jù)、dom
元素、子組件等;beforeUpdate
更新前調(diào)用 此時(shí) view
層還未更新,可用于獲取更新前的各種狀態(tài);updated
完成更新時(shí)調(diào)用 此時(shí)view層已經(jīng)完成更新,所有狀態(tài)已經(jīng)是最新的了;beforeUnmount
實(shí)例被銷毀前調(diào)用,可用于一些定時(shí)器或訂閱的取消;unMounted
銷毀一個(gè)實(shí)例時(shí)調(diào)用 可以清理與其他實(shí)例的鏈接,解綁它的全部指令以及事件監(jiān)聽器。
在 Vue3 中: setup
是比 created
先執(zhí)行的; 而且沒(méi)有 beforeCreate
和 created
。
權(quán)限管理一般需求就是對(duì)頁(yè)面權(quán)限和按鈕權(quán)限的管理
具體實(shí)現(xiàn)的時(shí)候分前端實(shí)現(xiàn)和后端實(shí)現(xiàn)兩種方案:
前端方案會(huì)把所有路由信息在前端配置,通過(guò)路由守衛(wèi)要求用戶登錄,用戶登錄后根據(jù)角色過(guò)濾出路由表,然后在動(dòng)態(tài)添加路由。比如我會(huì)配置一個(gè) asyncRoutes
數(shù)組,需要認(rèn)證的頁(yè)面在路由的 meta
中添加一個(gè) roles
字段,等獲取用戶角色之后取兩者的交集,若結(jié)果不為空則說(shuō)明可以訪問(wèn)。過(guò)濾結(jié)束后剩下的路由就是用戶能訪問(wèn)的頁(yè)面,最后通過(guò) router.addRoutes(accessRoutes)
方式動(dòng)態(tài)添加路由即可。
后端方案會(huì)把所有頁(yè)面路由信息存在數(shù)據(jù)庫(kù)中,用戶登錄的時(shí)候根據(jù)其角色查詢得到其能訪問(wèn)的所有路由信息返回給前端,前端再通過(guò) addRoute
動(dòng)態(tài)添加路由信息。
按鈕權(quán)限的控制通常會(huì)實(shí)現(xiàn)一個(gè)指令,例如 v-permission
,將按鈕要求角色通過(guò)值傳給 v-permission
指令,在指令的 mounted
鉤子中可以判斷當(dāng)前用戶角色和按鈕是否存在交集,有就保留按鈕,沒(méi)有就移除按鈕。
純前端方案的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,不需要額外權(quán)限管理頁(yè)面,但是維護(hù)起來(lái)問(wèn)題比較大,有新的頁(yè)面和角色需求就要修改前端代碼和重新打包部署;服務(wù)端方案就不存在這個(gè)問(wèn)題,通過(guò)專門的角色和權(quán)限管理頁(yè)面,配置頁(yè)面和按鈕權(quán)限信息到數(shù)據(jù)庫(kù),應(yīng)用每次登陸時(shí)獲取的都是最新的路由信息。
自己的話:權(quán)限管理一般分頁(yè)面權(quán)限和按鈕權(quán)限,而具體實(shí)現(xiàn)方案又分前端實(shí)現(xiàn)和后端實(shí)現(xiàn),前端實(shí)現(xiàn)就是會(huì)在前端維護(hù)一份動(dòng)態(tài)的路由數(shù)組,通過(guò)用戶登錄后的角色來(lái)篩選它所擁有權(quán)限的頁(yè)面,最后通過(guò) addRoute
將動(dòng)態(tài)添加到 router
中;而后端實(shí)現(xiàn)的不同點(diǎn)就是這些路由是后端返回給前端,前端再動(dòng)態(tài)添加進(jìn)去的。
按鈕權(quán)限一般會(huì)實(shí)現(xiàn)一個(gè) v-permission
,通過(guò)判斷用戶有沒(méi)有權(quán)限來(lái)控制按鈕是否顯示。
純前端方案的優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單,但是維護(hù)問(wèn)題大,有新的頁(yè)面和角色需求都需要改代碼重新打包部署,服務(wù)端則不存在這個(gè)問(wèn)題。
回答思路:
什么是雙向綁定?
雙向綁定的好處?
在什么地方使用雙向綁定?
雙向綁定的使用方式、使用細(xì)節(jié)、Vue3中的變化
原理實(shí)現(xiàn)描述
回答:
Vue中的雙向綁定是一個(gè)指令 v-model
,它可以綁定一個(gè)響應(yīng)式數(shù)據(jù)到視圖,同時(shí)視圖中變化也能改變?cè)撝怠?/p>
v-model
是一個(gè)語(yǔ)法糖,它的原理(默認(rèn)請(qǐng)情況下)就是通過(guò) :value
將變量掛到 dom
上,再通過(guò) input
事件 監(jiān)聽 dom
的變化改變變量的值。使用 v-model
的好處就是方便呀,減少了大量的繁瑣的事件處理,提高開發(fā)效率。
通常在表單上使用 v-model
,還可以在自定義組件上使用,表示某個(gè)值得輸入和輸出控制。
可以結(jié)合修飾符做進(jìn)一步限定(lazy/number/trim),用在自定義組件上時(shí)有些不同,它相當(dāng)于是給了子組件一個(gè) modelValue
的 屬性 和 update:modelValue
的 事件; 在 Vue3 中還可以用參數(shù)形式指定多個(gè)不同的綁定,如 v-model:foo
這個(gè)時(shí)候就相當(dāng)于 給了子組件一個(gè) foo
的 屬性 和 update:foo
的事件。
v-model
作為一個(gè)指令,它的原理就是 Vue 編譯器會(huì)把它轉(zhuǎn)換成 value屬性綁定和input的監(jiān)聽事件,上面說(shuō)過(guò)是默認(rèn)情況下,實(shí)際上編譯器會(huì)根據(jù)表單元素的不同分配不同的事件,比如 checkbox
和 radio
類型的input
會(huì)轉(zhuǎn)換為 checked
和 change
事件。
Vue 組件之間通信有以下這么幾種:
props
$emit
、$on
、$off
、$once
(后三者在Vue3中已被廢除)
$children
(Vue3中廢除)、$parent
$attrs
、$listeners
(Vue3中廢除)
ref
$root
eventbus
(Vue3中不好使了,需要自己封裝)
vuex
、pinia
provide + inject
以上的方法長(zhǎng)按使用場(chǎng)景可以分為:
父子組件之間可以使用
props
/$emit
/ $parent
/ ref
/$attrs
兄弟組件之間可以使用
$parent
/ $root
/ eventbus
/ vuex
跨層及組件之間可以使用
eventbus
/ vuex pinia
/ provide + inject
路由懶加載:有效拆分 App
尺寸,訪問(wèn)時(shí)才異步加載
const router = createRouter({
routes: [
{ path : '/foo', component: () => import('./foo.vue)}
]
})
keep-alive
緩存頁(yè)面:避免重復(fù)創(chuàng)建組件實(shí)例,且能保存緩存組件狀態(tài)
<keep-alive>
<router-view v-if="$route.meta.keepAlive == true"></router-view>
</keep-alive>
<router-view v-if="$route.meta.keepAlive != true"></router-view>
使用 v-show
復(fù)用 DOM
:避免重復(fù)創(chuàng)建組件
v-for
遍歷避免同時(shí)使用 v-if
(實(shí)際上這在 Vue3 中是錯(cuò)誤的寫法)
v-once
和 v-memo
: 不再變化的數(shù)據(jù)使用 v-once
;按條件跳過(guò)更新時(shí)使用 v-memo
長(zhǎng)列表性能優(yōu)化:如果是大數(shù)據(jù)長(zhǎng)列表,可采用虛擬滾動(dòng),只渲染少部分區(qū)域的內(nèi)容。一些開源庫(kù)(vue-virtual-scroller
/ vue-virtual-scroll-grid
)
事件的銷毀:Vue組件銷毀時(shí),會(huì)自動(dòng)解綁它的全部指令以及事件監(jiān)聽器,但是僅限于組件本身的事件。
圖片懶加載,自定義 v-lazy
指令 (參考項(xiàng)目:vue-lazyload
)
第三方插件按需引入 element-plus
避免體積太大
子組件分割策略:較重的狀態(tài)組件適合拆分
SSR
服務(wù)端渲染 解決首屏渲染慢的問(wèn)題
思路:
刷新后 Vuex 狀態(tài)為什么會(huì)丟失?
解決方法
第三方庫(kù)以及原理探討
個(gè)人理解
回答:
因?yàn)?Vuex 只是在內(nèi)存中保存狀態(tài),刷新后就會(huì)丟失,如果要持久化就要存起來(lái)。
可以是用 localStorage
存儲(chǔ) Vuex
的狀態(tài),store
中把值取出來(lái)作為 state
的初始值,提交 mutation
的時(shí)候就存入 localStorage
。
可以用 vuex-persist
、vuex-persistedstate
這種插件,可以通過(guò)插件選項(xiàng)控制哪些需要持久化。內(nèi)部的原理就是通過(guò)訂閱 mutation
變化做統(tǒng)一處理。
這里有兩個(gè)問(wèn)題,一是如果用戶手動(dòng)改了 localStorage
怎么辦?那我 Vuex
里的狀態(tài)不是也改變了?二是由于 localStorage API
的原因只能存儲(chǔ)字符串,所以我們只能將數(shù)據(jù)通過(guò) JSON.stringify
轉(zhuǎn)換為字符串,而當(dāng)我們存儲(chǔ)的數(shù)據(jù)為 Map
、Set
、Function
這種引用類型的數(shù)據(jù)時(shí),JSON.stringify
轉(zhuǎn)換后會(huì)變味 {}
而丟失。
對(duì)應(yīng)第一個(gè)問(wèn)題我的解決方法是可以通過(guò) 監(jiān)聽 storage
事件來(lái)清除數(shù)據(jù)
window.addEventListener("storage", function () {
localStorage.clear();
window.location.href = '/login'
console.error("不要修改localStorage的值~~~");
});
對(duì)于第二個(gè)問(wèn)題沒(méi)辦法了,只能選擇不適用 Map
和 Set
這種引用類型。
思路:
屬性攔截的幾種方式
defineProperty的問(wèn)題
Proxy的優(yōu)點(diǎn)
其他考量
回答:
JS
中做屬性攔截常見的方式有三種:defineProperty
、getter/setters
和 Proxy
Vue2
中使用 defineProperty
的原因是, 2013 年只能使用這種方式,由于該 API
存在一些局限性,比如對(duì)于數(shù)組的攔截有問(wèn)題,為此 Vue
需要專門為數(shù)組響應(yīng)式做一套實(shí)現(xiàn)。另外不能攔截那些新增、刪除屬性;最后 defineProperty
方案在初始化時(shí)需要深度遞歸遍歷處理對(duì)象才能對(duì)它進(jìn)行完全攔截,明顯增加了初始化的時(shí)間。
以上兩點(diǎn)在 Proxy
出現(xiàn)后迎刃而解,不僅可以對(duì)數(shù)組實(shí)現(xiàn)攔截,還能對(duì) Map
、Set
實(shí)現(xiàn)攔截;另外 Proxy
的攔截也是懶處理行為,如果用戶沒(méi)有訪問(wèn)嵌套對(duì)象,那么也不會(huì)實(shí)施攔截,這就讓初始化的速度和內(nèi)存占用改善了。
Proxy
有兼容性問(wèn)題,完全不支持IE
思路:
必要性
何時(shí)用
怎么用
使用細(xì)節(jié)
回答:
當(dāng)打包構(gòu)建時(shí),Javascript 抱回變得非常大,影響頁(yè)面加載。利用路由懶加載我們能把不同路由對(duì)應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問(wèn)的時(shí)候才加載對(duì)應(yīng)最賤,這樣更加高效,是一種優(yōu)化手段。
一般來(lái)說(shuō),對(duì)于所有的路由都使用動(dòng)態(tài)導(dǎo)入是個(gè)好主意
給 component
選項(xiàng)配置一個(gè)返回 Promise組件的函數(shù)就可以定義懶加載路由.例如:
{
path: '/login',
component: () => import('../views/login/Login.vue')
},
結(jié)合注釋
{
path: '/login',
component: () => import(/* webpackChunkName: "login" */'../views/login/Login.vue')
},
vite中結(jié)合rollupOptions定義分塊 5. 路由中不能使用異步組件
Vue-Router 有三個(gè)模式,其中 history 和 hash 更為常用。兩者差別主要在顯示形式和部署上,
hash模式在地址欄現(xiàn)實(shí)的時(shí)候有一個(gè) #
,這種方式使用和部署都較簡(jiǎn)單;history模式url看起來(lái)更優(yōu)雅沒(méi)關(guān),但是應(yīng)用在部署時(shí)需要做特殊配置,web服務(wù)器需要做回退處理,否則會(huì)出現(xiàn)刷新頁(yè)面404的問(wèn)題。
在實(shí)現(xiàn)上 hash
模式是監(jiān)聽hashchange
事件觸發(fā)路由跳轉(zhuǎn),history
模式是監(jiān)聽popstate
事件觸發(fā)路由跳轉(zhuǎn)。
在 Vue
中 nextTick
是等待下一次 DOM
更新刷新的工具方法。
Vue
有一個(gè)異步更新策略,意思是如果數(shù)據(jù)變化,Vue
不會(huì)立刻更新 DOM
,而是開啟一個(gè)隊(duì)列,把組件更新函數(shù)保存在隊(duì)列中,在同一時(shí)間循環(huán)中發(fā)生的所有數(shù)據(jù)變更會(huì)異步的批量更新。這一策略導(dǎo)致我們對(duì)數(shù)據(jù)的修改不會(huì)立刻體現(xiàn)在 DOM
上,此時(shí)如果想要獲取更新后的 DOM
狀態(tài),就需要使用 nextTick
nextTick
接受一個(gè)函數(shù),我們可以在這個(gè)函數(shù)內(nèi)部訪問(wèn)最新的 DOM
狀態(tài)
在開發(fā)時(shí),有兩個(gè)場(chǎng)景我們會(huì)用到 nextTick
:
created
中想要獲取 DOM
;
響應(yīng)式數(shù)據(jù)變化后獲取 DOM
更新后的狀態(tài);
nextTick
的原理:在 Vue
內(nèi)部,nextTick
之所以能夠讓我們看到 DOM
更新后的結(jié)果,是因?yàn)槲覀儌魅氲?callback
會(huì)被添加到隊(duì)列刷新函數(shù)的后面,這樣等隊(duì)列內(nèi)部的更新函數(shù)都執(zhí)行完畢,所有 DOM
操作也就結(jié)束了,callback
自然能夠獲取最新的 DOM
值。
先回答答案:在 vue2
中, v-for
的優(yōu)先級(jí)更高
但是在 vue3
中, v-if
的優(yōu)先級(jí)更高
拓展:無(wú)論什么時(shí)候,我們都不應(yīng)該把 v-for
和 v-if
放在一起,
怎么解決呢?一是可以定義一個(gè)計(jì)算屬性,讓 v-for
遍歷計(jì)算屬性。二是可以把 if
移到內(nèi)部容器里(ul
ol
)或者把v-for
移植外部容器(template
)中
vue2文檔vue3文檔
watch
store.subscribe()
watch
方式,可以以字符串形式監(jiān)聽 $store.state.xx
; subscribe
方法參數(shù)是一個(gè)回調(diào)函數(shù),回調(diào)函數(shù)接受mutation
對(duì)象和 state
對(duì)象,可以通過(guò) mutation.type
判斷監(jiān)聽的目標(biāo)。
wtach 方法更簡(jiǎn)單好用, subscribe
會(huì)略繁瑣,一般用 vuex
插件中(可以提一下vuex的持久化插件vuex-persist
、vuex-persistedstate
)
不支持持久化,頁(yè)面刷新狀態(tài)就會(huì)丟失
使用模塊比較繁瑣
不支持 ts
(或者說(shuō)很不友好)
vue3 + pinia 會(huì)是更好的組合。
兩者都能返回響應(yīng)式對(duì)象,ref
返回的是一個(gè)響應(yīng)式Ref
對(duì)象, reactive
返回的是響應(yīng)式代理對(duì)象。
ref
通常是處理單值得響應(yīng)式,reactive
用于處理對(duì)象類型的數(shù)據(jù)響應(yīng)式
ref
需要通過(guò) .value
訪問(wèn), 在視圖中會(huì)自動(dòng)脫 ref
,不需要 .value
,ref
可以接收對(duì)象或數(shù)組但內(nèi)部依然是 reactive
實(shí)現(xiàn)的;reactive
如果接收 Ref
對(duì)象會(huì)自動(dòng)脫 ref
;使用展開運(yùn)算符展開 reactive
返回的響應(yīng)式對(duì)象會(huì)使其失去響應(yīng)性,可以結(jié)合 toRefs()
將值轉(zhuǎn)換為 Ref
對(duì)象后再展開。
reactive
內(nèi)部使用 Prxoy
代理攔截對(duì)象各種操作,而 ref
內(nèi)部封裝一個(gè) RefImpl
類,設(shè)置 get value/set value
,攔截用戶對(duì)值得訪問(wèn)。
邏輯擴(kuò)展:mixins
、extends
、composition api
:
內(nèi)容擴(kuò)展:slots
mixins
很靈活,但是會(huì)沖突很混亂。extends
是一個(gè)不太常用的選項(xiàng),更 mixins
的不同是它只能擴(kuò)展單個(gè)對(duì)象,優(yōu)先級(jí)比 mixins
高。
混入的數(shù)據(jù)和方法 不能明確判斷來(lái)源而且可能和當(dāng)前組件內(nèi)變量 產(chǎn)生命名沖突,composition api 可以很好解決這些問(wèn)題,利用獨(dú)立出來(lái)的響應(yīng)式模塊可以很方便的編寫?yīng)毩⑦壿嫴⑻峁╉憫?yīng)式數(shù)據(jù)局,增強(qiáng)代碼的可讀性和維護(hù)性。
擴(kuò)展:Vue.mixin(全局混入) Vue.extend(有點(diǎn)像是 類/組件的繼承 創(chuàng)建一個(gè)子類)
vue-loader
是用于處理單文件組件(SFC)的webpack loader
因?yàn)橛辛?vue-loader
,我們才能用 .vue
文件形式編寫代碼,將代碼分割為 template
script
style
webpack
在打包的時(shí)候,會(huì)以 loader
的方式調(diào)用 vue-loader
vue-loader
被執(zhí)行時(shí),它會(huì)對(duì) SFC
中的每個(gè)語(yǔ)言塊用單獨(dú)的 loader
鏈處理,最后將這些單獨(dú)的塊裝配成最終的組件模塊
不能直接改。
組件化開發(fā)中有一個(gè)單向數(shù)據(jù)流原則,不在子組件修改父組件數(shù)據(jù)是個(gè)常識(shí)
如果你確實(shí)需要改,請(qǐng)通過(guò)emit向父組件發(fā)送一個(gè)事件,在父組件中修改
我么可以在路徑中使用一個(gè)動(dòng)態(tài)字段來(lái)實(shí)現(xiàn),例如/users/:id
其中 :id
就是路徑參數(shù)。
可以通過(guò) this.$route.parmas
獲取,參數(shù)還可以有多個(gè), $route
對(duì)象還公開了其他有用的信息如 query
hash
等。
思路:
什么是響應(yīng)式?
為什么vue需要響應(yīng)式?
有什么好處?
vue的響應(yīng)式怎么實(shí)現(xiàn)的,有哪些優(yōu)缺點(diǎn)?
vue3中的響應(yīng)式的新變化
回答:
數(shù)據(jù)響應(yīng)式就是 能夠監(jiān)測(cè)到數(shù)據(jù)變化并且做出響應(yīng)的一種機(jī)制
在 vue
中要解決的一個(gè)核心問(wèn)題就是連接數(shù)據(jù)層和視圖層,通過(guò)數(shù)據(jù)變化驅(qū)動(dòng)視圖更新,要做到這點(diǎn)就需要對(duì)數(shù)據(jù)做響應(yīng)式處理。
通過(guò)數(shù)據(jù)響應(yīng)式加上虛擬 DOM
和 patch
算法,我們只需要操作數(shù)據(jù),關(guān)心業(yè)務(wù),完全不需要接觸繁瑣的 DOM
操作,打打提升了開發(fā)效率,降低開發(fā)難度。
vue2
中實(shí)現(xiàn)數(shù)據(jù)響應(yīng)式的核心就是通過(guò) Object.defineProperty()
方法對(duì)數(shù)據(jù)進(jìn)行攔截,當(dāng) get
數(shù)據(jù)時(shí)做依賴收集 set
數(shù)據(jù)時(shí)做更新通知。這種機(jī)制很好的及絕了數(shù)據(jù)響應(yīng)式的問(wèn)題,但是實(shí)際使用也存在缺點(diǎn),比如在初始化時(shí)的遞歸遍歷會(huì)造成性能損失;無(wú)法監(jiān)聽新增或刪除屬性,在 vue
中要通過(guò)像 Vue.set/delete
這種特定的 API
才能實(shí)現(xiàn)對(duì)對(duì)象數(shù)組屬性的添加和刪除,而且也不支持 Ma
、Set
這些數(shù)據(jù)結(jié)構(gòu),
為了解決這些問(wèn)題,Vue3
重寫了這部分實(shí)現(xiàn),利用的是 ES6
中的 Proxy
代理要響應(yīng)化的數(shù)據(jù)。它有很多好處,初始化性能和內(nèi)存都大幅改善,也不需要特殊的 API
,但是不支持 IE
瀏覽器。
問(wèn) template
到 render
的過(guò)程其實(shí)是問(wèn)的 vue 編譯器
工作原理。
思路:
引入編譯器概念
說(shuō)明編譯器的必要性
闡述編譯器工作流程
回答:
Vue
中有個(gè)獨(dú)特的編譯模塊,稱為 compiler
,它的主要作用是將 template
編譯為 js
可執(zhí)行的 render
函數(shù)
之所以需要這個(gè)編譯過(guò)程是為了便于我們高校的編寫試圖模版。相比而言,我們還是更愿意用 HTML
來(lái)編寫視圖,直觀且高效。手寫 render
函數(shù)不僅效率低下,而且失去了被編譯器的優(yōu)化能力。
Vue
編譯器 首先會(huì)對(duì) template進(jìn)行解析
( Parse
),結(jié)束后會(huì)得到一個(gè)抽象語(yǔ)法樹AST
,然后對(duì) AST
進(jìn)行深加工轉(zhuǎn)換(transform
),最后將得到的 AST
生成為 js
代碼,也就是 render
函數(shù)
緩存組件可以使用 keep-alive
組件,include 和 exclude 可以指定包含不包含哪些組件。
Vue3
結(jié)合 vue-router
使用變化非常大,之前是 keep-alive
包含 router-view
,現(xiàn)在是 router-view
包含 keep-alive
緩存后如果想要獲取數(shù)據(jù)可以使用 actived
鉤子 或者 beforeRouteEnter
( vue-router
的一個(gè)守衛(wèi))
keep-alive
是一個(gè)通用組件,它內(nèi)部定義了一個(gè) map
,緩存創(chuàng)建過(guò)的組件實(shí)例,它返回的渲染函數(shù)內(nèi)部會(huì)查找內(nèi)嵌的 component
組件對(duì)應(yīng)組件的 vnode
,如果改組件在map中存在就直接返回它。由于 component
的 is
屬性是一個(gè)響應(yīng)式數(shù)據(jù),因此只要它變化,keep-alive
的 render
函數(shù)就會(huì)重新執(zhí)行。
虛擬 DOM
是什么?
虛擬 DOM
的本質(zhì)就是一個(gè) Javascript
對(duì)象。
為什么要引入虛擬 DOM
?(好處)
它能有效減少操作 DOM
的次數(shù),方便實(shí)現(xiàn)跨平臺(tái)
虛擬DOM如何生成?compiler
編譯器會(huì)把 template
模版編譯成渲染函數(shù),接下來(lái)在 mount
掛載的過(guò)程會(huì)調(diào)用這個(gè)渲染函數(shù),返回的對(duì)象就是 虛擬DOM
。掛載結(jié)束后,會(huì)進(jìn)入更新流程。如果某些響應(yīng)式數(shù)據(jù)發(fā)生變化,將會(huì)引起組件重新 render
,此時(shí)會(huì)生成新的 虛擬DOM
,和上次渲染結(jié)果做 diff
操作,最小量的操作 dom
,從而高效更新視圖。
異步組件就是不會(huì)立即加載而是會(huì)在需要的時(shí)候加載的組件。在大型應(yīng)用中,我們需要分割代碼為更小的塊試就可以用異步組件。
不僅可以在路由切換時(shí)懶加載組件,還可以在組件中使用異步組件,從而更細(xì)的分割代碼。
使用異步組件最簡(jiǎn)單的方式是直接給 defineAsyncComponet
指定一個(gè) loader
函數(shù),結(jié)合 ES 模塊 動(dòng)態(tài)導(dǎo)入函數(shù) import
可以快速實(shí)現(xiàn)。Vue3
還可以結(jié)合 Suspense
組件使用異步組件。
異步組件容易和路由懶加載混淆,實(shí)際上不是一個(gè)東西。異步組件不能被用于定義懶加載路由上,處理它的是 Vue
框架,處理路由組件加載的是 vue-router
。但是可以在懶加載的路由組件中使用異步組件。
避免大數(shù)據(jù)量:可以采用分頁(yè)的方式獲取
避免渲染大量數(shù)據(jù):vue-virtual-scroller等虛擬滾動(dòng)方案,只渲染視口范圍內(nèi)的數(shù)據(jù)
避免更新:可以使用v-once
方式只渲染一次
優(yōu)化更新:通過(guò)v-memo緩存組數(shù),有條件更新,提高服用,避免不必要更新
按需加載數(shù)據(jù):可以采用 懶加載
方式,在用戶需要的時(shí)候在加載數(shù)據(jù)。
computed
是計(jì)算屬性,watch
是偵聽器。
computed
通常用于處理模版中復(fù)雜的邏輯,而 watch
通常用于需要監(jiān)聽一個(gè)響應(yīng)式對(duì)象的變化而做一些操作的時(shí)候
watch
可以進(jìn)行異步操作,computed
不行。
計(jì)算屬性傳遞一個(gè)對(duì)象 有 set
和 get
兩個(gè)選項(xiàng),是它稱為即可讀又可寫的計(jì)算屬性,如果傳遞的是函數(shù)的話默認(rèn)就是 get
選項(xiàng),watch
可以傳遞一個(gè)對(duì)象,設(shè)置deep、immediate等選項(xiàng)
vue3
中 watch
發(fā)生了一些變化,例如不能再偵測(cè)一個(gè)點(diǎn)操符之外的字符串表達(dá)式,reactivity API
中新出的 watch
、watchEffect
可以完全替代 watch
選項(xiàng),而且功能更加強(qiáng)大
SPA
(Single Page Application)是單頁(yè)面應(yīng)用。一般也稱為客戶端渲染,簡(jiǎn)稱 CSR
。SSR(Server Side Render) 即服務(wù)端渲染。一般也稱為多頁(yè)面應(yīng)用(Mulpile Page Application),簡(jiǎn)稱 MPA。
SPA
只會(huì)首次請(qǐng)求 html
文件,后續(xù)只需要請(qǐng)求 JSON
數(shù)據(jù)即可,因此用戶體驗(yàn)更好,節(jié)約流量,服務(wù)端壓力也較小。但是首屏加載的時(shí)間會(huì)變長(zhǎng),而且 SEO
不友好。為了解決以上缺點(diǎn),就有了 SSR
方案,由于 HTML
內(nèi)容在服務(wù)器一次性生成出來(lái),首屏加載快,搜索引擎也可以很方便的抓取頁(yè)面信息。但同時(shí) SSR
方案也會(huì)有性能,開發(fā)受限等問(wèn)題。
選擇上,如果有首屏加載優(yōu)化需求,SEO需求時(shí),就可以考慮SSR。
但并不是只有這一種替代方案,比如對(duì)一些不常變化的靜態(tài)網(wǎng)站,SSR反而浪費(fèi)資源,我們可以考慮預(yù)渲染的方案。另外 nuxt.js/next.js
中給我們提供了SSG靜態(tài)網(wǎng)站生成方案也是很好的靜態(tài)站點(diǎn)解決方案,結(jié)合一些CI手段,可以起到很好的優(yōu)化效果。
回答思路:
diff算法是干什么的?
必要性
何時(shí)執(zhí)行
具體執(zhí)行方式
拔高:說(shuō)一下vue3中的優(yōu)化
回答:
Vue
中的 diff
算法稱為 patching
算法,虛擬DOM要想轉(zhuǎn)化為真實(shí)DOM就需要通過(guò) patch
方法轉(zhuǎn)換。
最初 Vue1.x
視圖中農(nóng)每個(gè)依賴均有更新函數(shù)對(duì)應(yīng),可以做到精確更新,因此不需要 虛擬DOM
和 patching
算法支持,但是這樣粒度過(guò)細(xì)導(dǎo)致 Vue1.x
無(wú)法承載較大應(yīng)用;Vue2.x
中為了降低 Watcher
粒度,每個(gè)組件只有一個(gè) Watcher
與之對(duì)應(yīng),此時(shí)就需要引入 patching
算法才能精確找到發(fā)生變化的地方并高效更新。
vue
中 diff
執(zhí)行的時(shí)刻是組件內(nèi)響應(yīng)式數(shù)據(jù)變更觸發(fā)實(shí)例執(zhí)行其更新函數(shù)時(shí),更新函數(shù)會(huì)再次執(zhí)行 render函數(shù)
獲得最新的 虛擬DOM
,然后執(zhí)行 patch函數(shù)
,對(duì)比新舊虛擬DOM,將其轉(zhuǎn)化為對(duì)應(yīng)的 DOM
操作。
patch
過(guò)程是一個(gè)遞歸過(guò)程,遵循深度優(yōu)先、同層比較的策略;以 vue3
的patch
為例:
新的子節(jié)點(diǎn)是文本,老的子節(jié)點(diǎn)是數(shù)組則清空,并設(shè)置文本;
新的子節(jié)點(diǎn)是文本,老的子節(jié)點(diǎn)是文本則直接更新文本;
新的子節(jié)點(diǎn)是數(shù)組,老的子節(jié)點(diǎn)是文本則清空文本,并創(chuàng)建新子節(jié)點(diǎn)數(shù)組中的子元素;
新的子節(jié)點(diǎn)是數(shù)組,老的子節(jié)點(diǎn)也是數(shù)組,那么比較兩組子節(jié)點(diǎn),更新細(xì)節(jié)blabla
首先判斷兩個(gè)節(jié)點(diǎn)是否為相同同類節(jié)點(diǎn),不同則刪除重新創(chuàng)建
如果雙方都是文本則更新文本內(nèi)容
如果雙方都是元素節(jié)點(diǎn)則遞歸更新子元素,同時(shí)更新元素屬性
更新子節(jié)點(diǎn)時(shí)又分了幾種情況:
vue3
中引入的更新策略:編譯期優(yōu)化 patchFlags
、block
等
從 0 創(chuàng)建項(xiàng)目我大致會(huì)做以下事情:項(xiàng)目構(gòu)建、引入必要插件、代碼規(guī)范、提交規(guī)范、常用庫(kù)和組件
目前vue3項(xiàng)目我會(huì)用vite或者create-vue創(chuàng)建項(xiàng)目
接下來(lái)引入必要插件:vue-router、vuex/pinia、element-plus、antd-vue、axios等等
其他常用的庫(kù)有 像lodash、dayjs、nprogress等等..
下面是代碼規(guī)范: editorconfig、prettier、eslint
最后是提交規(guī)范,可以使用husky、Commitizen
目錄結(jié)構(gòu)我喜歡按照下面的結(jié)構(gòu)來(lái)
+ |- /src
+ |- /assets 存放資源
+ |- /img
+ |- /css
+ |- /font
+ |- /data
+ |- base-ui 存放多個(gè)項(xiàng)目中都會(huì)用到的公共組件
+ |- components 存放這個(gè)項(xiàng)目用到的公共組件
+ |- hooks 存放自定義hook
+ |- views 視圖
+ |- store 狀態(tài)管理
+ |- router 路由
+ |- service 網(wǎng)絡(luò)請(qǐng)求
+ |- utils 工具
+ |- global 全局注冊(cè)、全局常量..
一個(gè) SPA
應(yīng)用的路由需要解決的問(wèn)題時(shí)頁(yè)面跳轉(zhuǎn)內(nèi)容改變同時(shí)不刷新,同時(shí)路由還需要已插件形式存在,所以:
首先我會(huì)定義一個(gè) createRouter
函數(shù),返回路由器實(shí)例,實(shí)例內(nèi)部做幾件事;
保存用戶傳入的配置項(xiàng)
監(jiān)聽 hash
或者 popstate
事件
回調(diào)里根據(jù) path
匹配對(duì)應(yīng)路由
將 router
定義成一個(gè) Vue
插件,即實(shí)現(xiàn) install
方法,內(nèi)部做兩件事:
實(shí)現(xiàn)兩個(gè)全局組件:router-link
和 router-view
,分別實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)和內(nèi)容顯示
定義兩個(gè)全局變量:$router
和 $route
,組件內(nèi)可以訪問(wèn)當(dāng)前路由和路由器實(shí)例
在項(xiàng)目規(guī)模變大的之后,單獨(dú)一個(gè)store對(duì)象會(huì)過(guò)于龐大臃腫,此時(shí)通過(guò)模塊方式可以拆分來(lái)便于維護(hù)
可以按之前規(guī)則單獨(dú)編寫資規(guī)模代碼,然后在主文件中通過(guò) modules
選項(xiàng)組織起來(lái):createStore({modules: {...}})
使用時(shí)需要注意訪問(wèn)子模塊狀態(tài)時(shí)需要加上注冊(cè)模塊名。但同時(shí)getters
、mutations
和 actions
又在全局空間中,使用方式和之前一樣。如果要做到完全拆分,需要在子模塊加上 namespace
選項(xiàng),此時(shí)再訪問(wèn)它們就要加上命名空間前綴。
模塊的方式可以拆分代碼,但是缺點(diǎn)也很明顯,使用起來(lái)比較繁瑣,容易出錯(cuò),而且類型系統(tǒng)支持很差,不能給我們帶來(lái)幫助。pinia 顯然在這方面有了很大改進(jìn),是時(shí)候切換過(guò)去了。
vue2
中組件確實(shí)只能有一個(gè)跟,但 vue3
中組件已經(jīng)可以多根組件了。
之所以需要這樣是因?yàn)?vdom
是一顆單根樹形結(jié)構(gòu),patch
方法在遍歷的時(shí)候從根節(jié)點(diǎn)開始遍歷,它要求只有一個(gè)根節(jié)點(diǎn)。組件也會(huì)轉(zhuǎn)換為一個(gè) vdom
,自然應(yīng)該滿足這個(gè)要求。
vue3
中之所以可以寫多個(gè)根節(jié)點(diǎn),是因?yàn)橐肓?Fragment
的概念,這是一個(gè)抽象的節(jié)點(diǎn),如果發(fā)現(xiàn)組件時(shí)多根的,就創(chuàng)建一個(gè) Fragment
節(jié)點(diǎn),把多個(gè)根節(jié)點(diǎn)作為它的 children
。將來(lái) pathch
的時(shí)候,如果發(fā)現(xiàn)是一個(gè) Fragment
節(jié)點(diǎn),則直接遍歷 children
創(chuàng)建或更新。
v-once
是 vue
的內(nèi)置指令,作用是僅渲染指定組件或元素一次,并跳過(guò)未來(lái)對(duì)其更新。
如果我們有一些元素或者組件再初始化渲染之后不再需要變化,這種情況下適合使用 v-once
,這樣哪怕這些數(shù)據(jù)變化,vue
也會(huì)跳過(guò)更新,是一種代碼優(yōu)化手段。
我們只需要作用的組件或元素上加上 v-once
即可。
補(bǔ)充:
vue3.2
之后,又增加了 v-memo
,這個(gè)指令可以有條件的緩存模板并控制他們的更新。
v-once
的原理:編譯器發(fā)現(xiàn)有 v-once
時(shí),會(huì)將首次計(jì)算結(jié)果存入緩存對(duì)象,組件再次渲染時(shí)就會(huì)從緩存獲取,從而避免再次計(jì)算。
在平時(shí)開發(fā)中,應(yīng)用的有些界面是由多層嵌套的組件組合而來(lái)的,這種情況下,url
各部分通常對(duì)應(yīng)某個(gè)嵌套的組件,vue-router
中可以使用嵌套路由表示這種關(guān)系。
表現(xiàn)形式是在兩個(gè)路由間切換時(shí),他們有公用的視圖內(nèi)容。此時(shí)通常提取一個(gè)父組件,內(nèi)部放上 view-router
,從而形成物理上的嵌套,和邏輯上的嵌套對(duì)應(yīng)起來(lái)。定義嵌套路由時(shí)使用 children
屬性組織嵌套關(guān)系
原理上是在 router-view
組件內(nèi)部判斷其所處嵌套的深度,將這個(gè)深度作為匹配組件數(shù)組 matched
的索引,獲取對(duì)應(yīng)渲染組件并渲染之。
如果你說(shuō)不出來(lái),可以直接舉例子。當(dāng)我開發(fā)一個(gè)頁(yè)面時(shí),如果需要顯示一個(gè)頂部導(dǎo)航欄,通過(guò)導(dǎo)航欄跳轉(zhuǎn)到不同的頁(yè)面,而頂部的導(dǎo)航欄又必須要在每個(gè)頁(yè)面顯示時(shí),就可以使用嵌套路由;還可以舉例,當(dāng)我需要查看某個(gè)列表的詳情頁(yè)面時(shí),往往需要嵌套路由 (detail/:id
)
watch
store.subscribe()
watch
方式,可以以字符串形式監(jiān)聽 $store.state.xx
; subscribe
方法參數(shù)是一個(gè)回調(diào)函數(shù),回調(diào)函數(shù)接受mutation
對(duì)象和 state
對(duì)象,可以通過(guò) mutation.type
判斷監(jiān)聽的目標(biāo)。
wtach 方法更簡(jiǎn)單好用, subscribe
會(huì)略繁瑣,一般
掛載實(shí)例的過(guò)程就是 app.mount()的過(guò)程,整體上就做了兩件事:初始化和建立更新機(jī)制
初始化會(huì)創(chuàng)建組件實(shí)例、初始化組件狀態(tài)、創(chuàng)建各種響應(yīng)式數(shù)據(jù)
簡(jiǎn)歷更新機(jī)制這一步會(huì)立即執(zhí)行一次組件更新函數(shù),這會(huì)首次執(zhí)行渲染函數(shù)并執(zhí)行 patch
將前面獲得vnode
轉(zhuǎn)換為 dom
;同時(shí)會(huì)創(chuàng)建它內(nèi)部響應(yīng)式數(shù)據(jù)和組件更新函數(shù)之間的依賴關(guān)系,這使得以后數(shù)據(jù)變化時(shí)會(huì)執(zhí)行對(duì)應(yīng)的更新函數(shù)。
key
的作用主要是為了更高效的更新虛擬 DOM
。
key
是 vue
在 patch
過(guò)程中判斷兩個(gè)節(jié)點(diǎn)是否是相同節(jié)點(diǎn)的關(guān)鍵條件(另一個(gè)是元素類型),如果不設(shè)置 key
,它的值就是 undefined
,vue
則可能永遠(yuǎn)認(rèn)為這是兩個(gè)相同節(jié)點(diǎn),只能去做更新操作,這造成了大量的 dom
更新操作,明顯是不可取的。
實(shí)際使用的過(guò)程中必須設(shè)置 key
,而且應(yīng)該盡量避免使用數(shù)組索引,這可能導(dǎo)致一些隱藏 bug
。
watchEffect
立即運(yùn)行函數(shù),被動(dòng)地追蹤它的依賴,傳入的函數(shù)即是依賴收集的數(shù)據(jù)源,也是回調(diào)函數(shù);watch
偵測(cè)一個(gè)或多個(gè)響應(yīng)式數(shù)據(jù)源,在數(shù)據(jù)源變化時(shí)調(diào)用一個(gè)回調(diào)函數(shù),通過(guò) immediate
選項(xiàng)也可以設(shè)置立即執(zhí)行一次。
watchEffect
是一種特殊的 watch
。如果不關(guān)心響應(yīng)式數(shù)據(jù)前后的值,可以使用 watchEffect
。其他情況都可以用 watch
。
parent created -> child created -> child mounted -> parent mounted
原因:Vue
創(chuàng)建是一個(gè)遞歸的過(guò)程,先創(chuàng)建父組件,有子組件就會(huì)創(chuàng)建子組件,因此創(chuàng)建時(shí)先有父組件再有子組件;子組件首次創(chuàng)建時(shí)會(huì)添加 Mounted
鉤子到隊(duì)列,等到 patch
結(jié)束再執(zhí)行它們,可見子組件的 mounted
鉤子是選進(jìn)入到隊(duì)列中的,因此等到 patch
結(jié)束執(zhí)行這些鉤子時(shí)也先執(zhí)行。
vuex是一個(gè)專門為vue應(yīng)用開發(fā)的狀態(tài)管理模式庫(kù),
當(dāng)你遇到多個(gè)組件共享狀態(tài)時(shí)或者項(xiàng)目中的組件難以管理的時(shí)候就可以使用vuex,它以一個(gè)全局單例模式管理全局的狀態(tài)。
基本核心概念有 state、mutation、action、getters、module等
說(shuō)些使用過(guò)程的感受 ts不友好 模塊使用繁瑣 頁(yè)面刷新數(shù)據(jù)也會(huì)消失
如果某個(gè)組件通過(guò)組件名稱引用它自己,這種情況就是遞歸組件。
類似 Tree
、Menu
這類組件,它們的節(jié)點(diǎn)往往包含子節(jié)點(diǎn),子節(jié)點(diǎn)結(jié)構(gòu)和父節(jié)點(diǎn)往往是相同的。這類組件的數(shù)據(jù)往往也是樹形結(jié)構(gòu),這種都是使用遞歸組件的典型場(chǎng)景。
使用自定義指令分為定義、注冊(cè)、和使用
定義有兩種方式,對(duì)象和函數(shù)形式,前者類似組件定義,有各種生命周期;后者只會(huì)在 mounted
和 updated
時(shí)執(zhí)行
注冊(cè):可以使用 app.directive
全局注冊(cè) 也可以通過(guò)選項(xiàng)局部注冊(cè)
使用時(shí)在注冊(cè)名稱前加上 v-即可。
v-copy
復(fù)制粘貼
v-lazy
圖片懶加載
v-debounce
防抖
v-permission
按鈕權(quán)限
v-longpress
長(zhǎng)按
API 層面
Composition API
setup
語(yǔ)法糖
Teleport
傳送門
Fragments
可以多個(gè)根節(jié)點(diǎn)
Emits
createRenderer
自定義渲染器
SFC
狀態(tài)驅(qū)動(dòng) css
變量 (v-bind in <style>
)
此外,Vue3在框架層面也有很多兩點(diǎn)和改進(jìn)
更快
虛擬 DOM
重寫
編譯器優(yōu)化:靜態(tài)提升、patchFlags
、block
等
基于 Proxy
的響應(yīng)式系統(tǒng)
更?。焊玫膿u樹優(yōu)化
更容易維護(hù):TS + 模塊化
更容易擴(kuò)展
獨(dú)立的響應(yīng)化模塊
自定義渲染器
最大設(shè)計(jì)目標(biāo)就是替代 Vue2
,為了實(shí)現(xiàn)這一點(diǎn),Vue3
在以下幾個(gè)方面做了很大改進(jìn),如:易用性,框架性能、擴(kuò)展性、可維護(hù)性、開發(fā)體驗(yàn)等
易用性方面:主要有 API
簡(jiǎn)化 v-model
變成了 v-model
和 sync
修飾符的結(jié)合體。類似的還有 h(type,props,children)
函數(shù)中的 props
不用考慮區(qū)分屬性、特性、事件等,框架替我們判斷,易用性增。
開發(fā)體驗(yàn)方面:新組建 Teleport
Fragment
Suspense
等都會(huì)簡(jiǎn)化特定場(chǎng)景的代碼編寫。 setup
語(yǔ)法糖更是極大提升了我們的開發(fā)體驗(yàn)。
擴(kuò)展性方面提升: 如獨(dú)獨(dú)立的 reactivity
模塊,custom render API
等
可維護(hù)性方面主要是 Composition API
,更容易編寫高復(fù)用性的業(yè)務(wù)邏輯。還有對(duì)TS支持的提升。
性能方面:編譯器優(yōu)化、基于 Proxy
的響應(yīng)式系統(tǒng)。
。。。
代碼方面:全新的響應(yīng)式API,基于 Proxy
實(shí)現(xiàn),初始化事件和內(nèi)存占用均大幅改進(jìn);
編譯方面:做了更多編譯優(yōu)化處理,比如靜態(tài)提升、動(dòng)態(tài)內(nèi)容標(biāo)記、事件緩存、區(qū)塊等,可以有效跳過(guò)大量diff過(guò)程
打包方面:更好的支持 tree-shaking
,因此體積更小,加載更快.(因?yàn)関ue3 所有的API都通過(guò)ES6模塊化的方式引入,這樣就能讓webpack或rollup等打包工具在打包時(shí)對(duì)沒(méi)有用到API進(jìn)行剔除,最小化bundle體積)
$attrs
和 $listeners
是做什么的?$attrs
獲取沒(méi)有在 props
中定義的屬性,v-bind="$attrs"
可以用于屬性透?jìng)?code>$listeners 用于獲取事件,vue3
中已經(jīng)移除合并到 attrs
中,使用起來(lái)更方便
Composition API
是一組API,包括 Reactivity API
、生命鉤子、依賴注入,使用戶可以通過(guò)導(dǎo)入函數(shù)方式編寫組件,而 Options API
則通過(guò)聲明組件選項(xiàng)的對(duì)象形式編寫組件。
Composition API
更簡(jiǎn)潔、邏輯復(fù)用更高效。解決的過(guò)去 Options API
中 mixins
的各種缺點(diǎn)(會(huì)沖突很混亂);另外 Composition API
更自由,沒(méi)有 Options API
那樣固定的寫法,并且可以更有效的將邏輯代碼組織在一起,而不用東一塊西一塊搞得很混亂,最后 Composition API
擁有更好的類型推斷,對(duì) ts
支持友好。
編碼風(fēng)格方面:
組件命名時(shí)使用 多詞風(fēng)格避免和html元素沖突
屬性名峰命名,模板或jsx中使用 肉串命名
v-for 務(wù)必加上key 且不要和v-if寫在一起‘’
性能方面:
路由懶加載減少應(yīng)用尺寸
SSR
減少首屏加載事件
v-once
v-memo
長(zhǎng)列表 虛擬滾動(dòng)技術(shù)
對(duì)于深層嵌套對(duì)象的大數(shù)據(jù)可以使用 shallowRef
或 shallowReactive
降低開銷
避免不必要的組件抽象
mutation
用于修改 state
action
用于提交一個(gè) mutation
,而且 action
可以包含異步操作
要實(shí)現(xiàn)一個(gè) Store
存儲(chǔ)全局狀態(tài)
要提供修改狀態(tài)所需的API:commit({type, payload})
, dispatch(type,payload)
實(shí)現(xiàn) Store
,可以定義 Store
類,構(gòu)造函數(shù)接受選項(xiàng) options
,設(shè)置屬性 state
對(duì)外暴露狀態(tài),提供 commit
和 dispatch
修改屬性。這里需要設(shè)置 state
為響應(yīng)式對(duì)象,同時(shí)將 Store
定義為一個(gè) Vue
插件(install方法)。
commit
可以獲取用戶傳入 mutations
并執(zhí)行它,這樣可以按用戶提供的方法修改狀態(tài),dispatch
類似,但是 dispatch
需要返回一個(gè) Promise
給用戶用于處理異步結(jié)果。
關(guān)于“Vue面試題及答案有哪些”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Vue面試題及答案有哪些”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
文章標(biāo)題:Vue面試題及答案有哪些
當(dāng)前鏈接:http://bm7419.com/article26/jceojg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、云服務(wù)器、自適應(yīng)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)