亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue.js面試題及答案有哪些

發布時間:2022-07-07 09:22:51 來源:億速云 閱讀:195 作者:iii 欄目:編程語言

這篇文章主要介紹了Vue.js面試題及答案有哪些的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Vue.js面試題及答案有哪些文章都會有所收獲,下面我們一起來看看吧。

Vue.js面試題及答案有哪些

一、Vue.js基本問題

1.1.Vue 響應式原理

Vue.js面試題及答案有哪些

核心實現類:
Observer : 它的作用是給對象的屬性添加 getter 和 setter,用于依賴收集和派發更新
Dep : 用于收集當前響應式對象的依賴關系,每個響應式對象包括子對象都擁有一個 Dep 實例(里面 subs 是 Watcher 實例數組),當數據有變更時,會通過 dep.notify()通知各個 watcher。
Watcher : 觀察者對象 , 實例分為渲染 watcher (render watcher),計算屬性 watcher (computed watcher),偵聽器 watcher(user watcher)三種
Watcher 和 Dep 的關系:
watcher 中實例化了 dep 并向 dep.subs 中添加了訂閱者,dep 通過 notify 遍歷了 dep.subs 通知每個 watcher 更新。
依賴收集:
initState 時,對 computed 屬性初始化時,觸發 computed watcher 依賴收集
initState 時,對偵聽屬性初始化時,觸發 user watcher 依賴收集
render()的過程,觸發 render watcher 依賴收集
re-render 時,vm.render()再次執行,會移除所有 subs 中的 watcer 的訂閱,重新賦值。
派發更新:
組件中對響應的數據進行了修改,觸發 setter 的邏輯
調用 dep.notify()
遍歷所有的 subs(Watcher 實例),調用每一個 watcher 的 update 方法。
原理:
當創建 Vue 實例時,vue 會遍歷 data 選項的屬性,利用 Object.defineProperty 為屬性添加 getter 和 setter 對數據的讀取進行劫持(getter 用來依賴收集,setter 用來派發更新),并且在內部追蹤依賴,在屬性被訪問和修改時通知變化。
每個組件實例會有相應的 watcher 實例,會在組件渲染的過程中記錄依賴的所有數據屬性(進行依賴收集,還有 computed watcher,user watcher 實例),之后依賴項被改動時,setter 方法會通知依賴與此 data 的 watcher 實例重新計算(派發更新),從而使它關聯的組件重新渲染。
一句話總結:
vue.js 采用數據劫持結合發布-訂閱模式,通過 Object.defineproperty 來劫持各個屬性的 setter,getter,在數據變動時發布消息給訂閱者,觸發響應的監聽回調

1.2.Vue.js 的特點

易用: 簡單,易學,上手快
靈活: (漸進式)不斷繁榮的生態系統,可以在一個庫和一套完整框架之間自如伸縮。
高效: 20kB min+gzip 運行大小;超快虛擬 DOM;最省心的優化
雙向綁定:開發效率高
基于組件的代碼共享
Web項目工程化,增加可讀性、可維護性

1.3. Vue.js 雙向綁定的原理

Vue.js 2.0 采用數據劫持(Proxy 模式)結合發布者-訂閱者模式(PubSub 模式)的方式,通過 Object.defineProperty()來劫持各個屬性的 setter,getter,在數據變動時發布消息給訂閱者,觸發相應的監聽回調。
每個組件實例都有相應的watcher程序實例,它會在組件渲染的過程中把屬性記錄為依賴,之后當依賴項的setter被調用時,會通知watcher重新計算,從而致使它關聯的組件得以更新。

Vue.js 3.0, 放棄了Object.defineProperty ,使用更快的ES6原生 Proxy (訪問對象攔截器, 也稱代理器)

步驟:

1.需要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上setter和getter這樣的話,給這個對象的某個值賦值,就會觸發setter,那么就能監聽到了數據變化
2.compile解析模板指令,將模板中的變量替換成數據,然后初始化渲染頁面視圖,并將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,更新視圖
3.Watcher訂閱者是Observer和Compile之間通信的橋梁,主要做的事情是: ①在自身實例化時往屬性訂閱器(dep)里面添加自己 ②自身必須有一個update()方法 ③待屬性變動dep.notice()通知時,能調用自身的update()方法,并觸發Compile中綁定的回調,則功成身退。
4.MVVM作為數據綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監聽自己的model數據變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋梁,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變更的雙向綁定效果。

1.4.Vue中如何監控某個屬性值的變化?

比如現在需要監控data中, obj.a 的變化。Vue中監控對象屬性的變化你可以這樣:

watch: {
      obj: {
      	handler (newValue, oldValue) {
        console.log('obj changed')
      },
      deep: true
    }

deep屬性表示深層遍歷,但是這么寫會監控obj的所有屬性變化,并不是我們想要的效果,所以做點修改:

watch: {
   'obj.a': {
      	handler (newName, oldName) {
        console.log('obj.a changed')
      }
   }
  }

還有一種方法,可以通過computed 來實現,只需要:

computed: {
    a1 () {
      return this.obj.a    
      }
}

利用計算屬性的特性來實現,當依賴改變時,便會重新計算一個新值。

1.5.Vue.js 3.0 放棄defineProperty, 使用Proxy的原因

Object.defineProperty缺陷

1.監控到數組下標的變化時,開銷很大。所以Vue.js放棄了下標變化的檢測;
2.Object.defineProperty只能劫持對象的屬性,而Proxy是直接代理對象。3.Object.defineProperty需要遍歷對象的每個屬性,如果屬性值也是對象,則需要深度遍歷。而 Proxy 直接代理對象,不需要遍歷操作。
4.Object.defineProperty對新增屬性需要手動進行Observe。vue2時需要使用 vm.$set 才能保證新增的屬性也是響應式
5.Proxy支持13種攔截操作,這是defineProperty所不具有的
6.Proxy 作為新標準,長遠來看,JS引擎會繼續優化 Proxy,但 getter 和 setter 基本不會再有針對性優化

1.6.Vue 2 中給 data 中的對象屬性添加一個新的屬性時會發生什么?如何解決?

視圖并未刷新。這是因為在Vue實例創建時,新屬性并未聲明,因此就沒有被Vue轉換為響應式的屬性,自然就不會觸發視圖的更新,這時就需要使用Vue的全局 api $set():

this.$set(this.obj, 'new_property', 'new_value')

1.7.Computed和Watch的區別及運用場景

computed 計算屬性 : 依賴其它屬性值,并且 computed 的值有緩存,只有它依賴的 屬性值發生改變,下一次獲取 computed 的值時才會重新計算 computed 的值。
watch 偵聽器 : 更多的是觀察的作用,無緩存性,類似于某些數據的監聽回調,每 當監聽的數據變化時都會執行回調進行后續操作。

運用場景:

1.當我們需要進行數值計算,并且依賴于其它數據時,應該使用 computed,因為可以利用 computed 的緩存特性,避免每次獲取值時,都要重新計算。
2.當我們需要在數據變化時執行異步或開銷較大的操作時,應該使用 watch,使用 watch 選項允許我們執行異步操作 ( 訪問一個 API ),限制我們執行該操作的頻率, 并在我們得到最終結果前,設置中間狀態。這些都是計算屬性無法做到的。
3.多個因素影響一個顯示,用Computed;一個因素的變化影響多個其他因素、顯示,用Watch;

1.8. Computed 和 Methods 的區別

1.computed: 計算屬性是基于它們的依賴進行緩存的,只有在它的相關依賴發生改變時才會重新求值對于 method ,只要發生重新渲染,
2.method 調用總會執行該函數

1.9.虛擬DOM,diff算法

1.讓我們不用直接操作DOM元素,只操作數據便可以重新渲染頁面
2.虛擬dom是為了解決瀏覽器性能問題而被設計出來的
當操作數據時,將改變的dom元素緩存起來,都計算完后再通過比較映射到真實的dom樹上
3.diff算法比較新舊虛擬dom。如果節點類型相同,則比較數據,修改數據;如果節點不同,直接干掉節點及所有子節點,插入新的節點;如果給每個節點都設置了唯一的key,就可以準確的找到需要改變的內容,否則就會出現修改一個地方導致其他地方都改變的情況。比如A-B-C-D, 我要插入新節點A-B-M-C-D,實際上改變的了C和D。但是設置了key,就可以準確的找到B C并插入

1.10.為何需要Virtual DOM?

1.具備跨平臺的優勢
2.操作 DOM 慢,js運行效率高。我們可以將DOM對比操作放在JS層,提高效率。
3.提升渲染性能

1.11.過濾器 (Filter)

在Vue中使用filters來過濾(格式化)數據,filters不會修改數據,而是過濾(格式化)數據,改變用戶看到的輸出(計算屬性 computed ,方法 methods 都是通過修改數據來處理數據格式的輸出顯示。
使用場景: 比如需要處理時間、數字等的的顯示格式;

1.12.常見的事件修飾符及其作用

1).stop:等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡;
2).prevent :等同于 JavaScript 中的 event.preventDefault() ,防止執行預設的行為(如果事件可取消,則取消該事件,而不停止事件的進一步傳播);
3).capture :當元素發生冒泡時,先觸發帶有該修飾符的元素。若有多個該修飾符,則由外而內觸發。如 p1中嵌套p2中嵌套p3.capture中嵌套p4,那么執行順序為:p3=》p4=》p2=》p1
4).self :只會觸發自己范圍內的事件,不包含子元素;
5).once :只會觸發一次。

1.13.v-show指令和v-if指令的區別是什么?

v-show 僅僅控制元素的顯示方式,將 display 屬性在 block 和 none 來回切換;而v-if會控制這個 DOM 節點的存在與否。當我們需要經常切換某個元素的顯示/隱藏時,使用v-show會更加節省性能上的開銷;當只需要一次顯示或隱藏時,使用v-if更加合理。

1.14.v-model 是如何實現的,語法糖實際是什么

作用在表單元素上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 " 作 用 在 組 件 上 , 本 質 是 一 個 父 子 組 件 通 信 的 語 法 糖 ,通過prop和.emit實現, 等同于:value="message" @input=" $emit('input', $event.target.value)"

1.15.data為什么是一個函數而不是對象

JavaScript中的對象是引用類型的數據,當多個實例引用同一個對象時,只要一個實例對這個對象進行操作,其他實例中的數據也會發生變化。
而在Vue中,我們更多的是想要復用組件,那就需要每個組件都有自己的數據,這樣組件之間才不會相互干擾。
所以組件的數據不能寫成對象的形式,而是要寫成函數的形式。數據以函數返回值的形式定義,這樣當我們每次復用組件的時候,就會返回一個新的data,也就是說每個組件都有自己的私有數據空間,它們各自維護自己的數據,不會干擾其他組件的正常運行。

1.16.Vue template 到 render 的過程

1.調用parse方法將template轉化為ast(抽象語法樹, abstract syntax tree)
2.對靜態節點做優化。如果為靜態節點,他們生成的DOM永遠不會改變,這對運行時模板更新起到了極大的優化作用。
3.生成渲染函數. 渲染的返回值是VNode,VNode是Vue的虛擬DOM節點,里面有(標簽名,子節點,文本等等)

1.17.Vue template 到 render 的過程

調用parse方法將template轉化為ast(抽象語法樹, abstract syntax tree)
對靜態節點做優化。如果為靜態節點,他們生成的DOM永遠不會改變,這對運行時模板更新起到了極大的優化作用。
生成渲染函數. 渲染的返回值是VNode,VNode是Vue的虛擬DOM節點,里面有(標簽名,子節點,文本等等)

1.18.axios是什么

易用、簡潔且高效的http庫, 支持node端和瀏覽器端,支持Promise,支持攔截器等高級配置。

1.19.sass是什么?如何在vue中安裝和使用?

sass是一種CSS預編譯語言安裝和使用步驟如下。

1.用npm安裝加載程序( sass-loader、 css-loader等加載程序)。
2.在 webpack.config.js中配置sass加載程序。

1.20.Vue.js頁面閃爍

Vue. js提供了一個v-cloak指令,該指令一直保持在元素上,直到關聯實例結束編譯。當和CSS一起使用時,這個指令可以隱藏未編譯的標簽,直到實例編譯結束。用法如下

1.21.如何解決數據層級結構太深的問題

在開發業務時,經常會岀現異步獲取數據的情況,有時數據層次比較深,如以下代碼: <span 'v-text=“a.b.c.d”>, 可以使用vm.$set手動定義一層數據:

vm.$set("demo",a.b.c.d)

1.22.在 Vue. js開發環境下調用API接口,如何避免跨域

config/ index.js內對 proxyTable項配置代理。

1.23.批量異步更新策略

Vue 在修改數據后,視圖不會立刻更新,而是等同一事件循環中的所有數據變化完成之后,再統一進行視圖更新。
換句話說,只要觀察到數據變化,就會自動開啟一個隊列,并緩沖在同一個事件循環中發生的所以數據改變。在緩沖時會去除重復數據,從而避免不必要的計算和 DOM 操作。

1.24.vue 的 nextTick 方法的實現原理

1.vue 用異步隊列的方式來控制 DOM 更新和 nextTick 回調先后執行
2.microtask 因為其高優先級特性,能確保隊列中的微任務在一次事件循環前被執行完畢

1.25.Vue 組件 data 為什么必須是函數 ?

因為組件是可以復用的,JS 里對象是引用關系,如果組件 data 是一個對象,那么子組件中的 data 屬性值會互相污染。
所以一個組件的 data 選項必須是一個函數,因此每個實例可以維護一份被返回對象的獨立的拷貝。

1.26.v-if和v-for一起使用的弊端及解決辦法

由于v-for的優先級比v-if高,所以導致每循環一次就會去v-if一次,而v-if是通過創建和銷毀dom元素來控制元素的顯示與隱藏,所以就會不停的去創建和銷毀元素,造成頁面卡頓,性能下降。

解決辦法:

1.在v-for的外層或內層包裹一個元素來使用v-if
2.用computed處理

1.27.vue常用指令

1.v-model 多用于表單元素實現雙向數據綁定(同angular中的ng-model)
2.v-bind 動態綁定 作用: 及時對頁面的數據進行更改
3.v-on:click 給標簽綁定函數,可以縮寫為@,例如綁定一個點擊函數 函數必須寫在methods里面
4.v-for 格式: v-for=“字段名 in(of) 數組json” 循環數組或json(同angular中的ng-repeat)
5.v-show 顯示內容 (同angular中的ng-show)
6.v-hide 隱藏內容(同angular中的ng-hide)
7.v-if 顯示與隱藏 (dom元素的刪除添加 同angular中的ng-if 默認值為false)
8.v-else-if 必須和v-if連用
9.v-else 必須和v-if連用 不能單獨使用 否則報錯 模板編譯錯誤
10.v-text 解析文本
11.v-html 解析html標簽
12.v-bind:class 三種綁定方法 1、對象型 ‘{red:isred}’ 2、三元型 ‘isred?“red”:“blue”’ 3、數組型 ‘[{red:“isred”},{blue:“isblue”}]’
13.v-once 進入頁面時 只渲染一次 不在進行渲染
14.v-cloak 防止閃爍
15.v-pre 把標簽內部的元素原位輸出

1.28. 組件傳值方式有哪些

1.父傳子:子組件通過props[‘xx’] 來接收父組件傳遞的屬性 xx 的值
2.子傳父:子組件通過 this.$emit(‘fnName’,value) 來傳遞,父組件通過接收 fnName 事件方法來接收回調
3.其他方式:通過創建一個bus,進行傳值
4.使用Vuex

1.30.vue中 key 值的作用

當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用“就地復用”策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單復用此處每個元素,并且確保它在特定索引下顯示已被渲染過的每個元素。key的作用主要是為了高效的更新虛擬DOM

1.31.為什么在 Vue3.0 采用了 Proxy,拋棄了 Object.defineProperty?

Object.defineProperty 本身有一定的監控到數組下標變化的能力,但是在 Vue 中,從性能/體驗的性價比考慮,尤大大就棄用了這個特性(Vue 為什么不能檢測數組變動 )。為了解決這個問題,經過 vue 內部處理后可以使用以下幾種方法來監聽數組

push();
pop();
shift();
unshift();
splice();
sort();
reverse();

由于只針對了以上 7 種方法進行了 hack 處理,所以其他數組的屬性也是檢測不到的,還是具有一定的局限性。

Object.defineProperty 只能劫持對象的屬性,因此我們需要對每個對象的每個屬性進行遍歷。Vue 2.x 里,是通過 遞歸 + 遍歷 data 對象來實現對數據的監控的,如果屬性值也是對象那么需要深度遍歷,顯然如果能劫持一個完整的對象是才是更好的選擇。
Proxy 可以劫持整個對象,并返回一個新的對象。Proxy 不僅可以代理對象,還可以代理數組。還可以代理動態增加的屬性。

1.32.談一談 nextTick 的原理

JS 運行機制

JS 執行是單線程的,它是基于事件循環的。事件循環大致分為以下幾個步驟:

所有同步任務都在主線程上執行,形成一個執行棧(execution context stack)。
主線程之外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。
一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務隊列",看看里面有哪些事件。那些對應的異步任務,于是結束等待狀態,進入執行棧,開始執行。
主線程不斷重復上面的第三步。

Vue.js面試題及答案有哪些
主線程的執行過程就是一個 tick,而所有的異步結果都是通過 “任務隊列” 來調度。 消息隊列中存放的是一個個的任務(task)。 規范中規定 task 分為兩大類,分別是 macro task 和 micro task,并且每個 macro task 結束后,都要清空所有的 micro task。

for (macroTask of macroTaskQueue) {
  // 1. Handle current MACRO-TASK
  handleMacroTask();

  // 2. Handle all MICRO-TASK
  for (microTask of microTaskQueue) {
    handleMicroTask(microTask);
  }}

在瀏覽器環境中 :

常見的 macro task 有 setTimeout、MessageChannel、postMessage、setImmediate

常見的 micro task 有 MutationObsever 和 Promise.then

異步更新隊列

可能你還沒有注意到,Vue 在更新 DOM 時是異步執行的。只要偵聽到數據變化,Vue 將開啟一個隊列,并緩沖在同一事件循環中發生的所有數據變更。
如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。這種在緩沖時去除重復數據對于避免不必要的計算和 DOM 操作是非常重要的。
然后,在下一個的事件循環“tick”中,Vue 刷新隊列并執行實際 (已去重的) 工作。
Vue 在內部對異步隊列嘗試使用原生的 Promise.then、MutationObserver 和 setImmediate,如果執行環境不支持,則會采用 setTimeout(fn, 0) 代替。
在 vue2.5 的源碼中,macrotask 降級的方案依次是:setImmediate、MessageChannel、setTimeout

vue 的 nextTick 方法的實現原理:

vue 用異步隊列的方式來控制 DOM 更新和 nextTick 回調先后執行
microtask 因為其高優先級特性,能確保隊列中的微任務在一次事件循環前被執行完畢
考慮兼容問題,vue 做了 microtask 向 macrotask 的降級方案

1.33.談談 Vue 事件機制,手寫on,off,emit,once

Vue 事件機制 本質上就是 一個 發布-訂閱 模式的實現。

class Vue {
  constructor() {
    //  事件通道調度中心
    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;
  }}

1.34.vue-router有哪幾種導航鉤子?

三種:

一種是全局導航鉤子:router.beforeEach(to,from,next),作用:跳轉前進行判斷攔截。第二種:組件內的鉤子;第三種:單獨路由獨享組件

1.35.vuex是什么?怎么使用?哪種功能場景使用它?

vue框架中狀態管理。在main.js引入store,注入。新建了一個目錄store,…… export 。
場景有:單頁應用中,組件之間的狀態。音樂播放、登錄狀態、加入購物車
Vue.js面試題及答案有哪些

1.36.MVVM和MVC區別?和其他框架(jquery)區別?那些場景適用?

MVVM和MVC都是一種設計思想,主要就是MVC中的Controller演變成ViewModel,,MVVM主要通過數據來顯示視圖層而不是操作節點,解決了MVC中大量的DOM操作使頁面渲染性能降低,加載速度慢,影響用戶體驗問題。主要用于數據操作比較多的場景。
場景:數據操作比較多的場景,更加便捷
Vue.js面試題及答案有哪些

1.37.聊聊你對Vue.js的模板編譯的理解

簡而言之,就是先轉化成AST樹,再得到的渲染函數返回VNODE(Vue公司的虛擬DOM節點)
詳情步驟:

首先,通過編譯編譯器把模板編譯成AST語法樹(抽象語法樹即源代碼的抽象語法結構的樹狀表現形式),編譯是createCompiler的返回值,createCompiler是用以創建編譯器的。負責合并選項。
然后,AST會經過生成(將AST語法樹轉化成渲染功能字符串的過程)得到渲染函數,渲染的返回值是VNode,VNode是Vue的虛擬DOM節點,里面有(標簽名,子節點,文本等等)

1.38.< keep-alive>< /keep-alive>的作用是什么,如何使用?

答:包裹動態組件時,會緩存不活動的組件實例,主要用于保留組件狀態或避免重新渲染;
使用:簡單頁面時
緩存: < keep-alive include=”組件名”>< /keep-alive>
不緩存: < keep-alive exclude=”組件名”>< /keep-alive>

1.39.vue和react區別

相同點:都鼓勵組件化,都有’props’的概念,都有自己的構建工具,Reat與Vue只有框架的骨架,其他的功能如路由、狀態管理等是框架分離的組件。

不同點:React:數據流單向,語法—JSX,在React中你需要使用setState()方法去更新狀態。Vue:數據雙向綁定,語法–HTML,state對象并不是必須的,數據由data屬性在Vue對象中進行管理。適用于小型應用,但對于對于大型應用而言不太適合。

1.40.vue生命周期的理解?

參照大神文章:vue筆記 - 生命周期第二次學習與理解
Vue.js面試題及答案有哪些

beforeCreate是new Vue()之后觸發的第一個鉤子,在當前階段data、methods、computed以及watch上的數據和方法都不能被訪問。

created在實例創建完成后發生,當前階段已經完成了數據觀測,也就是可以使用數據,更改數據,在這里更改數據不會觸發updated函數。可以做一些初始數據的獲取,在當前階段無法與Dom進行交互,如果非要想,可以通過vm.$nextTick來訪問Dom。

beforeMount發生在掛載之前,在這之前template模板已導入渲染函數編譯。而當前階段虛擬Dom已經創建完成,即將開始渲染。在此時也可以對數據進行更改,不會觸發updated。

mounted在掛載完成后發生,在當前階段,真實的Dom掛載完畢,數據完成雙向綁定,可以訪問到Dom節點,使用$refs屬性對Dom進行操作。

beforeUpdate發生在更新之前,也就是響應式數據發生更新,虛擬dom重新渲染之前被觸發,你可以在當前階段進行更改數據,不會造成重渲染。

updated發生在更新完成之后,當前階段組件Dom已完成更新。要注意的是避免在此期間更改數據,因為這可能會導致無限循環的更新。

beforeDestroy發生在實例銷毀之前,在當前階段實例完全可以被使用,我們可以在這時進行善后收尾工作,比如清除計時器。

destroyed發生在實例銷毀之后,這個時候只剩下了dom空殼。組件已被拆解,數據綁定被卸除,監聽被移出,子實例也統統被銷毀。

1.41.Vue2.x和Vue3.x渲染器的diff算法分別說一下

簡單來說,diff算法有以下過程

1.同級比較,再比較子節點
2.先判斷一方有子節點一方沒有子節點的情況(如果新的children沒有子節點,將舊的子節點移除)
3.比較都有子節點的情況(核心diff)
3.遞歸比較子節點

正常Diff兩個樹的時間復雜度是O(n^3),但實際情況下我們很少會進行跨層級的移動DOM,所以Vue將Diff進行了優化,從O(n^3) -> O(n),只有當新舊children都為多個子節點時才需要用核心的Diff算法進行同層級比較。

Vue2的核心Diff算法采用了雙端比較的算法,同時從新舊children的兩端開始進行比較,借助key值找到可復用的節點,再進行相關操作。相比React的Diff算法,同樣情況下可以減少移動節點次數,減少不必要的性能損耗,更加的優雅。

Vue3.x借鑒了
ivi算法和 inferno算法

在創建VNode時就確定其類型,以及在 mount/patch 的過程中采用位運算來判斷一個VNode的類型,在這個基礎之上再配合核心的Diff算法,使得性能上較Vue2.x有了提升。(實際的實現可以結合Vue3.x源碼看。)

該算法中還運用了動態規劃的思想求解最長遞歸子序列。

1.42.你都做過哪些Vue的性能優化?

編碼階段

1.盡量減少data中的數據,data中的數據都會增加getter和setter,會收集對應的2.watcher
3.v-if和v-for不能連用
4.如果需要使用v-for給每項元素綁定事件時使用事件代理
5.SPA 頁面采用keep-alive緩存組件
6.在更多的情況下,使用v-if替代v-show
7.key保證唯一
8.使用路由懶加載、異步組件
9.防抖、節流
10.第三方模塊按需導入
11.長列表滾動到可視區域動態加載
12.圖片懶加載

SEO優化

1.預渲染
2.服務端渲染SSR

打包優化

1.壓縮代碼
2.Tree Shaking/Scope Hoisting
3.使用cdn加載第三方模塊
4.多線程打包happypack
5.splitChunks抽離公共文件
6.sourceMap優化

用戶體驗

1.骨架屏
2.PWA

還可以使用緩存(客戶端緩存、服務端緩存)優化、服務端開啟gzip壓縮等。

1.43.hash路由和history路由實現原理說一下

location.hash的值實際就是URL中#后面的東西。

history實際采用了HTML5中提供的API來實現,主要有history.pushState()history.replaceState()

1.44.SPA 單頁面的理解,它的優缺點分別是什么

SPA( single-page application )僅在 Web 頁面初始化時加載相應的 HTML、JavaScript 和 CSS
一旦頁面加載完成,SPA 不會因為用戶的操作而進行頁面的重新加載或跳轉
取而代之的是利用路由機制實現 HTML 內容的變換, UI 與用戶的交互,避免頁面的重新加載
優點:

1、用戶體驗好、快,內容的改變不需要重新加載整個頁面,避免了不必要的跳轉和重復渲染
2、基于上面一點,SPA 相對對服務器壓力小
3、前后端職責分離,架構清晰,前端進行交互邏輯,后端負責數據處理

缺點:

1、初次加載耗時多:為實現單頁 Web 應用功能及顯示效果,
需要在加載頁面的時候將 JavaScript、CSS 統一加載,部分頁面按需加載
2、前進后退路由管理:由于單頁應用在一個頁面中顯示所有的內容,
所以不能使用瀏覽器的前進后退功能,所有的頁面切換需要自己建立堆棧管理
3、SEO 難度較大:由于所有的內容都在一個頁面中動態替換顯示,所以在 SEO 上其有著天然的弱勢

1.45.vue.cli中怎樣使用自定義的組件?有遇到過哪些問題嗎?

第一步:在components目錄新建你的組件文件(indexPage.vue),script一定要export default {}
第二步:在需要用的頁面(組件)中導入:import indexPage from ‘@/components/indexPage.vue’
第三步:注入到vue的子組件的components屬性上面,components:{indexPage}
第四步:在template視圖view中使用,
例如有indexPage命名,使用的時候則index-page

1.46.vue如何實現按需加載配合webpack設置

webpack中提供了require.ensure()來實現按需加載。以前引入路由是通過import 這樣的方式引入,改為const定義的方式進行引入。
不進行頁面按需加載引入方式:import home from '../../common/home.vue'
進行頁面按需加載的引入方式:const home = r => require.ensure( [], () => r (require('../../common/home.vue')))

二、組件 Component

2.1.vue中如何編寫可復用的組件 (編寫組件的原則)

以組件功能命名
只負責ui的展示和交互動畫,不要在組件里與服務器打交道(獲取異步數據等)
可復用組件不會因組件使用的位置、場景而變化。盡量減少對外部條件的依賴。

2.2.如何讓CSS只在當前組件中起作用?

在每一個Vue.js組件中都可以定義各自的CSS、 JavaScript代碼。如果希望組件內寫的CSS只對當前組件起作用,只需要在Style標簽添加Scoped屬性即可

2.3.keep-alive是什么?

如果需要在組件切換的時候,保存一些組件的狀態防止多次渲染,就可以使用 keep-alive 組件包裹需要保存的組件。

兩個重要屬性,include 緩存組件名稱,exclude 不需要緩存的組件名稱。

2.4.如何在 Vue. js動態插入圖片

對“src”屬性插值將導致404請求錯誤。應使用 v-bind:src (簡寫:src)格式代替。

2.5.父子組件的生命周期順序(可參照上方圖解)

加載渲染過程:
beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
子組件更新過程:父beforeUpdate->子beforeUpdate->子updated->父updated
父組件更新過程:父beforeUpdate->父updated
銷毀過程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

三、Vuex

3.1.vuex的核心概念

1.state => 基本數據
2.getters => 從基本數據派生的數據
3.mutations => 修改數據,同步
4.actions => 修改數據,異步 (Action 提交的是 mutation,而不是直接變更狀態)
5.modules => 模塊化Vuex

3.2.vuex是什么?怎么使用?哪種功能場景使用它?

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理器,采用集中式存儲管理應用的所有組件的狀態,主要是為了多頁面、多組件之間的通信。
Vuex有5個重要的屬性,分別是 State、Getter、Mutation、Action、Module,由 view 層發起一個 Action 給 Mutation,在 Mutation 中修改狀態,返回新的狀態,通過 Getter暴露給 view層的組件或者頁面,頁面監測到狀態改變于是更新頁面。如果你的項目很簡單,最好不要使用 Vuex,對于大型項目,Vuex 能夠更好的幫助我們管理組件外部的狀態,一般可以運用在購物車、登錄狀態、播放等場景中。

3.3.多個組件之間如何拆分各自的state,每塊小的組件有自己的狀態,它們之間還有一些公共的狀態需要維護,如何思考這塊

1.公共的數據部分可以提升至和他們最近的父組件,由父組件派發
2.公共數據可以放到vuex中統一管理,各組件分別獲取

3.4.Vue.js中ajax請求代碼應該寫在組件的methods中還是vuex的actions中?

1.如果請求來的數據是不是要被其他組件公用,僅僅在請求的組件內使用,就不需要放入vuex 的state里。

2.如果被其他地方復用,這個很大幾率上是需要的,如果需要,請將請求放入action里,方便復用,并包裝成promise返回,在調用處用async await處理返回的數據。如果不要復用這個請求,那么直接寫在vue文件里很方便

3.5.Vuex中如何異步修改狀態

actions與mutations作用類似,都是可以對狀態進行修改。不同的是actions是異步操作的。

actions是可以調用Mutations里的方法的。

const actions={
	addActions(context){
		context.commit('add',10);//調用mutations中的方法
		setTimeout(()=>{context.commit('reduce')},5000)
	//	setTimeOut(()=>{context.commit('reduce')},3000);
		console.log('我比reduce提前執行');
	},
	
	reduceActions({commit}){
		commit('reduce');
	}}

3.6.Vuex中actions和mutations的區別

Mutation 更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 變更狀態
      state.count++
    }
  }})

Action Action 類似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接變更狀態。
Action 可以包含任意異步操作

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }})

3.7.怎么在組件中批量使用Vuex的state狀態?

使用mapState輔助函數, 利用對象展開運算符將state混入computed對象中

import {mapState} from 'vuex' export default{ computed:{ ...mapState(['price','number']) } }

3.8.Vuex中狀態是對象時,使用時要注意什么?

對象是引用類型,復制后改變屬性還是會影響原始數據,這樣會改變state里面的狀態,是不允許,所以先用深度克隆復制對象,再修改。

四、Router

4.1.vue-router 路由模式有幾種

1.Hash: 使用 URL 的 hash 值來作為路由。支持所有瀏覽器。 帶#。如:http://localhost:8080/#/pageA。改變hash,瀏覽器本身不會有任何請求服務器動作的,但是頁面狀態和url已經關聯起來了。
2.History: 以來 HTML5 History API 和服務器配置。參考官網中 HTML5 History 模式,不帶#, 如:http://localhost:8080/ 正常的而路徑,并沒有#。基于HTML5的 pushState、replaceState實現
3.Abstract: 支持所有 javascript 運行模式。如果發現沒有瀏覽器的 API,路由會自動強制進入這個模式。

4.2.vue-router如何定義嵌套路由

通過children 數組:

const router = new VueRouter({
  routes: [
    {
      path: "/parentPage",
      component: testPage,
      children: [
        {
          path: "/childrenA",
          component: childrenComponentA,
        },
        {
          path: "/childrenB",
          component: childrenComponentB,
        },
      ],
    },
    {
      // 其他和parentPage平級的路由
    },
  ],});

4.3.vue-router有哪幾種導航鉤子?

1.全局導航鉤子:router.beforeEach(to,from,next)
2.組件內的鉤子beforeRouteEnter (to, from, next) beforeRouteUpdate (to, from, next) beforeRouteLeave (to, from, next)
3.單獨路由獨享組件 beforeEnter: (to, from, next)

參數:有to(去的那個路由)、from(離開的路由)、next(一定要用這個函數才能去到下一個路由,如果不用就攔截)最常用就這幾種

4.4. $ route和$ router的區別

1、$route是“路由信息對象”,包括path,params,hash,query,fullPath,matched,name等路由信息參數。

1.$route.path 字符串,對應當前路由的路徑,總是解析為絕對路徑如"/foo/bar"。
2. $route.params 一個 key/value 對象,包含了 動態片段 和 全匹配片段, 如果沒有路由參數,就是一個空對象。
3. $route.query 一個 key/value 對象,表示 URL 查詢參數。 例如,對于路徑 /foo?user=1,則有$route.query.user == 1, 如果沒有查詢參數,則是個空對象
4. $route.hash 當前路由的hash值 (不帶#) ,如果沒有 hash 值,則為空字符串
5. $route.fullPath 完成解析后的 URL,包含查詢參數和hash的完整路徑。
6. $route.matched 數組,包含當前匹配的路徑中所包含的所有片段所對應的配置參數對象。
7. $route.name 當前路徑名字
8. $ route.meta 路由元信息

2、$router是“路由實例”對象包括了路由的跳轉方法,鉤子函數等

實例方法:

1)、push

1.字符串this.$router.push('home')
2. 對象this.$router.push({path:'home'})
3. 命名的路由this.$router.push({name:'user',params:{userId:123}})
4.帶查詢參數,變成 /register?plan=123this.$router.push({path:'register',query:{plan:'123'}})
push方法其實和< router-link :to=“…”>是等同的。
注意:push方法的跳轉會向 history 棧添加一個新的記錄,當我們點擊瀏覽器的返回按鈕時可以看到之前的頁面。

2)、go
頁面路由跳轉
前進或者后退this.$router.go(-1) // 后退

3)、replace
push方法會向 history 棧添加一個新的記錄,而replace方法是替換當前的頁面,
不會向 history 棧添加一個新的記錄

4.5.路由之間跳轉的方式

1.聲明式(標簽跳轉)
2.編程式( js跳轉)

4.6.active-class是哪個組件的屬性

vue-router 模塊 的router-link組件

4.7.vue-router實現路由懶加載(動態加載路由)

把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問時才加載對應的組件即為路由的懶加載,可以加快項目的加載速度,提高效率

const router = new VueRouter({
  routes: [
    {
      path: '/home',
      name: 'Home',      
      component:() = import('../views/home')
	}
  ]})

4.8.怎么定義vue-router的動態路由以及如何獲取傳過來的動態參數?

在router目錄下的index.js文件中,對path屬性加上/:id
使用router對象的params id

關于“Vue.js面試題及答案有哪些”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Vue.js面試題及答案有哪些”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

外汇| 舞钢市| 会泽县| 张北县| 昌吉市| 榆中县| 乌拉特前旗| 广汉市| 淮滨县| 拉萨市| 扎兰屯市| 南华县| 宝清县| 英吉沙县| 开原市| 栾川县| 吉首市| 桂林市| 双流县| 武鸣县| 炉霍县| 镇远县| 成武县| 永修县| 二连浩特市| 遂溪县| 安远县| 平湖市| 马公市| 神农架林区| 色达县| 望谟县| 商河县| 军事| 漳州市| 凤阳县| 波密县| 长乐市| 静宁县| 奉化市| 平果县|