前端面試題Vue答案

1.vue的原理?

image.png

關(guān)鍵詞: 虛擬DOM樹+訪問(wèn)器屬性

  • 解釋一下:響應(yīng)式原理?

當(dāng)你把一個(gè)普通的 JavaScript 對(duì)象傳入 Vue 實(shí)例作為 data 選項(xiàng),Vue 將遍歷此對(duì)象所有的 property,并使用 Object.defineProperty把這些 property 全部轉(zhuǎn)為 getter/setter這些 getter/setter 對(duì)用戶來(lái)說(shuō)是不可見(jiàn)的,但是在內(nèi)部它們讓 Vue 能夠追蹤依賴,在 property 被訪問(wèn)和修改時(shí)通知變更,每個(gè)組件實(shí)例都對(duì)應(yīng)一個(gè) watcher 實(shí)例,它會(huì)在組件渲染的過(guò)程中把“接觸”過(guò)的數(shù)據(jù) property 記錄為依賴。之后當(dāng)依賴項(xiàng)的 setter 觸發(fā)時(shí),會(huì)通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染。

  • vue為什么不支持IE8及更低版本?

Object.defineProperty` 是 ES5 中一個(gè)無(wú)法 shim 的特性,這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的原因。

2. vue有哪些缺點(diǎn)

  1. Vue 不能檢測(cè)數(shù)組和對(duì)象的變化

3.為什么vue不能檢測(cè)對(duì)象的變化

對(duì)于對(duì)象, Vue 無(wú)法檢測(cè) property 的添加或移除,由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì) property 執(zhí)行 getter/setter 轉(zhuǎn)化,所以 property 必須在 data 對(duì)象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的.

  • 追問(wèn):那如何解決上述問(wèn)題?

使用this.$set(this.someObject,'b',2) 添加新的屬性
使用this.$delete(this.someObject,'b') 刪除舊屬性

4.講一下 $set 的實(shí)現(xiàn)原理

1、如果目標(biāo)是數(shù)組,使用 vue 實(shí)現(xiàn)的變異方法 splice 實(shí)現(xiàn)響應(yīng)式
2、如果目標(biāo)是對(duì)象,判斷屬性存在,即為響應(yīng)式,直接賦值
3、如果 target 本身就不是響應(yīng)式,直接賦值
4、如果屬性不是響應(yīng)式,則調(diào)用 defineReactive 方法進(jìn)行響應(yīng)式處理

核心代碼如下

export function set(target: Array | Object, key: any, val: any): any {
  // target 為數(shù)組
  if (Array.isArray(target) && isValidArrayIndex(key)) {
   // 修改數(shù)組的長(zhǎng)度, 避免索引>數(shù)組長(zhǎng)度導(dǎo)致splice()執(zhí)行有誤
    target.length = Math.max(target.length, key);
    // 利用數(shù)組的splice變異方法觸發(fā)響應(yīng)式
    target.splice(key, 1, val);
    return val;
  }

  // target為對(duì)象, key在target或者target.prototype上 且必須不能在 Object.prototype 上,直接賦值
  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }

  // 以上都不成立, 即開(kāi)始給target創(chuàng)建一個(gè)全新的屬性
  // 獲取Observer實(shí)例
  const ob = (target: any).__ob__;
  // target 本身就不是響應(yīng)式數(shù)據(jù), 直接賦值
  if (!ob) {
    target[key] = val;
    return val;
  }

  // 進(jìn)行響應(yīng)式處理
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;
}

5.new Vue()實(shí)例中,data 可以直接是一個(gè)對(duì)象,為什么在 vue 組件中,data 必須是一個(gè)函數(shù)呢?

關(guān)鍵詞:復(fù)用+污染 + 函數(shù)返回 + 數(shù)據(jù)拷貝

因?yàn)榻M件是可以復(fù)用的,JS 里對(duì)象是引用關(guān)系,如果組件 data 是一個(gè)對(duì)象,那么子組件中的 data 屬性值會(huì)互相污染,產(chǎn)生副作用。所以一個(gè)組件的 data 選項(xiàng)必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝。new Vue 的實(shí)例是不會(huì)被復(fù)用的,因此不存在以上問(wèn)題。

6.computed 和 watch 有什么區(qū)別?

image.png

computed 計(jì)算屬性 :
依賴其它屬性值,只有它依賴的屬性值發(fā)生改變,下一次獲取 computed 的值時(shí)才會(huì)重新計(jì)算 computed 的值,如果和上次計(jì)算結(jié)果不一致,重新渲染頁(yè)面。
watch 偵聽(tīng)器 : 更多的是「觀察」的作用,無(wú)緩存性,類似于某些數(shù)據(jù)的監(jiān)聽(tīng)回調(diào),每當(dāng)監(jiān)聽(tīng)的數(shù)據(jù)變化時(shí)都會(huì)執(zhí)行回調(diào)進(jìn)行后續(xù)操作。

追問(wèn):computed 和 watch 應(yīng)用場(chǎng)景?
關(guān)鍵詞 computed+緩存

computed :當(dāng)我們需要進(jìn)行數(shù)值計(jì)算,并且依賴于其它數(shù)據(jù)時(shí),應(yīng)該使用 computed,因?yàn)榭梢岳?computed 的緩存特性,避免每次獲取值時(shí),都要重新計(jì)算。
watch: 當(dāng)我們需要在數(shù)據(jù)變化時(shí)執(zhí)行的操作時(shí)使用(如調(diào)用其它函數(shù))

追問(wèn) :能使用箭頭函數(shù)定義computed和watch嗎?

不應(yīng)該使用箭頭函數(shù)來(lái)定義 watcher 函數(shù),理由是箭頭函數(shù)綁定了父級(jí)作用域的上下文,所以 this 將不會(huì)按照期望指向 Vue 實(shí)例,為undefined

7.MVC和MVVM的原理

  • MVC


    image.png

視圖(View):用戶界面。
控制器(Controller):業(yè)務(wù)邏輯
模型(Model):數(shù)據(jù)保存

實(shí)現(xiàn)流程

1.View 傳送指令到 Controller
2.Controller 完成業(yè)務(wù)邏輯后,要求 Model 改變狀態(tài)
3.Model 將新的數(shù)據(jù)發(fā)送到 View,用戶得到反饋

  • MVVM

視圖(View):用戶界面。
視圖模型(VM):雙向數(shù)據(jù)綁定
模型(Model):數(shù)據(jù)+業(yè)務(wù)

在MVVM架構(gòu)下,View 和 Model 之間并沒(méi)有直接的聯(lián)系,而是通過(guò)ViewModel進(jìn)行交互. Model 和 ViewModel 之間的交互是雙向的, 因此View 數(shù)據(jù)的變化會(huì)同步到Model中,而Model 數(shù)據(jù)的變化也會(huì)立即反應(yīng)到View 上。

image.png

8.vue數(shù)據(jù)綁定是雙向還是單向的

Vue 在不同組件間強(qiáng)制使用單向數(shù)據(jù)流。這使應(yīng)用中的數(shù)據(jù)流更加清晰易懂。

9.v-model雙向綁定的原理?

v-model 本質(zhì)上不過(guò)是語(yǔ)法糖。它負(fù)責(zé)監(jiān)聽(tīng)用戶的輸入事件以更新數(shù)據(jù).

原理如下:

Object.defineproperty()重新定義(set方法)對(duì)象設(shè)置屬性值和(get方法)獲取屬性值的操縱來(lái)實(shí)現(xiàn)的.
1.實(shí)現(xiàn)一個(gè)監(jiān)聽(tīng)器Observer,用來(lái)劫持并監(jiān)聽(tīng)所有屬性,如果有變動(dòng)的,就通知訂閱者。
2.實(shí)現(xiàn)一個(gè)訂閱者Watcher,可以收到屬性的變化通知并執(zhí)行相應(yīng)的函數(shù),從而更新視圖。
3.實(shí)現(xiàn)一個(gè)解析器Compile,可以掃描和解析每個(gè)節(jié)點(diǎn)的相關(guān)指令,并根據(jù)初始化模板數(shù)據(jù)以及初始化相應(yīng)的訂閱器。

9.全局導(dǎo)航鉤子函數(shù)應(yīng)用場(chǎng)景?

vue router.beforeEach(全局前置守衛(wèi))router.beforeEach 是頁(yè)面加載之前(before each)意思是在 每次每一個(gè)路由改變的時(shí)候都得執(zhí)行一遍.
vue router.afterEach(全局后置守衛(wèi)),相反router.afterEach是頁(yè)面加載之后.

應(yīng)用場(chǎng)景:

  1. 可進(jìn)行一些頁(yè)面跳轉(zhuǎn)前處理,例如判斷需要登錄的頁(yè)面進(jìn)行攔截,做登錄跳轉(zhuǎn)!
    2.進(jìn)入頁(yè)面登錄判斷、管理員權(quán)限判斷、瀏覽器判斷

10 .v-if和v-for在同一個(gè)標(biāo)簽中的執(zhí)行順序?

v-for 比 v-if 優(yōu)先級(jí)高,如果每一次都需要遍歷整個(gè)數(shù)組,將會(huì)影響速度注意v-for 遍歷避免同時(shí)使用 v-if

如果需要使用判斷,建議使用計(jì)算屬性

<ul>  <li    v-for="user in activeUsers"    :key="user.id">    {{ user.name }}  </li></ul>

computed: {  activeUsers: function () {    return this.users.filter(function (user) {    return user.isActive    })  }}

10.路由獨(dú)享的守衛(wèi)(路由內(nèi)鉤子)

路由獨(dú)享的守衛(wèi)(路由內(nèi)鉤子)你可以在路由配置上直接定義 beforeEnter 守衛(wèi):

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

11.vue-loader是什么?它有什么作用?

 解析和轉(zhuǎn)換 .vue 文件,提取出其中的邏輯代碼 script、樣式代 碼 style、以及 HTML 模版 template,再分別把它們交給對(duì)應(yīng)的 Loader 去處理。

12.vue中怎么重置data?

this .$options.data可以獲取到組件初始化狀態(tài)下的datathis.$data獲取當(dāng)前狀態(tài)下的data// 將數(shù)據(jù)拷貝到this.$data中即可Object.assign(this.$data, this.$options.data())

13.在vue項(xiàng)目中如果methods的方法用箭頭函數(shù)定義結(jié)果會(huì)怎么樣?

因?yàn)榧^函數(shù)默綁定父級(jí)作用域的上下文,所以不會(huì)綁定vue實(shí)例, 在嚴(yán)格模式下this是undefined,在非嚴(yán)格模式下指向window

14.vue怎么實(shí)現(xiàn)強(qiáng)制刷新組件?

1.調(diào)用強(qiáng)制刷新方法 this.$forceUpdate()

  1. 給模板上綁定key值,通過(guò)修改key值,實(shí)現(xiàn)組件刷新<SomeComponent :key="theKey"/>//選項(xiàng)里綁定datadata(){ return{ theKey:0 }}//刷新key達(dá)到刷新組件的目的theKey++;

15.如何在子組件中訪問(wèn)父組件的實(shí)例?

通過(guò)this.parent 可以獲取父組件子組件如何調(diào)用父組件的方法? 1:直接在子組件中通過(guò)this.parent.event來(lái)調(diào)用父組件的方法
2:在子組件里用$emit向父組件觸發(fā)一個(gè)事件,父組件監(jiān)聽(tīng)這個(gè)事件

3:父組件把方法傳入子組件中,在子組件里直接調(diào)用這個(gè)方法父組件如何調(diào)用子組件的方法?給子組件設(shè)置屬性ref
<子組件 ref="name" />可以在子組件中加上ref,然后通過(guò)this.$refs.ref.method調(diào)用

16.vue組件里寫的原生addEventListeners監(jiān)聽(tīng)事件,要手動(dòng)去銷毀嗎?為什么?

需要, Vue不會(huì)主動(dòng)移除監(jiān)聽(tīng)事件, 多次進(jìn)入組件,事件會(huì)綁定多次,另一方面是函數(shù)沒(méi)釋放會(huì)內(nèi)存溢出.

17.組件中寫name選項(xiàng)有什么作用?

a.項(xiàng)目使用keep-alive時(shí),可搭配組件name進(jìn)行緩存過(guò)濾b.DOM做遞歸組件時(shí)需要調(diào)用自身name
c.vue-devtools調(diào)試工具里顯示的組見(jiàn)名稱是由vue中組件name決定的

18.<template></template>有什么用?

當(dāng)做一個(gè)不可見(jiàn)的包裹元素,減少不必要的DOM元素,整個(gè)結(jié)構(gòu)會(huì)更加清晰。使用場(chǎng)景主要用于分組的條件判斷和列表渲染。結(jié)合v-for、v-if等一起使用,插槽時(shí)使用

19 .vue組件之間的通信都有哪些?

父子組件傳值

  1. 通過(guò)props屬性傳值
  2. 通過(guò)emit/on傳值
  3. ( parents/children ) / $refs

兄弟組件傳值
1.Vuex
2.Bus
跨級(jí)組件傳值

  1. provide/inject
  2. attrs/listeners

20.route和router有什么區(qū)別?

route:代表當(dāng)前路由信息對(duì)象,可以獲取到當(dāng)前路由的信息參數(shù)router:代表路由實(shí)例的對(duì)象,包含了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等

21.怎樣動(dòng)態(tài)加載路由?

通過(guò)router.addRoutes方法可以動(dòng)態(tài)加載路由.

 let router=new VueRouter({
       routes:[           
             {path:'/product',component:a,name:'product'} 
        ]
        });  
      router.addRoutes([     
         {path:'/user',component:c,name:'user'},       
         {path:'/address',component:address,name:'address'}  
       ]);

22.說(shuō)說(shuō)active-class是哪個(gè)組件的屬性?

active-class是vue-router模塊的router-link組件中的屬性,用來(lái)設(shè)置選中連接的樣式.

23.為什么vue使用異步更新組件?

收集當(dāng)前的改動(dòng)一次性批量更新,為了節(jié)省diff開(kāi)銷.

24.怎么緩存當(dāng)前的組件?緩存后怎么更新?

1.通過(guò)keep-alive組件緩存需要緩存的組件

 <keep-alive includes="組件1name,組件2name">
      <router-view>
  </keep-alive>

2.當(dāng)組件激活后,會(huì)觸發(fā)鉤子函數(shù)actived,在這個(gè)鉤子函數(shù)中,做數(shù)據(jù)更新.

25.vue怎么獲取DOM節(jié)點(diǎn)?

為組件定義ref屬性<input ref="myInput">通過(guò)this.$refs.myInput 就可以獲取dom節(jié)點(diǎn).

26.vuex中actions和mutations有什么區(qū)別?

1.mutations可以直接修改state,但只能包含同步操作,同時(shí),只能通過(guò)提交commit調(diào)用.
2.actions可以包含異步操作,通過(guò)store.dispatch觸發(fā),不能直接修改數(shù)據(jù),需要調(diào)用commit去修改數(shù)據(jù).

27. 怎么監(jiān)聽(tīng)vuex數(shù)據(jù)的變化?

通過(guò)watch監(jiān)聽(tīng)數(shù)據(jù)的變化

watch:{ 
     '$store.state.test':function(value){    
          console.log('數(shù)據(jù)修改了',value) 
      }}

28.開(kāi)啟vuex中的嚴(yán)格模式有什么好處?

主要用戶防止不合理的改變狀態(tài)值如:this.$.store.state.list = [],這樣就會(huì)拋出異常

A.在嚴(yán)格模式下,無(wú)論何時(shí)發(fā)生了狀態(tài)變更且不是由 mutation 函數(shù)引起的,將會(huì)拋出錯(cuò)誤。這能保證所有的狀態(tài)變更都能被調(diào)試工具跟蹤到。
B. 不要在發(fā)布環(huán)境下啟用嚴(yán)格模式!嚴(yán)格模式會(huì)深度監(jiān)測(cè)狀態(tài)樹來(lái)檢測(cè)不合規(guī)的狀態(tài)變更——請(qǐng)確保在發(fā)布環(huán)境下關(guān)閉嚴(yán)格模式,以避免性能損失。

如何使用?

const store = new Vuex.Store({  
  // 讓構(gòu)建工具自動(dòng)幫我們處理
  strict: process.env.NODE_ENV !== 'production'
  })

30.你了解雙向綁定的計(jì)算屬性的應(yīng)用場(chǎng)景嗎?

<input type="text" v-model="username">

如果我們想要監(jiān)聽(tīng)用戶輸入變化,我們首先會(huì)想到下面的方法

<input type="text" v-model="username" @input="onChange">

其實(shí)我們可以使用雙向綁定的計(jì)算屬性來(lái)實(shí)現(xiàn)

 data() {    
   return {      _username:''    }; 
 },  computed:{   
  username:{     
  get(){        
      return this._username     
    },     
  set(value){         // 監(jiān)聽(tīng)數(shù)據(jù)變化      
      console.log('監(jiān)聽(tīng)數(shù)據(jù)變化',value)   
      this._username = value   }
    }
  }

當(dāng)我們使用了Vuex時(shí),并且開(kāi)啟了嚴(yán)格模式,那么我們就不能直接綁定狀態(tài)值了, 在用戶輸入時(shí),v-model 會(huì)試圖直接修改狀態(tài)name的值,這樣會(huì)拋出異常<input v-model="$store.state.name">這個(gè)時(shí)候我們需要使用雙向綁定的計(jì)算屬性來(lái)解決這個(gè)問(wèn)題

<input v-model="name">
computed: {  
  name: {    
   get () {     
       return this.$store.state.name   
   }, 
   set (value) {      
     this.$store.commit('updateName', value)  
    } 
 }}

30.vue中的指令v-on如何綁定多個(gè)屬性?

v-on={ 事件名:綁定的自定義回調(diào)函數(shù)}

  <input  type="text"  v-on="{input:onInput,focus:onFocus}"/>

31.vue中使用delete刪除對(duì)象的屬性,頁(yè)面會(huì)更新嗎?

delete this.list[1] 頁(yè)面不會(huì)更新, Vue不能檢測(cè)到 property 被刪除那么如何在刪除元素或者對(duì)象屬性時(shí),可以觸發(fā)更新視圖? this.$delete(this.list,1)

32.watch怎么深度監(jiān)聽(tīng)對(duì)象變化?

 data() {    
      return {     
         data:{},    
         user:{      
            info:{  name:123        }   
          }
       };
      }

比如我們要對(duì)user.info 屬性進(jìn)行監(jiān)聽(tīng),如果info屬性有任何更改觸發(fā)通知

watch:{     'user.info':{    
   handler(value){     
     console.log("數(shù)據(jù)變化",value)  
     }
   }
  }

此時(shí)我們調(diào)用

this.user.info.name = "8888888"handle方法不會(huì)被觸發(fā).這個(gè)user.info是一個(gè)對(duì)象
Vue只響應(yīng)對(duì)象的地址變化進(jìn)行響應(yīng).
如果我們需要讓Vue對(duì)整個(gè)info里面的屬性變化,進(jìn)行監(jiān)聽(tīng),
就需要開(kāi)啟深度監(jiān)聽(tīng)屬性deep:true

watch:{   
  'user.info':{       
   handler(value){       
   console.log("數(shù)據(jù)變化",value) 
  },     
   deep:true
  }
 }

33 .vue組件會(huì)在什么時(shí)候下被銷毀?

1.頁(yè)面關(guān)閉、
2.路由跳轉(zhuǎn)、
3.v-if為false
4.改變key值

33.怎么使css樣式只在當(dāng)前組件中生效

給style標(biāo)簽添加scoped屬性, 通過(guò)該屬性,可以使得組件之間的樣式不互相污染<style scoped> </style>

原理vue中的scoped屬性的效果主要通過(guò)PostCSS轉(zhuǎn)譯實(shí)現(xiàn), PostCSS給一個(gè)組件中的所有dom添加了一個(gè)獨(dú)一無(wú)二的動(dòng)態(tài)屬性,然后,給CSS選擇器額外添加一個(gè)對(duì)應(yīng)的屬性選擇器來(lái)選擇該組件中dom.

<div  adfs-888-123213 ></div>

vue
vuex
vue-reouter
axios
https://developer.mozilla.org/zh-CN/docs/Web/HTTP
微信小程序
支付寶小程序
can I use
實(shí)戰(zhàn)經(jīng)驗(yàn)
安全
ES6教程
javascript

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 談?wù)勀銓?duì)MVVM開(kāi)發(fā)模式的理解 MVVM分為Model、View、ViewModel三者。 Model 代表數(shù)據(jù)模...
    廖若晨閱讀 1,463評(píng)論 0 4
  • 1.Vue的生命周期 Vue的生命周期主要分為幾個(gè)簡(jiǎn)單,數(shù)據(jù)初始化,dom掛載,數(shù)據(jù)更新,組件卸載,在一個(gè)就是開(kāi)啟...
    淺時(shí)咣閱讀 1,030評(píng)論 0 10
  • 1、vue獲取服務(wù)器數(shù)據(jù)的時(shí)候,執(zhí)行函數(shù)放到哪個(gè)生命周期函數(shù)中一般 created/beforeMount/mou...
  • 1、vue與react的區(qū)別 vue和react的區(qū)別 兩者本質(zhì)的區(qū)別:模板和組件化的區(qū)別 Vue本質(zhì)是MVVM框...
    亦腕n_n閱讀 5,063評(píng)論 0 16
  • 1. 說(shuō)一下Vue的雙向綁定數(shù)據(jù)的原理 vue 實(shí)現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,...
    為光pig閱讀 2,597評(píng)論 1 46

友情鏈接更多精彩內(nèi)容