2022年Vue面試題

本次讓我們系統(tǒng)的熟悉vue的面試常用題目,無論是給準(zhǔn)備面試還是準(zhǔn)備跳槽的小伙伴晌块,一個學(xué)習(xí)以及溫故知新的版塊爱沟。這其中加入了我的理解,我盡量用白話文和易懂的語言形式進(jìn)行解釋匆背,如果有地方解釋的不正確或者不準(zhǔn)確的情況呼伸,還請大家不吝賜教。

2022年大環(huán)境的不景氣,讓我們用知識充實自己括享,面對生活的一次次挑戰(zhàn)與考驗搂根,加油!

入門級:

1:什么是mvvm铃辖?

MVVM是Model-View-ViewModel的簡寫剩愧,是M-V-VM三部分組成。它本質(zhì)上是MVC的改進(jìn)版本娇斩,MVVM就是將其中的View的狀態(tài)和行為抽象化仁卷,其中ViewModel將視圖 UI 和業(yè)務(wù)邏輯分開,它可以取出 Model 的數(shù)據(jù)同時幫忙處理 View 中由于需要展示內(nèi)容而涉及的業(yè)務(wù)邏輯犬第。

MVVM采用雙向數(shù)據(jù)綁定锦积,view中數(shù)據(jù)變化將自動反映到viewmodel上,反之歉嗓,model中數(shù)據(jù)變化也將會自動展示在頁面上丰介。把Model和View關(guān)聯(lián)起來的就是ViewModel。ViewModel負(fù)責(zé)把Model的數(shù)據(jù)同步到View顯示出來鉴分,還負(fù)責(zé)把View的修改同步回Model哮幢。

讓我們開發(fā)人員可以專注于業(yè)務(wù)邏輯方面(ViewModel),對于數(shù)據(jù)的綁定與展示(自動更新dom)志珍,不需要過多的dom操作橙垢。可以理解為數(shù)據(jù)(medel)驅(qū)動UI(view)碴裙,而UI(view)的改變也會影響數(shù)據(jù)(medel)钢悲。他們之間就是靠ViewModel來實現(xiàn)点额。

因此開發(fā)者只需要關(guān)注業(yè)務(wù)邏輯舔株,不需要手動操作 DOM,也不需要關(guān)注數(shù)據(jù)狀態(tài)的同步問題还棱,這些都由 MVVM 統(tǒng)一管理载慈。

2:為什么要用vue?

1.虛擬dom:dom操作是非常的消耗性能的珍手,不再使用原生的dom操作節(jié)點的方式办铡,模擬一個虛擬dom樹,運用deff算法琳要,只更新修改的dom節(jié)點寡具,極大的釋放了dom操作。

2.視圖稚补,數(shù)據(jù)童叠,結(jié)構(gòu)的分離:使數(shù)據(jù)的更改更為簡單,不需要進(jìn)行邏輯代碼的修改课幕,只需要操作數(shù)據(jù)就能完成相關(guān)操作(mvvm)

3.組件化:把一個單頁應(yīng)用中的各個模塊拆分到一個個單獨的組件中厦坛,各個組件有自己的行為邏輯以及自己的樣式五垮,相互不干擾。便于開發(fā)杜秸,以及后期維護(hù)放仗。相同組件的公用也大大節(jié)約了開發(fā)成本。

3:vue的生命周期(11個鉤子函數(shù))


1.beforeCreate(創(chuàng)建前):在此生命周期函數(shù)執(zhí)行的時候撬碟,data和methods中的數(shù)據(jù)還沒有初始化诞挨。

2.created(創(chuàng)建后):在這個生命周期中,data 和 methods 都已經(jīng)被初始化好了呢蛤,可以訪問到data中的數(shù)據(jù)以及methods的方法亭姥。

3.beforeMount(載入前):在此生命周期函數(shù)執(zhí)行的時候,模板已經(jīng)在內(nèi)存中編譯好了顾稀,但是尚未掛載到頁面中去达罗,此時頁面還是舊的。

4.mounted(載入后):此時頁面和內(nèi)存中是最新數(shù)據(jù)静秆,dom樹創(chuàng)建粮揉,此時才可以操作dom節(jié)點。

5.beforeUpdate(更新前):顧名思義抚笔,這個時候頁面正準(zhǔn)備進(jìn)行更新扶认,只是還未開始更新動作,所以頁面中的數(shù)據(jù)還是舊的殊橙,但是data中的數(shù)據(jù)已經(jīng)是新的辐宾,只是頁面并未和最新數(shù)據(jù)同步。

6.Updated(更新后):此時頁面顯示數(shù)據(jù)和最新的 data 數(shù)據(jù)同步膨蛮。

7.beforeDestroy(銷毀前):組件銷毀前的鉤子函數(shù)叠纹,此時實例上的data,methods敞葛,以及過濾器等都處于可用狀態(tài)誉察。我們一般可以在這個鉤子內(nèi)清除當(dāng)前組件的定時器(clearInterval() )

8.destroyed(銷毀后):此時組件已經(jīng)被完全銷毀惹谐,實例中的所有的數(shù)據(jù)持偏、方法、屬性氨肌、過濾器…等都已經(jīng)不可用了

// 以上8個生命周期鉤子函數(shù)是我們常用的鉤子函數(shù)鸿秆,接下來的3個鉤子函數(shù)可以在特定的時候使用,方便我們理解

9.activated(組件激活時):在使用被keep-alive緩存的組件時怎囚,進(jìn)入函數(shù)卿叽。如果一個子頁面或者一個組件被keep-alive包含,那么當(dāng)這個頁面或組件第一次時會走一次完整的生命周期,當(dāng)此組件無法被銷毀附帽。等重復(fù)使用的時候埠戳,會從緩存里面直接調(diào)出,此時組件不在執(zhí)行前4個生命周期鉤子(因為它并沒有被銷毀蕉扮,不需要重新創(chuàng)建)整胃。取而代之的是進(jìn)入activated鉤子函數(shù)。表示該頁面或組件被激活喳钟。

10.deactivated(組件未激活時):實例沒有被激活時(同9)屁使。

11.errorCaptured(錯誤調(diào)用):當(dāng)捕獲一個來自后代組件的錯誤時被調(diào)用

注意:有很多面試會問父子組件創(chuàng)建銷毀的生命周期順序:
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

即父組件走到beforeMount 后,開始走完子組件的完整生命周期奔则,然后再走父組件mounted

這樣理解:
1.有父才有子蛮寂,所以一開始是父組件先創(chuàng)建實例。
2.mounted本身就是掛在到頁面上的鉤子易茬,所以必須要等所有的子組件完成后再一起掛載到頁面中酬蹋。(既然是父,當(dāng)然要包含所有的子)

4:watch抽莱、computed 和 methods 的區(qū)別

  • methods 方法:組件內(nèi)部的業(yè)務(wù)邏輯方法的集合
  • computed 計算屬性:依賴已有的變量來計算一個目標(biāo)變量范抓,例如根據(jù)data的變量來計算新的變量,用來格式化食铐∝暗妫或者引用store,...mapState的語法糖引用state虐呻。(computed是有緩存的象泵,注意不能進(jìn)行異步操作)
  • watch 監(jiān)聽:監(jiān)聽某一個變量的變化,并且執(zhí)行相應(yīng)的回調(diào)函數(shù)(watch沒有緩存斟叼,目標(biāo)變化一次執(zhí)行一次偶惠,可以進(jìn)行異步操作)

許多面試官喜歡問computed 和watch的區(qū)別,這里請多加理解

5.Vue.js的特點

  • 簡潔:頁面由HTML模板+Json數(shù)據(jù)+Vue實例組成犁柜,結(jié)構(gòu)簡單易懂
  • 數(shù)據(jù)驅(qū)動:自動計算屬性和追蹤依賴的模板表達(dá)式
  • 組件化:用組件來構(gòu)造頁面洲鸠,可復(fù)用,維護(hù)方便
  • 輕量:代碼量小馋缅,不依賴其他庫
  • 快速:精確有效批量 DOM 更新
  • 模板友好:可通過 npm,bower 等多種方式安裝绢淀,很容易融入

6:插槽的理解

插槽用于決定將所攜帶的內(nèi)容萤悴,插入到子組件指定的某個位置,但內(nèi)容必須在父組件中子組件的標(biāo)簽內(nèi)定義皆的,在子組件中用標(biāo)簽接收覆履。slot 是組件內(nèi)部的占位符。即組件編寫時留給組件使用者的一個插入口。使用者可以在此編寫自己的html格式以及樣式硝全,插入的位置由編寫者制定

7.Vue組件之間傳參

1.父傳子:

  • 父組件通過props方式傳遞數(shù)據(jù)
  • 父組件也可以直接選擇子節(jié)點的形式選中子組件的實例
this.$refs.nodeName // refs是根據(jù)組件名字來取的響應(yīng)組件的屬性
this.$children[2] // 返回一個數(shù)組(使用幾率小栖雾,一般不這樣調(diào)用)

2.子傳父:

  • 子組件用$emit方法,觸發(fā)父組件的監(jiān)聽
  • this.$parnet獲取當(dāng)前組件的父組件實例

3.兄弟組件之間(這里寫的是兄弟組件之間伟众,實際上是所有組件之間都可以析藕,包括父子)

  • 用一個事件總線,evenBus凳厢。新建一個空的vue實例作事件總線(為了方便調(diào)用一般綁定到vue原型)账胧,然后用$on監(jiān)聽事件,用$emit觸發(fā)事件先紫。
this.$eventBus.$on('sayName',(data)=>{
  console.log(data)
}) // 監(jiān)聽事件總線中sayName方法
this.$eventBus.$emit('sayName',data)

詳細(xì)講解請移步到:http://www.reibang.com/p/267e17c59d32

  • Vuex:Vuex 是一個專門為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式治泥。在下面的復(fù)習(xí)中我們會詳細(xì)講解到

4.瀏覽器本地緩存,例如localStorage遮精,sessionStorage

8.vue 組件中的 data 為什么是一個函數(shù)

data 是一個函數(shù)時居夹,每個組件實例都有自己的作用域,每個實例相互獨立本冲,不會相互影響吮播。Object 是引用數(shù)據(jù)類型,如果不用 function 返回眼俊,每個組件的 data 都是內(nèi)存的同一個地址(儲存的是地址意狠,指針,此處可以復(fù)習(xí)淺拷貝和深拷貝)疮胖,一個數(shù)據(jù)改變了其他也改變了环戈。
理解就是運用了function的函數(shù)作用域讓他變成局部作用域,這樣每復(fù)用一次組件澎灸,就會返回一份新的 data院塞,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間

9.路由懶加載(首頁加載優(yōu)化)

在單頁應(yīng)用中,如果沒有應(yīng)用懶加載性昭,運用 webpack 打包后的文件將會異常的大拦止,造成進(jìn)入首頁時,需要加載的內(nèi)容過多糜颠,延時過長汹族,不利于用戶體驗,而運用懶加載則可以將頁面進(jìn)行劃分其兴,需要的時候加載頁面顶瞒,可以有效的分擔(dān)首頁所承擔(dān)的加載壓力,減少首頁加載用時

原理:vue 異步組件技術(shù):異步加載元旬,vue-router 配置路由 , 使用 vue 的異步組件技術(shù) , 實現(xiàn)按需加載


import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
  routes: [
//     {
//       path: '/',
//       name: 'HelloWorld',
//       component: HelloWorld
//     }
        {
          path: '/',
          name: 'HelloWorld',
          component: () => import('@/components/HelloWorld.vue')
        }
  ]
})

10:請說出 vue.cli 項目中 src 目錄每個文件夾和文件的用法`

assets 文件夾是放靜態(tài)資源榴徐;
components 是放組件守问;
router 是定義路由相關(guān)的配置;
store vuex模塊;
view 視圖坑资;
app.vue 是一個應(yīng)用主組件耗帕;
main.js 是入口文件

11.Vue 中 key 值的作用

當(dāng) Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認(rèn)用“就地復(fù)用”策略袱贮。如果數(shù)據(jù)項的順序被改變仿便,Vue 將不會移動 DOM 元素來匹配數(shù)據(jù)項的順序, 而是簡單復(fù)用此處每個元素字柠,并且確保它在特定索引下顯示已被渲染過的每個元素探越。key 的作用主要是為了高效的更新虛擬 DOM。
key 是為 Vue 中 vnode 的唯一標(biāo)記窑业,通過這個 key钦幔,我們的 diff 操作可以更準(zhǔn)確、更快速

12:vue 的指令

  • v-bind:給元素綁定屬性常柄,簡寫為:

  • v-on:給元素綁定事件,簡寫為@

  • v-html:給元素綁定數(shù)據(jù)鲤氢,且該指令可以解析 html 標(biāo)簽

  • v-text:給元素綁定數(shù)據(jù),不解析標(biāo)簽

  • v-model:數(shù)據(jù)雙向綁定

  • v-for:遍歷數(shù)組

  • v-show:條件渲染指令西潘,將不符合條件的數(shù)據(jù)隱藏(display:none)

  • v-if:條件渲染指令卷玉,動態(tài)在 DOM 內(nèi)添加或刪除 DOM 元素(無節(jié)點)

  • v-else:條件渲染指令,必須跟 v-if 成對使用

  • v-else-if:判斷多層條件喷市,必須跟 v-if 成對使用

  • v-cloak:解決插值閃爍問題

  • v-once:只渲染元素或組件一次

  • v-pre:跳過這個元素以及子元素的編譯過程相种,以此來加快整個項目的編譯速度

13.v-for 與 v-if

因為v-for的優(yōu)先級高于v-if,勢必會先遍歷數(shù)組品姓,然后再判斷是否顯示寝并,這樣就會影響速度,尤其是只需要渲染很小一部分的時候腹备,渲染了許多無用的節(jié)點衬潦,增加許多無用的dom操作,建議用computed先把需要的數(shù)組格式化出來

<div v-for="item in list">
    {{item}}
</div>

computed() {
    list() {
        return [1, 2, 3, 4, 5, 6, 7].filter(item => item !== 3)
    }
 }

14.Vue怎么兼容IE

使用 babel-polyfill 插件省省吧植酥,2022年6月16日起ie都退役了

15.Vue 怎么重置 data

在很多情況下我們會遇到初始化data的時候镀岛,比如在調(diào)用element的dialog組件時(組件是v-show控制,會保留之前的狀態(tài))

Object.assign(this.$data, this.$options.data()) // 初始化data

16.route 和 router

  • route 是“路由信息對象”友驮,包括 path,params,hash,query,fullPath,matched,name 等路由信息參數(shù)漂羊。
    route查詢修改當(dāng)前路由的對象
  • router 是“路由實例對象”,包括了路由的跳轉(zhuǎn)方法(push喊儡、go)拨与,鉤子函數(shù)等。
    router獲取當(dāng)前路由實例艾猜,調(diào)用方法

17.Vue的修飾符有哪些买喧?


常用修飾符:

  • .stop 阻止事件繼續(xù)傳播
  • .prevent 阻止標(biāo)簽?zāi)J(rèn)行為
  • .capture 使用事件捕獲模式,即元素自身觸發(fā)的事件先在此處處理,然后才交由內(nèi)部元素進(jìn)行處理
  • .self 只當(dāng)在 event.target 是當(dāng)前元素自身時觸發(fā)處理函數(shù)
  • .once 事件將只會觸發(fā)一次
  • .passive 告訴瀏覽器你不想阻止事件的默認(rèn)行為
  • .right 使用鼠標(biāo)右鍵觸發(fā)事件@click.right

中級:

1.虛擬 DOM 原理

虛擬 DOM匆赃,其實就是用對象的方式取代真實的DOM操作淤毛,把真實的DOM操作放在內(nèi)存當(dāng)中,在內(nèi)存中的對象里做模擬操作算柳。當(dāng)頁面打開時瀏覽器會解析 HTML 元素低淡,構(gòu)建一顆 DOM樹,將狀態(tài)全部保存起來瞬项,在內(nèi)存當(dāng)中模擬我們真實的 DOM操作蔗蹋,操作完后又會生成一顆 dom 樹,兩顆DOM樹進(jìn)行比較囱淋,根據(jù) diff 算法比較兩顆 DOM樹不同的地方猪杭,只渲染一次不同的地方。
用diff算法把虛擬DOM和真實DOM比較妥衣,找出不同的地方皂吮,頁面只渲染不同的地方

2:nextTick 的理解

Vue 是異步修改 DOM 的,并且不鼓勵開發(fā)者直接接觸 DOM税手,但是有時候需要必須對數(shù)據(jù)更改后的 DOM 元素做相應(yīng)的處理蜂筹,但是獲取到的 DOM 數(shù)據(jù)并不是更改后的數(shù)據(jù),這時候就需要 this.$nextTick()芦倒;
很常見一個例子艺挪,在數(shù)據(jù)變化后馬上要使用ref進(jìn)行節(jié)點操作,由于vue是異步修改dom的兵扬,所以在數(shù)據(jù)變化后可能沒有找到需要操作的dom麻裳,故而報錯

<div ref="mydom"  v-if="isShow"></div>

  methods() {
    this.isShow = true;
    this.$nextTick(()=>{
      this.$refs.mydom.play() // 等待最新的dom更新了之后的回調(diào),此時已經(jīng)有了mydom節(jié)點周霉,可以對其進(jìn)行dom操作
    })
  },

3.不需要響應(yīng)式的數(shù)據(jù)應(yīng)該怎么處理掂器?

在我們的Vue開發(fā)中,會有一些數(shù)據(jù)俱箱,從始至終都未曾改變過国瓮,這種死數(shù)據(jù),既然不改變狞谱,那也就不需要對他做響應(yīng)式處理了乃摹,不然只會做一些無用功消耗性能,比如一些寫死的下拉框跟衅,寫死的表格數(shù)據(jù)孵睬,這些數(shù)據(jù)量大的死數(shù)據(jù),如果都進(jìn)行響應(yīng)式處理伶跷,那會消耗大量性能掰读。

// 方法一:將數(shù)據(jù)定義在return 之外(初始化時期只會對data內(nèi)的數(shù)據(jù)綁定getter和setter)
data () {
    this.list1 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list2 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list3 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list4 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list5 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    return {}
 }
    
// 方法二:Object.freeze()
data () {
    return {
        list1: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list2: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list3: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list4: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list5: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
    }
 }

4.vue 中的雙向綁定原理

概念:雙向綁定是vue的一個核心功能秘狞,所謂雙向綁定就是當(dāng)視圖發(fā)生改變的時候傳遞給VM(ViewModel ),讓數(shù)據(jù)得到更新,當(dāng)數(shù)據(jù)發(fā)生改變的時候傳給VM(ViewModel ),使得視圖發(fā)生變化蹈集。

那么vue怎么做到的呢烁试?
observer(觀察者),劫持監(jiān)聽所有屬性拢肆,什么意思呢减响?

vue.js是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter郭怪,getter支示,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)來渲染視圖鄙才。

先簡單的實現(xiàn)一個js的雙向數(shù)據(jù)綁定來熟悉一下Object.defineProperty()方法

 <input type="text" id="in"/>
    輸入的值為:<span id="out"></span>
    <script>
        var int = document.getElementById('in');
        var out = document.getElementById('out');
        var obj = {};
        Object.defineProperty(obj, 'msg', {
            enumerable: true,
            configurable: true,
            set (newVal) {
                out.innerHTML = newVal;
            }
        })
        int.addEventListener('input', function(e) {
            obj.msg = e.target.value;
        })

/*通過給in輸入框添加事件監(jiān)聽input來觸發(fā)obj對象的set方法颂鸿,
而set在修改了訪問器屬性的同時,也修改了dom樣式咒循,改變了span標(biāo)簽內(nèi)的文本据途。*/

5.vue3的了解

大致有三個點:
1.關(guān)于提出的新 API setup()函數(shù)。
2.對于 Typescript 的支持叙甸。
3.最后說了關(guān)于替換 Object.defineProperty 為 Proxy 的支持颖医。詳細(xì)說了下關(guān)于 Proxy 代替帶來的性能上的提升,因為傳統(tǒng)的原型鏈攔截的方法裆蒸,無法檢測對象及數(shù)組的一些更新操作熔萧,但使用 Proxy 又帶來了瀏覽器兼容問題。

6.vue-cli 替我們做了哪些工作

vue-cli 是基于 Vue.js 進(jìn)行快速開發(fā)的完整系統(tǒng)僚祷,也可以理解成是很多 npm 包的集合佛致。
vue-cli 完成的功能:

  • .vue 文件 --> .js 文件
  • ES6 語法 --> ES5 語法
  • Sass,Less,Stylus --> CSS
  • 對 jpg,png,font 等靜態(tài)資源的處理
  • 熱更新
  • 定義環(huán)境變量,區(qū)分 dev 和 production 模式
  • 如果開發(fā)者需要補充或修改默認(rèn)設(shè)置辙谜,需要在 package.json 同級下新建一個 vue.config.js 文件

7.axios攔截器

響應(yīng)攔截

axios.interceptors.response.use((response)=>{
    //對響應(yīng)數(shù)據(jù)做點什么
    return response.data
},(error)=>{
    //對錯誤響應(yīng)做點什么
    return Promise.reject(error)
})

請求攔截

axios.interceptors.request.use((config)=>{
    //在發(fā)送請求之前做些什么
    return config
},(error)=>{
    //對請求錯誤做些什么
    return Promise.reject(error)
})

14:vue-router 路由鉤子函數(shù)是什么 執(zhí)行順序是什么

路由鉤子的執(zhí)行流程, 鉤子函數(shù)種類有:全局守衛(wèi)俺榆、路由守衛(wèi)、組件守衛(wèi)

完整的導(dǎo)航解析流程:

  • 導(dǎo)航被觸發(fā)装哆。
  • 在失活的組件里調(diào)用 beforeRouteLeave 守衛(wèi)罐脊。
  • 調(diào)用全局的 beforeEach 守衛(wèi)。
  • 在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi) (2.2+)蜕琴。
  • 在路由配置里調(diào)用 beforeEnter萍桌。
  • 解析異步路由組件。
  • 在被激活的組件里調(diào)用 beforeRouteEnter凌简。
  • 調(diào)用全局的 beforeResolve 守衛(wèi) (2.5+)上炎。
  • 導(dǎo)航被確認(rèn)。
  • 調(diào)用全局的 afterEach 鉤子雏搂。
  • 觸發(fā) DOM 更新藕施。
  • 調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)寇损,創(chuàng)建好的組件實例會作為回調(diào)函數(shù)的參數(shù)傳入

1.全局守衛(wèi):

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
  }
]

const router = new VueRouter({
  routes
})
// 跳轉(zhuǎn)路由之前
router.beforeEach((to,from,next)=>{
  // ..............
  next()
})
// 跳轉(zhuǎn)路由之后
router.afterEach((to,from,next)=>{
  // ..............
  next()
})

export default router

2.單個路由獨享的守衛(wèi)

const routes = [
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
    beforeEach:((to,from,next)=>{
      // ..............
      next()
    })
  }
]

3.組件級守衛(wèi)(beforeRouteEnter)組件級的守衛(wèi)寫在頁面組件中,與data,methods同級铅碍。如圖

export default {
  data(){
    return{}
  },
  created:{},
  components: {},
  methods:{},
  beforeRouteEnter(to,from,next){
      // ..............
  next()
  }
};

15.Vuex的理解重點

定義:Vuex是一個專為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式润绵。它采用集中式儲存管理應(yīng)用的所有組件的狀態(tài)线椰,并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化胞谈。
使用場景:需要構(gòu)建一個中大型單頁應(yīng)用,您很可能會考慮如何更好的在組件外部管理狀態(tài)憨愉,Vuex將會成為自然而然的選擇烦绳。
優(yōu)點:當(dāng)你在state中定義了一個數(shù)據(jù)之后,可以在所在項目中的任何一個組件里進(jìn)行獲取配紫、進(jìn)行修改径密、并且你的修改可以得到全局的響應(yīng)變更。(全局變量理解方式)

主要包括以下幾個模塊:

  • State:定義了應(yīng)用狀態(tài)的數(shù)據(jù)結(jié)構(gòu)躺孝,可以在這里設(shè)置默認(rèn)的初始狀態(tài)享扔。
  • Getter:允許組件從 Store 中獲取數(shù)據(jù),mapGetters 輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計算屬性植袍。
  • Mutation:是唯一更改 store 中狀態(tài)的方法惧眠,且必須是同步函數(shù)
  • Action:用于提交 mutation于个,而不是直接變更狀態(tài)氛魁,可以包含任意異步操作
  • Module:允許將單一的 Store 拆分為多個 store 且同時保存在單一的狀態(tài)樹中厅篓。大型項目時可以把store也拆分多個模塊秀存,每個store包含自己的state,getter,mutation,action

Vuex的運行機(jī)制:Vuex提供數(shù)據(jù)(state)來驅(qū)動試圖(vue components),通過dispath派發(fā)actions羽氮,在其中可以做一些異步的操作泉褐,然后通過commit來提交mutations晓折,最后mutations來更改state。

import Vuex from 'vuex';
import Vue from 'vue';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
  },
  mutations: {
    increment(state, val) {
      console.log(state);
    },
  },
  actions: {
    addCount(context) {
      console.log(context);
      // 可以包含異步操作
      // context 是一個與 store 實例具有相同方法和屬性的 context 對象
    },
  },
  getters: {
    doneTodos(state) {
      return state;
    }
  }
});

export default store;

16:Vuex 頁面刷新數(shù)據(jù)丟失怎么解決

我們都知道,vuex是作為一個公共的狀態(tài)管理集合禾蚕,但是他是存儲在內(nèi)存中的,在瀏覽器中掏击,刷新頁面會清空一次內(nèi)存棍厌。顯然對于一些公共的狀態(tài),我們是不希望刷新清空的掀淘,這里就有了vuex數(shù)據(jù)持久化的一個問題

需要做 vuex 數(shù)據(jù)持久化 一般使用本地存儲的方案來保存數(shù)據(jù) 可以自己設(shè)計存儲方案 也可以使用第三方插件

1.推薦使用 vuex-persist 插件旬蟋,它就是為 Vuex 持久化存儲而生的一個插件。不需要你手動存取 storage 革娄,而是直接將狀態(tài)保存至 cookie 或者 localStorage 中
(注實際開發(fā)中使用sessionStorage來保存倾贰,原因是localStorage在同一瀏覽器中多個賬戶登錄保存到localStroage會出問題)

2.或者手動把vuex數(shù)據(jù)存儲在sessionStorage中

window.addEventListener('beforeunload', e => {
  console.log('頁面進(jìn)行了刷新或者關(guān)閉')
// 保存vuex操作
})
// 注意要卸載監(jiān)聽事件
window.removeEventListener('beforeunload', e =>{})

17.你都用過哪些vue性能優(yōu)化

這里只列舉針對 Vue 的性能優(yōu)化 整個項目的性能優(yōu)化是一個大工程 可以另寫一篇性能優(yōu)化的文章了

1.減少http請求
2.對象層級不要過深冕碟,否則性能就會差
3.不需要響應(yīng)式的數(shù)據(jù)不要放到 data的return 中(可以用 Object.freeze() 凍結(jié)數(shù)據(jù))
4.v-if 和 v-show 區(qū)分使用場景
5.computed 和 watch 區(qū)分使用場景
6.v-for 遍歷必須加 key,key 最好是 id 值匆浙,且避免同時使用 v-if
7.大數(shù)據(jù)列表和表格性能優(yōu)化-虛擬列表/虛擬表格
8.防止內(nèi)部泄漏安寺,組件銷毀后把全局變量和事件銷毀
9.圖片懶加載
10.路由懶加載(首頁加載優(yōu)化)
11.第三方插件的按需引入
12.適當(dāng)采用 keep-alive 緩存組件
13.防抖、節(jié)流運用
14.服務(wù)端渲染 SSR or 預(yù)渲染
15.插件引入盡量不要全局引入(首頁加載優(yōu)化)

18.描述下vue從初始化頁面=>修改數(shù)據(jù)=>刷新頁面 UI 過程首尼?

1.當(dāng) Vue 進(jìn)入初始化階段時挑庶,一方面 Vue 會遍歷 data 中的屬性,并用 Object.defineProperty 將它轉(zhuǎn)化成 getter/setterd 的形式软能,實現(xiàn)數(shù)據(jù)劫持迎捺;
2.另一方面,Vue 的指令編譯器 Compiler 對元素節(jié)點的各個指令進(jìn)行解析查排,初始化視圖凳枝,并訂閱 Watcher 來更新視圖,此時 Watcher 會將自己添加到消息訂閱器 Dep 中跋核,此時初始化完畢岖瑰。
3.當(dāng)數(shù)據(jù)發(fā)生變化時,觸發(fā) Observer 中 setter 方法砂代,立即調(diào)用 Dep.notify( )蹋订,Dep 這個數(shù)組開始遍歷所有的訂閱者,并調(diào)用其 update 方法泊藕,Vue 內(nèi)部再通過 diff 算法辅辩,patch 相應(yīng)的更新完成對訂閱者視圖的改變。

19.給對象添加了新的屬性娃圆,data改變了玫锋,但是頁面上沒有改變,為什么讼呢?

這里用到$set

原因:vue在創(chuàng)建實例的時候把data深度遍歷所有屬性,并使用 Object.defineProperty 把這些屬性全部轉(zhuǎn)為 getter/setter撩鹿。讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化悦屏。所以屬性必須在 data 對象上存在才能讓 Vue 轉(zhuǎn)換它节沦,這樣才能讓它是響應(yīng)的。

vue.$set 是能讓 vue 知道你添加了屬性, 它會給你做處理

change(){
  this.$set(this.list,1,0);
}

進(jìn)階級

1.說一下Vue.mixin

在日常的開發(fā)中础爬,我們經(jīng)常會遇到在不同的組件中經(jīng)常會需要用到一些相同或者相似的代碼甫贯,這些代碼的功能相對獨立,可以通過 Vue 的 mixin 功能抽離公共的業(yè)務(wù)邏輯看蚜,原理類似“對象的繼承”叫搁,當(dāng)組件初始化時會調(diào)用 mergeOptions 方法進(jìn)行合并,采用策略模式針對不同的屬性進(jìn)行合并。當(dāng)組件和混入對象含有同名選項時渴逻,這些選項將以恰當(dāng)?shù)姆绞竭M(jìn)行“合并”
詳細(xì)請點擊http://www.reibang.com/p/772d67305f98

2.keep-alive 使用場景和原理

keep-alive 是 Vue 內(nèi)置的一個組件疾党,可以實現(xiàn)組件緩存,當(dāng)組件切換時不會對當(dāng)前組件進(jìn)行卸載惨奕。

  • 常用的兩個屬性 include/exclude雪位,允許組件有條件的進(jìn)行緩存。
  • 兩個生命周期 activated/deactivated梨撞,用來得知當(dāng)前組件是否處于活躍狀態(tài)雹洗。
  • keep-alive 的中還運用了 LRU(最近最少使用) 算法,選擇最近最久未使用的組件予以淘汰

3.函數(shù)式組件使用場景和原理

1.函數(shù)式組件需要在聲明組件是指定 functional:true
2.不需要實例化聋袋,所以沒有this,this通過render函數(shù)的第二個參數(shù)context來代替
3.沒有生命周期鉤子函數(shù)队伟,不能使用計算屬性,watch
4.不能通過$emit對外暴露事件幽勒,調(diào)用事件只能通過context.listeners.click的方式調(diào)用外部傳入的事件
5.因為函數(shù)式組件是沒有實例化的,所以在外部通過ref去引用組件時港令,實際引用的是HTMLElement
6.函數(shù)式組件的props可以不用顯示聲明啥容,所以沒有在props里面聲明的屬性都會被自動隱式解析為prop,而普通組件所有未聲明的屬性都解析到$attrs里面,并自動掛載到組件根元素上面(可以通過inheritAttrs屬性禁止)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顷霹,一起剝皮案震驚了整個濱河市咪惠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淋淀,老刑警劉巖遥昧,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異朵纷,居然都是意外死亡炭臭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門袍辞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞋仍,“玉大人,你說我怎么就攤上這事搅吁⊥矗” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵谎懦,是天一觀的道長肚豺。 經(jīng)常有香客問我,道長界拦,這世上最難降的妖魔是什么吸申? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上呛谜,老公的妹妹穿的比我還像新娘在跳。我一直安慰自己,他們只是感情好隐岛,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布猫妙。 她就那樣靜靜地躺著,像睡著了一般聚凹。 火紅的嫁衣襯著肌膚如雪割坠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天妒牙,我揣著相機(jī)與錄音彼哼,去河邊找鬼。 笑死湘今,一個胖子當(dāng)著我的面吹牛敢朱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摩瞎,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼拴签,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旗们?” 一聲冷哼從身側(cè)響起蚓哩,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎上渴,沒想到半個月后岸梨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡稠氮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年曹阔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片括袒。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡次兆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锹锰,到底是詐尸還是另有隱情芥炭,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布恃慧,位于F島的核電站园蝠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痢士。R本人自食惡果不足惜彪薛,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一茂装、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧善延,春花似錦少态、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至豆茫,卻和暖如春侨歉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背揩魂。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工幽邓, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人火脉。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓牵舵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親忘分。 傳聞我的和親對象是個殘疾皇子棋枕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容