vue出鏡率比較高的十大面試題


1、vue的底層原理

vue是M-V-VM模式,通過modelView作為中間層,進行雙向數據的綁定和變化
①通過document.createDocumentFrament()方法建立虛擬Dom樹
②一旦被檢測到數據發生變化,會通過Object.defineProperty定義的數據攔截
③攔截到數據變化從而通過訂閱-發布模式觸發觀察者,從而改變虛擬dom中具體數據
④最后通過更新虛擬Dom的元素值,從而改變最后dom樹的值,完成雙向綁定

 

2、Vue Router 路由模式 hash 和 history 的實現原理,以及他們的特性

hash模式實現原理:location.hash的值就是url中#后面的內容。
以下幾個特性:
① url中hash值只是客戶端一種狀態,向服務端發送請求時hash部分不會被發送
② hash值的改變,都會在瀏覽器增加一個歷史記錄,因此能通過瀏覽器回退、前進按鈕控制hash的切換
③ 可以用hashchange事件去監聽hash變化,從而對頁面進行跳轉(渲染)
④ 可以通過a標簽設置href屬性,當用戶點擊后hash值會發生變化,或者通過js對location.hash賦值改變url的hash值

history模式實現原理:
H5 提供了HistoryAPI 來實現URL的變化,history.pushState() 和 history.repalceState()兩個API可以在不進行刷新情況下操作瀏覽器歷史記錄
不同的是,前者是新增一個歷史記錄,后者是直接替換當前記錄。

以下幾個特性:
① pushState和repalceState兩個API來操作實現url的變化
② 可以用popstate事件來監聽url變化,從而對頁面進行跳轉
③ pushState或repalceState不會觸發popstate事件,這時需要手動觸發頁面跳轉
④ history路由模式需要后台配置支持,需要在服務端增加一個覆蓋所有情況的候選資源,如果url匹配不到靜態資源,應該返回同一個app依賴的index.html頁面

 

3、什么是虛擬DOM,為什么他能提高性能? 說下diff算法

虛擬dom也就是虛擬節點,是通過js的Object對象模擬dom中的節點,然后通過特定的render方法將其渲染成真正的DOM節點
當改變元素的節點或者屬性時候,並不是真正改變dom元素,而是做一次diff算法做一次對比,他會以最小的代價更新dom
虛擬Dom相當於在js和真實Dom之間加了一個緩存,利用dom diff算法避免了沒有必要的dom操作,從而提高性能
虛擬Dom工作的三個簡單步驟:
1)沒當數據發生變化時候,整個頁面將在虛擬dom中重新渲染
2)然后計算之前的dom與新的dom中間差異
3)完成計算后,將只用實際更改的內容更新真實dom

diff算法:
根據真實dom生成一個虛擬dom,當虛擬dom某個節點數據變化改變后會生成一個新的vnode,然后新的和舊的對比,一邊對比一邊打補丁
發現有不一樣的就直接修改在真實的dom上。
當數據發生改變時,set方法會調用Dep.notify通知所有訂閱者,訂閱者就會調用patch給真實的DOM打補丁,更新相應的視圖

 

4、vue如何實現組件和邏輯復用

組件復用可以使用slot作用域插槽,讓子組件暴露出屬性 直接在父組件使用
邏輯復用可以使用Mixin 混入模式,將一些邏輯封裝,然后混入到需要該功能的組件中

說說你對mixin的理解,以及應用場景 ?
mixin,一個混入對象可以包含任意組件選項。多個實例引用了相同的方法或者屬性,可將這些重復的內容抽取出來作為mixin的js
export導出去,在需要引用vue文件通過mixin屬性注入。他允許封裝一塊在應用的其他組件都可以使用的函數
比如有兩個非常相似的組件,基本功能一致,但個別地方又有差異,這時候可以使用mixin

 

5、頁面刷新后vuex的state數據為什么會丟失,如何解決

原因:因為store里的數據是把保存在運行內存中,當頁面刷新時,會重新加載vue實例,store里面的數值就會重新賦值初始化
解決方法:在頁面向后台請求數據,並且在頁面刷新前,將vuex中數據存儲到localStorage或sessionStorage中

export default {
name: 'App',
created() {
//在頁面加載時讀取sessionStorage里的狀態信息
if(sessionStorage.getItem('store')){
this.$store.replaceState(Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem('store'))
))
}
//在頁面刷新時將vuex里的信息保存在sessionStorage中
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('store', JSON.stringify(this.$store.state));
})
}
}

 

6、如何理解Vue中的Render渲染函數,他和JSX有什么不同

Vue一般使用template來創建HTML,然后有時候,我們需要使用js來創建html,這時候我們需要使用render函數
render函數return一個createElement組件中的子元素存儲在組件實列中,createElement返回的是包含的信息會告訴VUE頁面上需要渲染什么樣的節點。
一般用render函數封裝東西會比較靈活,尤其是配置和模板分離。

JSX是JavScript和XML結合一種的格式,Js在解析JSX時會先創建虛擬DOM,JSX最后會被編譯為JavaScript代碼執行
JSX相當於createElement的語法糖,這種形式可以直接使用template模板格式在render函數里寫

 

7、Proxy代理與Object.defineProperty的優劣對比

vue是基於數據劫持的雙向綁定,數據劫持有兩種,分別是Object.defineProperty和Proxy代理
Vue3.0以Proxy來替代Object.defineProperty數據劫持
Proxy優勢:
1)可以直接監聽對象,而非屬性
2)可以直接監聽數組的變化
3)有很多攔截方法
4)返回一個新對象,可以只操作新對象即可

 

8、說一下formData上傳表單的實現原理

先創建一個formData對象,通過append向form對象添加數據(鍵值隊)
let formData = new FormData();
formData.append(name,value)

通過axios上傳文件,配置添加請求頭,添加上傳進度監聽事件
let config = {
header: {"Content-Type,multipart/form-data"},
onUploadProgress: e =>{
let percent = (progressEvent.loaded / progressEvent.total * 100) | 0
//調用onProgress方法來顯示進度條,需要傳遞個對象 percent為進度值
params.onProgress({ percent: percent })
}
}
上傳成功 調用onSuccess方法,上傳失敗 調用onError方法
axios.post().then((response) => {
console.log(response)
params.onSuccess(response.info)
}).catch((error) =>{
params.onError(error)
})

 

9、vue項目中做過哪些優化處理 ?

①v-if 、v-show區分使用場景
v-if是真正的條件渲染,條件成立才會渲染,否則不會渲染,v-show只是操作display屬性來控制元素,不管條件是否成立都會渲染。如果需要頻繁切換使用v-show較為合適
②v-for遍歷時給item添加key,並且避免同時使用v-if
在數據進行遍歷渲染時,需要為每一項item設置唯一的key值,方便vue內部機制准確查找該數據。當state更新時,新的狀態值和舊的對比,可以更快的定位到diff
③事件的銷毀
如果是非組件本身的事件,比如addEventListener方式是不會自動銷毀的,需要手動移除,以免造成內存泄漏
created(){
addEventListener('click','this.click',false)
},
beforeDestroy(){
removeEventListener('click', this.click, false)
}
④路由懶加載
vue單頁面應用,一次加載過多資源造成用時過長甚至會出現白屏情況
運用懶加載可以當路由被訪問時候才加載,
import方式和require.ensure()方式
{
path: '/about',
name: 'about',
meta: {
breadcrumb: "關於我們"
},
component: () => import('@/view/about')
}
⑤圖片懶加載
對於圖片過多的頁面,為了提高加載速度,可以使用懶加載。將頁面內未出現在可視區域的圖片先不加載,等滾動到可視區域時再做加載
可以使用vue-lazyload插件
⑥第三方插件的按需引入
項目中引入第三方插件時,如果直接引入整個插件會造成項目提交過大
可以借助babel-plugin-component插件只引入需要的組件,從而減小項目的體積
⑦webpack對圖片進行壓縮
使用image-webpack-loader插件
⑧開啟 gzip 壓縮

 

10、vue3.0新增了哪些東西,和2.0有什么區別 ?

vue3.0采用了ts來編寫
vue3.0將組件的邏輯都寫在了函數內部,setup()會取代之前的data()函數,返回一個對象,暴露給模板,而且只在初始化的時候調用一次
相對2.0,壓縮包體積更小
1)雙向綁定,3.0使用es6的proxy,相對於object.defineProperty有很多優勢
2)虛擬dom的對比更新,只更新vdom綁定的動態數據的部分
3)2.0無論是否使用一些功能和方法都需要下下來,3.0將全局的API和內部的一些組件通過ES的模塊進行導出webpack在打包時候就會更加的快捷


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM