天天看點

Vue常見面試題總結

1.vue的生命周期

元件建立期間的四個生命周期函數:

beforeCreate 執行個體初始化之後,this指向建立的執行個體,不能通路到data、computed、watch、methods上的方法和資料,常用于初始化非響應式變量。

created 執行個體建立完成,可通路data、computed、watch、methods上的方法和資料,未挂載到DOM,不能通路到$el屬性,$ref屬性内容為空數組,常用于簡單的ajax請求,頁面的初始化。

beforeMount 在挂載開始之前被調用,頁面中的元素,還沒有真正的替換過來,隻是之前的一些模闆字元串,如{{}}中的data中的資料并不能調用,隻會顯示字元串。

mounted 執行個體挂載到DOM上,此時可以通過DOM API擷取到DOM節點,$ref屬性可以通路。使用者已經可以看到渲染好的頁面,是執行個體建立期間最後一個生命周期函數,執行完mounted就表示,執行個體已經被完全建立好了。

元件運作周期的生命周期函數:

beforeupdate 表示界面還沒有被更新,但是資料(data)已經更新了,執行時,頁面顯示資料還是舊的資料,此時data已經更新,頁面上的資料暫時未和data保持同步。

updated 事件執行的時候,頁面 data資料已經保持同步了,都是最新的。

元件銷毀的生命周期函數:

beforeDestroy 鈎子函數時,vue執行個體就已經從運作階段進入了銷毀階段,執行個體身上所有的data和所有的methods,以及過濾器,指令都是處于可用狀态,還沒有被完全銷毀。

destroyed 元件已經被完全銷毀了,此時元件中所有的資料、方法、指令、過濾器都無法使用。

2.如何封裝axios

https://zhuanlan.zhihu.com/p/32734197

這個知乎網站檢視

3.vue-router的鈎子函數

1.vue router.beforeEach(全局前置守衛)

beforeEach的鈎子函數,他是一個全局的before鈎子函數,(beforeeach)意思是在每次每一個路由改變時都執行一次。

它的三個參數:

to:(router路由對象)即将要進入的目标路由對象to對象下面的屬性: path params query hash...

from:(router路由對象)目前導航正要離開的路由

next:(function函數)一定要調用該方法來resolve這個鈎子。

next(無參數的時候):進行管道中的下一個鈎子,如果走到最後一個鈎子函數,那麼導航的狀态就是confirmed(确認的)

next('/')或者next({path:'/'}):跳轉到一個不同的位址。目前的導航被中斷,然後進行一個新的導航。

4.vue項目上線後出現白屏的情況怎麼處理

第一種:由于把路由模式mode設定成了history了,預設是hash.

解決辦法:路由裡面router/index.js路由配置裡面預設模式是hash,如果改成了history模式的話,打開也會是一片空白。是以改為hash或者直接把模式配置删除,讓它預設的就行。如果非要使用history模式的話,需要你在服務端加一個覆寫所有的情況的候選資源;如果url比對不到任何靜态資源,則應該傳回一個index.html,這個頁面就是你項目的依賴頁面。

第二種:打包後的dist目錄下的檔案引用路徑不對,會因找不到檔案而報錯導緻白屏。

解決辦法:修改一下config下面的index.js中build子產品導出的路徑。因為index.HTML裡面的内容都是通過script标簽引入的,而前面的路徑不對,打開肯定是空白的。

第三種:在項目中使用了es6的文法,一些浏覽器不支援es6,造成編譯錯誤不能解析而造成白屏

解決方法:1.安裝npm install --save-dev babel-preset-es2015

2.安裝 npm install --save-dev babel-preset-stage-3

3.在項目根目錄建立一個.babelrc檔案 裡面内容 最基本配置是:

{

// 此項指明,轉碼的規則

"presets": [

// env項是借助插件babel-preset-env,下面這個配置說的是babel對es6,es7,es8進行轉碼,并且設定amd,commonjs這樣的子產品化檔案,不進行轉碼

["env", { "modules": false }],

// 下面這個是不同階段出現的es文法,包含不同的轉碼插件

"stage-2"

],

// 下面這個選項是引用插件來處理代碼的轉換,transform-runtime用來處理全局函數和優化babel編譯

"plugins": ["transform-runtime"],

// 下面指的是在生成的檔案中,不産生注釋

"comments": false,

// 下面這段是在特定的環境中所執行的轉碼規則,當環境變量是下面的test就會覆寫上面的設定

"env": {

// test 是提前設定的環境變量,如果沒有設定BABEL_ENV則使用NODE_ENV,如果都沒有設定預設就是development

"test": {

"presets": ["env", "stage-2"],

// instanbul是一個用來測試轉碼後代碼的工具

"plugins": ["istanbul"]

}

}

}

然後重新開機npm run dev 你會發現,可以在其他低版本浏覽器跑了,基本相容所有浏覽器,ie8以下除外。而且大多數的手機浏覽器也ok。重新打包到正式環境也正常。

5.token值的應用,存儲在什麼地方

token可以存在 Storage (localStorage \ sessionStorage \ cookie )。這些基本上支援H5的浏覽器對這個本地儲存都相容。如果您是IE678之類的,建議存cookie。

Storage的localStorage長期有效,sessionStorage關閉浏覽器時會自動清除

cookie的可以設定有效期。

在做登入界面時代碼如下:

登入頁面(login.vue)

methods: {
  handleLogin (data) {
    api.AuthResource.save(data).then(response => {
      if (!response.ok) {
        console.log('登入失敗')
      }
      const token = response.data.token
      window.localStorage.setItem('token', token)
      window.location.pathname = '/'
    }, response => {
      console.log('登入失敗')
    })
  }
}           

複制

接口配置(api.js)

Vue.http.interceptors.push((request, next) => {
  if (window.localStorage.getItem('token')) {
    Vue.http.headers.common['Authorization'] = 'Bearer ' + window.localStorage.getItem('token')
  }
  next((response) => {
    if (response.status === 401) {
      del('token')
      window.location.pathname = '/login'
    }
  })
})           

複制

配置路由(router.js)

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: require('./views/Home'),
    meta: {
      requiresAuth: true
    }
  },
]

const router = new VueRouter({
  routes: routes
})

router.beforeEach((to, from, next) => {
  let token = window.localStorage.getItem('token')
  if (to.matched.some(record => record.meta.requiresAuth) && (!token || token === null)) {
    next({
      path: '/login',
      query: { redirect: to.fullPath }
    })
  } else {
    next()
  }
})

export default router           

複制

原理是通過vue-router的beforeEach鈎子,在每次路由到一個位址的時候先判斷該路由是否攜帶了meta資訊,且該資訊中的requireAuth是否為true,如果為true表示該路由是需要身份驗證的。則去localStorage找token,若token不存在則表示使用者未認證,去登入請求token。若token存在則拿着token去請求。

6.vue路由的說明以及應用

路由中有三個基本的概念 route, routes, router。

    1, route,它是一條路由,由這個英文單詞也可以看出來,它是單數, Home按鈕 => home内容, 這是一條route, about按鈕 => about 内容, 這是另一條路由。

    2, routes 是一組路由,把上面的每一條路由組合起來,形成一個數組。[{home 按鈕 =>home内容 }, { about按鈕 => about 内容}]

    3, router 是一個機制,相當于一個管理者,它來管理路由。因為routes 隻是定義了一組路由,它放在哪裡是靜止的,當真正來了請求,怎麼辦?就是當使用者點選home 按鈕的時候,怎麼辦?這時router 就起作用了,它到routes 中去查找,去找到對應的 home 内容,是以頁面中就顯示了 home 内容。

    4,用戶端中的路由,實際上就是dom 元素的顯示和隐藏。當頁面中顯示home 内容的時候,about 中的内容全部隐藏,反之也是一樣。用戶端路由有兩種實作方式:基于hash 和基于html5 history api.

7. 跨域問題的解決

1)背景更改header:

header('Access-Control-Allow-Origin:*');//允許所有來源通路 
 header('Access-Control-Allow-Method:POST,GET');//允許通路的方式           

複制

2)使用jQuery提供的jsonp:

methods: {
 getData () {
 var self = this
 $.ajax({
   url: 'http://f.apiplus.cn/bj11x5.json',
   type: 'GET',
   dataType: 'JSONP',
   success: function (res) {
     self.data = res.data.slice(0, 3)
     self.opencode = res.data[0].opencode.split(',')
   }
 })
}}           

複制

3)使用http-proxy-middleware代了解決(項目需要使用到vue-cli腳手架搭建)

比如請求url:"http://f.apiplus.cn/bj11x5.json"

1.打開config/index.js,在Proxytype中添加如下代碼:

proxyTable: {
   '/api': {  //使用"/api"來代替"http://f.apiplus.c"
     target: 'http://f.apiplus.cn', //源位址
     changeOrigin: true, //改變源
     pathRewrite: {
       '^/api': 'http://f.apiplus.cn' //路徑重寫
       }
   }
 }           

複制

‍ 2.使用axios請求資料時直接使用“/api”

getData () { 
         axios.get('/api/bj11x5.json', function (res) { 
           console.log(res) 
          })           

複制

8、vuex是什麼?怎麼使用?哪種功能場景使用它?

答:vue架構中狀态管理。在main.js引入store,注入。建立了一個目錄store,….. export 。場景有:單頁應用中,元件之間的狀态。音樂播放、登入狀态、加入購物車

9、mvvm架構是什麼?它和其它架構(jquery)的差別是什麼?哪些場景适合?

答:一個model+view+viewModel架構,資料模型model,viewModel連接配接兩個

差別:vue資料驅動,通過資料來顯示視圖層而不是節點操作。

場景:資料操作比較多的場景,更加便捷

10、自定義指令(v-check、v-focus)的方法有哪些?它有哪些鈎子函數?還有哪些鈎子函數參數?

答:全局定義指令:在vue對象的directive方法裡面有兩個參數,一個是指令名稱,另外一個是函數。元件内定義指令:directives

鈎子函數:bind(綁定事件觸發)、inserted(節點插入的時候觸發)、update(元件内相關更新)

鈎子函數參數:el、binding

11、Vue的雙向資料綁定原理是什麼?

12、vue如何實作父子元件通信,以及非父子元件通信?

可以通過props屬性來實作

父元件:

//這裡必須要用 - 代替駝峰

data(){ return { msg: [1,2,3] }; }

子元件通過props來接收資料: 方式1:

props: ['childMsg']

方式2 :

props: { childMsg: Array //這樣可以指定傳入的類型,如果類型不對,會警告 }

方式3:

props: { childMsg: { type: Array, default: [0,0,0] //這樣可以指定預設的值 } }

這樣呢,就實作了父元件向子元件傳遞資料。

可以通過eventHub來實作通信. 所謂eventHub就是建立一個事件中心,相當于中轉站,可以用它來傳遞事件和接收事件.

let Hub = new Vue(); //建立事件中心

元件1觸發:

methods: { eve() { Hub.$emit('change','hehe'); //Hub觸發事件 } }

元件2接收:

created() { Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }

這樣就實作了非父子元件之間的通信了.原理就是把Hub當作一個中轉站!

13. Vue中插槽-----特殊特性slot、slot-scope與指令v-slot的使用方法

https://blog.csdn.net/qq_40616529/article/details/94033417

14、說說你對 SPA 單頁面的了解,它的優缺點分别是什麼?

15、元件中 data 為什麼是一個函數?

【更多擴充】30 道 Vue 面試題,内含詳細講解(涵蓋入門到精通,自測 Vue 掌握程度) -- 基礎必須掌握

https://blog.csdn.net/xu_song/article/details/102861394