vue相關面試

來自vue相關

什麼是 mvvm?

MVVM 是 Model-View-ViewModel 的縮寫。mvvm 是一種設計思想。Model 層代表數據模型,也可以在 Model 中定義數據修改和操作的業務邏輯;View 代表 UI 組件,它負責將數據模型轉化成 UI 展現出來,ViewModel 是一個同步 View 和 Model 的對象。

簡述Vue的響應式原理

當一個Vue實例創建時,vue會遍歷data選項的屬性,用 Object.defineProperty 將它們轉爲 getter/setter並且在內部追蹤相關依賴,在屬性被訪問和修改時通知變化。
每個組件實例都有相應的 watcher 程序實例,它會在組件渲染的過程中把屬性記錄爲依賴,之後當依賴項的 setter 被調用時,會通知 watcher 重新計算,從而致使它關聯的組件得以更新。

vue生命週期的理解

總共分爲 8 個階段創建前/後,載入前/後,更新前/後,銷燬前/後。
創建前/後: 在 beforeCreate 階段,vue 實例的掛載元素 el 還沒有。
載入前/後:在 beforeMount 階段,vue 實例的$el 和 data 都初始化了,但還是掛載之前爲虛擬的 dom 節點,data.message 還未替換。在 mounted 階段,vue 實例掛載完成,data.message 成功渲染。
更新前/後:當 data 變化時,會觸發 beforeUpdate 和 updated 方法。
銷燬前/後:在執行 destroy 方法後,對 data 的改變不會再觸發周期函數,說明此時 vue 實例已經解除了事件監聽以及和 dom 的綁定,但是 dom 結構依然存在。

爲什麼vue中data必須是一個函數?

當重用組件時,由於數據對象都指向同一個data對象,當在一個組件中修改data時,其他重用的組件中的data會同時被修改;而使用返回對象的函數,由於每次返回的都是一個新對象(Object的實例),引用地址不同,則不會出現這個問題。

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

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

<!-- 組件內的鉤子 -->
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染該組件的對應路由被 confirm 前調用
    // 不!能!獲取組件實例 `this`
    // 因爲當守衛執行前,組件實例還沒被創建
  },
  beforeRouteUpdate (to, from, next) {
    // 在當前路由改變,但是該組件被複用時調用
    // 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由於會渲染同樣的 Foo 組件,因此組件實例會被複用。而這個鉤子就會在這個情況下被調用。
    // 可以訪問組件實例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 導航離開該組件的對應路由時調用
    // 可以訪問組件實例 `this`
  }
}

<!--路由獨享的守衛-->

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

計算屬性和watch的區別 ?

計算屬性是用來一些數據需要隨着其它數據變動而變動時用的.

基於它們的響應式依賴進行緩存的。只在相關響應式依賴發生改變時它們纔會重新求值。依賴還沒有發生改變 , 計算屬性會立即返回之前的計算結果,而不會再次執行函數.

watch是用來監聽數據變動的. 當需要在數據變化時執行異步或開銷較大的操作時,這個方式是最有用的。

vue 組件通信 ?

父傳遞子

父:自定義屬性名 + 數據(要傳遞)=> :value=“數據”
子:props ["父組件上的自定義屬性名“] =>進行數據接收)

子傳遞父

在父組件中註冊子組件並在子組件標籤上綁定自定義事件的監聽。
子:this.$emit(‘自定義事件名稱’, 數據) 子組件標籤上綁定@自定義事件名稱=‘回調函數’
父:methods: {自定義事件() {//邏輯處理} }

的作用是什麼?

保持這些組件的狀態,以避免反覆重渲染導致的性能問題, 緩存動態組件的行爲

$nextTick ?

將回調延遲到下次 DOM 更新循環之後執行,在修改數據之後立即執行.

常用的事件修飾符

.stop .prevent .once .self: 只當事件是從事件綁定的元素本身觸發時才觸發回調

Vue子組件調用父組件的方法

  1. this.$parent
  2. $emit

axios的特點有哪些?

  1. axios是一個基於promise的HTTP庫,支持promise的所有API;
  2. 它可以攔截請求和響應;
  3. 它可以轉換請求數據和響應數據,並對響應回來的內容自動轉換爲json類型的數據;
  4. 它安全性更高,客戶端支持防禦XSRF;

vue中的 ref 是什麼?

ref 被用來給元素或子組件註冊引用信息。引用信息將會註冊在父組件的 $refs 對象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例。

vue.js的兩個核心是什麼?

數據驅動、組件系統

vue如何兼容ie的問題。

babel-polyfill插件

頁面刷新vuex被清空解決辦法?

vuex-persistedstate

import Vue from 'vue'
import Vuex from 'vuex'
import * as Cookies from 'js-cookie'
import createPersistedState from 'vuex-persistedstate'
import createLogger from 'vuex/dist/logger'
import actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
import player from './modules/player/index'
Vue.use(Vuex)

// webpack 中 生產模式或開發
const debug = process.env.NODE_ENV !== 'production'
const store = new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
  modules: {
    player
  },
  // 嚴格模式
  strict: debug,
  plugins: [
    // vuex-persistedstate,使vuex狀態持久化(緩存到本地)
    createPersistedState({
      storage: {
       // cookie / localStorage
        getItem: key => Cookies.get(key),
        setItem: (key, value) => Cookies.set(key, value, {
          expires: 3,
          secure: true
        }),
        removeItem: key => Cookies.remove(key)
      }
    }),
    debug ? createLogger() : false
  ]
})

export default store

如何優化SPA應用的首屏加載速度慢的問題?

  1. 公用js庫外部CDN引入
  2. 路由懶加載
  3. 骨架屏或Loading圖. 優化用戶體驗

DOM 渲染在哪個週期中就已經完成?

mounted, 注意 mounted 不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以用 vm.$nextTick 替換掉 mounted

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

vue中的diff算法是怎樣實現的 ?

diff算法是一種優化手段,將前後兩個模塊(vNode: virtual DOM)進行差異化對比,修補(更新真實的DOM)差異的過程叫做patch(打補丁)

diff的過程就是調用名爲patch的函數,比較新舊節點,一邊比較一邊給真實的DOM打補丁。

virtual DOM是將真實的 DOM 的數據抽取出來,以對象的形式模擬樹形結構,diff算法比較的也是virtual DOM

<div>
  <p>Hello World</p>
</div>
// 轉換成虛擬節點 類似於下面這種
const Vnode = {
  tag:'div',
  children:[
    {tag:'p',text:'Hello World'}
  ]
}

如何比較?

談談你對vue的雙向數據綁定原理的理解

vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變動時發佈消息給訂閱者,觸發相應的監聽回調。

第一步:需要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter和getter。這樣的話,給這個對象的某個值賦值,就會觸發setter,那麼就能監聽到了數據變化

第二步:compile解析模板指令,將模板中的變量替換成數據,然後初始化渲染頁面視圖,並將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,更新視圖

第三步:Watcher訂閱者是Observer和Compile之間通信的橋樑,主要做的事情是:

1、在自身實例化時往屬性訂閱器(dep)裏面添加自己

2、自身必須有一個update()方法

3、待屬性變動dep.notice()通知時,能調用自身的update()方法,並觸發Compile中綁定的回調,則功成身退。

第四步:MVVM作爲數據綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監聽自己的model數據變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變更的雙向綁定效果。

image

MVVM如何實現模板綁定,依賴是如何收集的?

transition: 過渡的實現原理

vue組件間的交互有七種你知道幾種?

請詳細說出vue生命週期的執行過程

vue-router: 官方路由的實現原理

vue-cli3.0如何實現的?

說說hash路由和history路由,你能自己編寫一個前端路由嗎?

你能手寫vuex狀態管理嗎?

待續…

2.5x 源碼解析

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章