vue面試題

1、組件間怎么傳值,具體說說代碼怎樣實(shí)現(xiàn)

  • 子傳父:子向父是通過 events($emit);通過父鏈 / 子鏈也可以通信($parent / $children);ref 也可以訪問組件實(shí)例;provide / inject API;$attrs/$listeners

  • 父?jìng)髯樱焊赶蜃觽鬟f數(shù)據(jù)是通過 props,

  • 兄弟組件傳值:bus,vuex

  • 跨級(jí)父子通信:Bus;Vuex;provide / inject API、$attrs/$listeners

以上傳值示列文檔

2、Vue雙向綁定原理

采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個(gè)屬性的setter,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。

1、實(shí)現(xiàn)一個(gè)數(shù)據(jù)監(jiān)聽器Observer,能夠?qū)?shù)據(jù)對(duì)象的所有屬性進(jìn)行監(jiān)聽,如有變動(dòng)可拿到最新值并通知訂閱者
2、實(shí)現(xiàn)一個(gè)指令解析器Compile,對(duì)每個(gè)元素節(jié)點(diǎn)的指令進(jìn)行掃描和解析,根據(jù)指令模板替換數(shù)據(jù),以及綁定相應(yīng)的更新函數(shù)
3、實(shí)現(xiàn)一個(gè)Watcher,作為連接Observer和Compile的橋梁,能夠訂閱并收到每個(gè)屬性變動(dòng)的通知,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù),從而更新視圖

3、Vue的生命周期和鉤子函數(shù)

[圖片上傳失敗...(image-87e971-1566982812354)]

beforecreate : 舉個(gè)栗子:可以在這加個(gè)loading事件
created :在這結(jié)束loading,還做一些初始化,實(shí)現(xiàn)函數(shù)自執(zhí)行
mounted : 在這發(fā)起后端請(qǐng)求,拿回?cái)?shù)據(jù),配合路由鉤子做一些事情
beforeDestroy: 你確認(rèn)刪除XX嗎? destroyed :當(dāng)前組件已被刪除,清空相關(guān)內(nèi)容

4、應(yīng)該在vue的生命周期的什么階段發(fā)出ajax請(qǐng)求,為什么

看實(shí)際情況,一般在 created 里面就可以,如果涉及到需要頁面加載完成之后的話就用 mounted

5、vuex是什么?怎么使用?哪種功能場(chǎng)景使用它?

只用來讀取的狀態(tài)集中放在store中; 改變狀態(tài)的方式是提交mutations,這是個(gè)同步的事務(wù); 異步邏輯應(yīng)該封裝在action中。
在main.js引入store,注入。新建了一個(gè)目錄store,….. export 。
場(chǎng)景有:?jiǎn)雾搼?yīng)用中,組件之間的狀態(tài)同步、音樂播放、登錄狀態(tài)、加入購物車
[圖片上傳失敗...(image-8e3ed4-1566982812354)]

state
Vuex 使用單一狀態(tài)樹,即每個(gè)應(yīng)用將僅僅包含一個(gè)store 實(shí)例,但單一狀態(tài)樹和模塊化并不沖突。存放的數(shù)據(jù)狀態(tài),不可以直接修改里面的數(shù)據(jù)。
mutations
mutations定義的方法動(dòng)態(tài)修改Vuex 的 store 中的狀態(tài)或數(shù)據(jù)。
getters
類似vue的計(jì)算屬性,主要用來過濾一些數(shù)據(jù)。
action
actions可以理解為通過將mutations里面處里數(shù)據(jù)的方法變成可異步的處理數(shù)據(jù)的方法,簡(jiǎn)單的說就是異步操作數(shù)據(jù)。view 層通過 store.dispath 來分發(fā) action。

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

modules
項(xiàng)目特別復(fù)雜的時(shí)候,可以讓每一個(gè)模塊擁有自己的state、mutation、action、getters,使得結(jié)構(gòu)非常清晰,方便管理。

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
 }
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
 }

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
})

6、Vue路由守衛(wèi)

路由跳轉(zhuǎn)前做一些驗(yàn)證,比如登錄驗(yàn)證,是網(wǎng)站中的普遍需求。對(duì)此,vue-route 提供的 beforeRouteUpdate 可以方便地實(shí)現(xiàn)導(dǎo)航守衛(wèi)。

全局守衛(wèi)

你可以使用 router.beforeEach 注冊(cè)一個(gè)全局前置守衛(wèi):

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

每個(gè)守衛(wèi)方法接收三個(gè)參數(shù):

  • to: Route: 即將要進(jìn)入的目標(biāo) 路由對(duì)象
  • from: Route: 當(dāng)前導(dǎo)航正要離開的路由
  • next: Function: 一定要調(diào)用該方法來 resolve 這個(gè)鉤子。執(zhí)行效果依賴 next 方法的調(diào)用參數(shù),確保要調(diào)用 next 方法,否則鉤子就不會(huì)被 resolved

舉一個(gè)例子:

  1. 列舉需要判斷登錄狀態(tài)的“路由集合”,當(dāng)跳轉(zhuǎn)至集合中的路由時(shí),如果“未登錄狀態(tài)”,則跳轉(zhuǎn)到登錄頁面LoginPage;
  2. 當(dāng)直接進(jìn)入登錄頁面LoginPage時(shí),如果“已登錄狀態(tài)”,則跳轉(zhuǎn)到首頁HomePage;

7、常用的vue指令,Vue的自定義指令怎么做

常用的vue指令有v-if、v-show,v-for,v-model等等

  • 創(chuàng)建局部指令
var app = new Vue({
    el: '#app',
    data: {    
    },
    // 創(chuàng)建指令(可以多個(gè))
    directives: {
        // 指令名稱
        drag: {
            inserted(el) {
                // 指令中第一個(gè)參數(shù)是當(dāng)前使用指令的DOM
                console.log(el);
                console.log(arguments);
                // 對(duì)DOM進(jìn)行操作
                el.style.width = '200px';
                el.style.height = '200px';
                el.style.background = '#000';
            }
        }
    }
})
  • 全局指令
Vue.directive('dir2', {
    inserted(el) {
        console.log(el);
    }
})
  • 指令的使用
<div id="app">
    <div v-dir1></div>
    <div v-dir2></div>
</div>

8、Vue登錄流程?需要做什么驗(yàn)證

在前后端完全分離的情況下,Vue項(xiàng)目中實(shí)現(xiàn)token驗(yàn)證大致思路如下:

  • 第一次登錄的時(shí)候,前端調(diào)后端的登陸接口,發(fā)送用戶名和密碼

  • 后端收到請(qǐng)求,驗(yàn)證用戶名和密碼,驗(yàn)證成功,就給前端返回一個(gè)token

  • 前端拿到token,將token存儲(chǔ)到localStorage和vuex中,并跳轉(zhuǎn)路由頁面

  • 前端每次跳轉(zhuǎn)路由,就判斷 localStroage 中有無 token ,沒有就跳轉(zhuǎn)到登錄頁面,有則跳轉(zhuǎn)到對(duì)應(yīng)路由頁面

  • 每次調(diào)后端接口,都要在請(qǐng)求頭中加token,我們常用axios的請(qǐng)求庫中,添加全局?jǐn)r截器,將token設(shè)置在請(qǐng)求頭中。

  • 后端判斷請(qǐng)求頭中有無token,有token,就拿到token并驗(yàn)證token,驗(yàn)證成功就返回?cái)?shù)據(jù),驗(yàn)證失?。ɡ纾簍oken過期)就返回401,請(qǐng)求頭中沒有token也返回401

  • 如果前端拿到狀態(tài)碼為401,就清除token信息并跳轉(zhuǎn)到登錄頁面

// http request 攔截器
axios.interceptors.request.use(
    config => {
        if (store.state.token) {  // 判斷是否存在token,如果存在的話,則每個(gè)http header都加上token
            config.headers.Authorization = `token ${store.state.token}`;
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    });
 
// http response 攔截器
axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    // 返回 401 清除token信息并跳轉(zhuǎn)到登錄頁面
                    store.commit(types.LOGOUT);
                    router.replace({
                        path: 'login',
                        query: {redirect: router.currentRoute.fullPath}
                    })
            }
        }
        return Promise.reject(error.response.data)   // 返回接口返回的錯(cuò)誤信息
});


9、講一下MVVM中的vm工作流程

MVVM 是 Model-View-ViewModel 的縮寫。
Model代表數(shù)據(jù)模型,也可以在Model中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯。
View 代表UI 組件,它負(fù)責(zé)將數(shù)據(jù)模型轉(zhuǎn)化成UI 展現(xiàn)出來。
ViewModel 監(jiān)聽模型數(shù)據(jù)的改變和控制視圖行為、處理用戶交互,簡(jiǎn)單理解就是一個(gè)同步View 和 Model的對(duì)象,連接Model和View。
在MVVM架構(gòu)下,View 和 Model 之間并沒有直接的聯(lián)系,而是通過ViewModel進(jìn)行交互,Model 和 ViewModel 之間的交互是雙向的, 因此View 數(shù)據(jù)的變化會(huì)同步到Model中,而Model 數(shù)據(jù)的變化也會(huì)立即反應(yīng)到View 上。
ViewModel 通過雙向數(shù)據(jù)綁定把 View 層和 Model 層連接了起來,而View 和 Model 之間的同步工作完全是自動(dòng)的,無需人為干涉,因此開發(fā)者只需關(guān)注業(yè)務(wù)邏輯,不需要手動(dòng)操作DOM, 不需要關(guān)注數(shù)據(jù)狀態(tài)的同步問題,復(fù)雜的數(shù)據(jù)狀態(tài)維護(hù)完全由 MVVM 來統(tǒng)一管理。

10、Vue和react的區(qū)別?

  • react和vue都是做組件化的,整體的功能都類似,但是他們的設(shè)計(jì)思路是有很多不同的。使用react和vue,主要是理解他們的設(shè)計(jì)思路的不同

  • react整體是函數(shù)式的思想,把組件設(shè)計(jì)成純組件,狀態(tài)和邏輯通過參數(shù)傳入,所以在react中,是單向數(shù)據(jù)流,

  • 而vue的思想是響應(yīng)式的,也就是基于是數(shù)據(jù)可變的,通過對(duì)每一個(gè)屬性建立Watcher來監(jiān)聽,當(dāng)屬性變化的時(shí)候,響應(yīng)式的更新對(duì)應(yīng)的虛擬dom

  • react的性能優(yōu)化需要手動(dòng)去做,而vue的性能優(yōu)化是自動(dòng)的,但是vue的響應(yīng)式機(jī)制也有問題,就是當(dāng)state特別多的時(shí)候,Watcher也會(huì)很多,會(huì)導(dǎo)致卡頓

  • react是類式的寫法,api很少,而vue是聲明式的寫法,通過傳入各種options,api和參數(shù)都很多

  • react可以通過高階組件(Higher Order Components--HOC)來擴(kuò)展,而vue需要通過mixins來擴(kuò)展

總結(jié):react整體的思路就是函數(shù)式,所以推崇純組件,數(shù)據(jù)不可變,單向數(shù)據(jù)流,當(dāng)然需要雙向的地方也可以做到,比如結(jié)合redux-form,而vue是基于可變數(shù)據(jù)的,支持雙向綁定。react組件的擴(kuò)展一般是通過高階組件,而vue組件會(huì)使用mixin。vue內(nèi)置了很多功能,而react做的很少,很多都是由社區(qū)來完成的,vue追求的是開發(fā)的簡(jiǎn)單,而react更在乎方式是否正確。

11、Vue里面的插槽

<slot>

是組件的一塊HTML模板,父組件決定這塊模板顯不顯示以及怎么顯示。

位置由子組件自身決定(slot現(xiàn)在組件template的什么位置,父組件傳過來的模板將來就顯示在什么位置)

匿名插槽:只能有一個(gè),可以放在組件的任何位置

<v-xx><h1></h1></v-xx>

12、Vue-cli2.0和Vue-cli3.0的區(qū)別

用vue-cli3.0版本創(chuàng)建的項(xiàng)目與2.0版本相比較,我們會(huì)發(fā)現(xiàn),文件目錄少了很多 eg:build、config,那么如何像vue-cli 2.* 之前關(guān)于端口號(hào)的配置、打包之后的路徑的配置、圖片的配置等,到哪里配置呢??vue-cli 3.0 可以在項(xiàng)目的根目錄下新建一個(gè) vue.config.js 文件,之前繁瑣的配置都可以在這里直接配置

3.0能直接運(yùn)行單個(gè)組件

3.0有一個(gè)UI管理界面

安裝了2.0版本,要先卸載

13、Vue的路由實(shí)現(xiàn) || vue-router的原理

hash模式:在瀏覽器中符號(hào)“#”,#以及#后面的字符稱之為hash,用window.location.hash讀取;
特點(diǎn):hash雖然在URL中,但不被包括在HTTP請(qǐng)求中;用來指導(dǎo)瀏覽器動(dòng)作,對(duì)服務(wù)端安全無用,hash不會(huì)重加載頁面。
hash 模式下,僅 hash 符號(hào)之前的內(nèi)容會(huì)被包含在請(qǐng)求中,如 http://www.xxx.com,因此對(duì)于后端來說,即使沒有做到對(duì)路由的全覆蓋,也不會(huì)返回 404 錯(cuò)誤。

history模式:history采用HTML5的新特性;且提供了兩個(gè)新方法:pushState(),replaceState()可以對(duì)瀏覽器歷史記錄棧進(jìn)行修改,以及popState事件的監(jiān)聽到狀態(tài)變更。
history 模式下,前端的 URL 必須和實(shí)際向后端發(fā)起請(qǐng)求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少對(duì) /items/id 的路由處理,將返回 404 錯(cuò)誤。Vue-Router 官網(wǎng)里如此描述:“不過這種模式要玩好,還需要后臺(tái)配置支持……所以呢,你要在服務(wù)端增加一個(gè)覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態(tài)資源,則應(yīng)該返回同一個(gè) index.html 頁面,這個(gè)頁面就是你 app 依賴的頁面?!?/p>

14、vue路由的鉤子函數(shù)

首頁可以控制導(dǎo)航跳轉(zhuǎn),beforeEach,afterEach等,一般用于頁面title的修改。一些需要登錄才能調(diào)整頁面的重定向功能。

beforeEach主要有3個(gè)參數(shù)to,from,next:

to:route即將進(jìn)入的目標(biāo)路由對(duì)象,

from:route當(dāng)前導(dǎo)航正要離開的路由

next:function一定要調(diào)用該方法resolve這個(gè)鉤子。執(zhí)行效果依賴next方法的調(diào)用參數(shù)。可以控制網(wǎng)頁的跳轉(zhuǎn)。

15、對(duì)keep-alive 的了解

<keep-alive>是Vue的內(nèi)置組件,能在組件切換過程中將狀態(tài)保留在內(nèi)存中,防止重復(fù)渲染DOM。

<keep-alive> 包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,而不是銷毀它們。

<keep-alive><transition>相似,只是一個(gè)抽象組件,它不會(huì)在DOM樹中渲染(真實(shí)或者虛擬都不會(huì)),也不在父組件鏈中存在,比如:你永遠(yuǎn)在 this.$parent 中找不到 keep-alive

keep-alive生命周期鉤子函數(shù):activated、deactivated

使用<keep-alive>會(huì)將數(shù)據(jù)保留在內(nèi)存中,如果要在每次進(jìn)入頁面的時(shí)候獲取最新的數(shù)據(jù),需要在activated階段獲取數(shù)據(jù),承擔(dān)原來created鉤子中獲取數(shù)據(jù)的任務(wù)。

被包含在 <keep-alive> 中創(chuàng)建的組件,會(huì)多出兩個(gè)生命周期的鉤子: activateddeactivated

activated:在組件被激活時(shí)調(diào)用,在組件第一次渲染時(shí)也會(huì)被調(diào)用,之后每次keep-alive激活時(shí)被調(diào)用。

deactivated:在組件被停用時(shí)調(diào)用。

注意:只有組件被 keep-alive 包裹時(shí),這兩個(gè)生命周期才會(huì)被調(diào)用,如果作為正常組件使用,是不會(huì)被調(diào)用,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,這兩個(gè)鉤子依然不會(huì)被調(diào)用!另外在服務(wù)端渲染時(shí)此鉤子也不會(huì)被調(diào)用的。

什么時(shí)候獲取數(shù)據(jù)?

當(dāng)引入keep-alive 的時(shí)候,頁面第一次進(jìn)入,鉤子的觸發(fā)順序created-> mounted-> activated,退出時(shí)觸發(fā)deactivated。當(dāng)再次進(jìn)入(前進(jìn)或者后退)時(shí),只觸發(fā)activated。

16、DOM 和虛擬DOM的區(qū)別 以及你對(duì)于他們了解

DOM的本質(zhì):DOM是瀏覽器概念,瀏覽器從服務(wù)器端讀取html頁面,瀏覽器將html解析成一棵元素嵌套關(guān)系的dom樹,用對(duì)象來表示頁面上的元素,并提供操作dom對(duì)象的api。

虛擬DOM:框架概念,程序員用js對(duì)象來模擬頁面上dom元素的嵌套關(guān)系( 本質(zhì) ),為了實(shí)現(xiàn)頁面元素的高效更新( 目的 )

虛擬DOM是真實(shí)DOM結(jié)構(gòu)的映射,即一個(gè)數(shù)據(jù)集合

// 對(duì)于這個(gè)Html 文件
<div class="">
    <p>
        <span>
            Hello, the world!
        </span>
        <span>
            Hello, the code!
        </span>
    </p>

</div>

// 它對(duì)應(yīng)的虛擬DOM就是
let nodesData = {
    tag: 'div',
    attr: []
    children: [
      {
        tag: 'p',
        children: [
          {
            tag: 'span',
            children: [
              {
                tag: '#text',
                text: 'Hello, the world!'
              }
            ]
          }
        ]
      },
      {
        tag: 'span',
          children: [
            {
              tag: '#text',
              text: 'Hello, the code!'
            }
          ]
      }
    ]
  }
 //  或這種寫法
 let vNodes = v('div', [
      v('p', [
        v('span', [ v('#text', 'Hello, the world!') ] )
        ]
      ),
      v('span', [
        v('#text',  'Hello, the code!')
        ])
    ]
  )
 虛擬DOM的核心就是一個(gè)diff算法:使用一個(gè)render()方法就可以將上面vNodes還原成真實(shí)的Html頁面

17、vue指令的生命周期

自定義指令有五個(gè)生命周期(也叫鉤子函數(shù)),分別是 bind,inserted,update,componentUpdated,unbind

  • bind:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用,用這個(gè)鉤子函數(shù)可以定義一個(gè)綁定時(shí)執(zhí)行一次的初始化動(dòng)作。
  • inserted:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(父節(jié)點(diǎn)存在即可調(diào)用,不必存在于document中)。
  • update:被綁定于元素所在的模板更新時(shí)調(diào)用,而無論綁定值是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新。
  • componentUpdated:被綁定元素所在模板完成一次更新周期時(shí)調(diào)用。
  • unbind:只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。

18、vue封裝公共組件(通用組件)需要考慮到什么

開發(fā)通用組件是很基礎(chǔ)且重要的工作,通用組件必須具備高性能、低耦合的特性

一、數(shù)據(jù)從父組件傳入

為了解耦,子組件本身就不能生成數(shù)據(jù)。即使生成了,也只能在組件內(nèi)部運(yùn)作,不能傳遞出去。

父對(duì)子傳參,就需要用到 props,但是通用組件的的應(yīng)用場(chǎng)景比較復(fù)雜,對(duì) props 傳遞的參數(shù)應(yīng)該添加一些驗(yàn)證規(guī)則

二、在父組件處理事件

在通用組件中,通常會(huì)需要有各種事件,

比如復(fù)選框的 change 事件,或者組件中某個(gè)按鈕的 click 事件

這些事件的處理方法應(yīng)當(dāng)盡量放到父組件中,通用組件本身只作為一個(gè)中轉(zhuǎn)

三、記得留一個(gè) slot

一個(gè)通用組件,往往不能夠完美的適應(yīng)所有應(yīng)用場(chǎng)景

所以在封裝組件的時(shí)候,只需要完成組件 80% 的功能,剩下的 20% 讓父組件通過 solt 解決

四、不要依賴 Vuex

父子組件之間是通過 props 和 自定義事件 來傳參,非父子組件通常會(huì)采用 Vuex 傳參

但是 Vuex 的設(shè)計(jì)初衷是用來管理組件狀態(tài),雖然可以用來傳參,但并不推薦

因?yàn)?Vuex 類似于一個(gè)全局變量,會(huì)一直占用內(nèi)存

在寫入數(shù)據(jù)龐大的 state 的時(shí)候,就會(huì)產(chǎn)生內(nèi)存泄露

五、合理運(yùn)用 scoped 編寫 CSS

在編寫組件的時(shí)候,可以在 <style> 標(biāo)簽中添加 scoped,讓標(biāo)簽中的樣式只對(duì)當(dāng)前組件生效

但是一味的使用 scoped,肯定會(huì)產(chǎn)生大量的重復(fù)代碼

所以在開發(fā)的時(shí)候,應(yīng)該避免在組件中寫樣式

當(dāng)全局樣式寫好之后,再針對(duì)每個(gè)組件,通過 scoped 屬性添加組件樣式

19、父組件怎么調(diào)用子組件里的方法

  • 在父組件中:首先要引入子組件 import Child from './child';

  • <child ref="mychild"></child>是在父組件中為子組件添加一個(gè)占位,ref="mychild"是子組件在父組件中的名字

  • 父組件中 components: {  是聲明子組件在父組件中的名字}

  • 在父組件的方法中調(diào)用子組件的方法,很重要 this.$refs.mychild.parentHandleclick("嘿嘿嘿"); parentHandleclick是子組件中的方法

20、css只在當(dāng)前組件起作用

答:在style標(biāo)簽中寫入scoped即可 例如:<style scoped></style>

21、v-if 和 v-show 區(qū)別

答:v-if按照條件是否渲染,v-show是display的block或none;

22、route和router的區(qū)別

答:route是“路由信息對(duì)象”,包括path,params,hash,query,fullPath,matched,name等路由信息參數(shù)。而router是“路由實(shí)例”對(duì)象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等。

23、vue.js的兩個(gè)核心是什么?

答:數(shù)據(jù)驅(qū)動(dòng)、組件系統(tǒng)

24、vue常用的修飾符?

答:.prevent: 提交事件不再重載頁面;.stop: 阻止單擊事件冒泡;.self: 當(dāng)事件發(fā)生在該元素本身而不是子元素的時(shí)候會(huì)觸發(fā);.capture: 事件偵聽,事件發(fā)生的時(shí)候會(huì)調(diào)用

25、v-on 可以綁定多個(gè)方法嗎?

答:可以

26、vue中 key 值的作用?

答:當(dāng) Vue.js 用 v-for 正在更新已渲染過的元素列表時(shí),它默認(rèn)用“就地復(fù)用”策略。如果數(shù)據(jù)項(xiàng)的順序被改變,Vue 將不會(huì)移動(dòng) DOM 元素來匹配數(shù)據(jù)項(xiàng)的順序, 而是簡(jiǎn)單復(fù)用此處每個(gè)元素,并且確保它在特定索引下顯示已被渲染過的每個(gè)元素。key的作用主要是為了高效的更新虛擬DOM。

27、什么是vue的計(jì)算屬性?

答:在模板中放入太多的邏輯會(huì)讓模板過重且難以維護(hù),在需要對(duì)數(shù)據(jù)進(jìn)行復(fù)雜處理,且可能多次使用的情況下,盡量采取計(jì)算屬性的方式。好處:①使得數(shù)據(jù)處理結(jié)構(gòu)清晰;②依賴于數(shù)據(jù),數(shù)據(jù)更新,處理結(jié)果自動(dòng)更新;③計(jì)算屬性內(nèi)部this指向vm實(shí)例;④在template調(diào)用時(shí),直接寫計(jì)算屬性名即可;⑤常用的是getter方法,獲取數(shù)據(jù),也可以使用set方法改變數(shù)據(jù);⑥相較于methods,不管依賴的數(shù)據(jù)變不變,methods都會(huì)重新計(jì)算,但是依賴數(shù)據(jù)不變的時(shí)候computed從緩存中獲取,不會(huì)重新計(jì)算。

計(jì)算屬性就是當(dāng)其依賴屬性的值發(fā)生變化時(shí),這個(gè)屬性的值會(huì)自動(dòng)更新。
<body>
    <div id="app">
         <input type="text" v-model="msg">
         <p>原始字符:{{msg}}</p>
         <p>計(jì)算屬性翻轉(zhuǎn)字符:{{reverseMsg}}</p>
    </div>
    <script>
         new Vue({
             el:'#app',
             data:{
                 msg:'Hello'
             },
             //vue的計(jì)算屬性
             computed:{
                 reverseMsg(){
                     //返回翻轉(zhuǎn)后的字符串,當(dāng)msg變化后reverseMsg會(huì)跟著變化
                     return this.msg.split('').reverse().join('')
                 }
             }
         })
    </script>
</body>

28、vue等單頁面應(yīng)用及其優(yōu)缺點(diǎn)

答:優(yōu)點(diǎn):Vue 的目標(biāo)是通過盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件,核心是一個(gè)響應(yīng)的數(shù)據(jù)綁定系統(tǒng)。MVVM、數(shù)據(jù)驅(qū)動(dòng)、組件化、輕量、簡(jiǎn)潔、高效、快速、模塊友好。
缺點(diǎn):不支持低版本的瀏覽器,最低只支持到IE9;不利于SEO的優(yōu)化(如果要支持SEO,建議通過服務(wù)端來進(jìn)行渲染組件);第一次加載首頁耗時(shí)相對(duì)長一些;不可以使用瀏覽器的導(dǎo)航按鈕需要自行實(shí)現(xiàn)前進(jìn)、后退。

29、路由之間跳轉(zhuǎn)

聲明式(標(biāo)簽跳轉(zhuǎn)) 編程式( js跳轉(zhuǎn))

通過router-link實(shí)現(xiàn)跳轉(zhuǎn)

img

通過js的編程的方式

img

30、Vue中怎么實(shí)現(xiàn)跨域

使用http-proxy-middleware 代理解決(項(xiàng)目使用vue-cli腳手架搭建)

例如請(qǐng)求的url:“http://aa.com/demo.json“

1、打開config/index.js,在proxyTable中添寫如下代碼:

proxyTable: { 
  '/api': {  //使用"/api"來代替"http://aa.com" 
    target: 'http://aa.com', //源地址 
    changeOrigin: true, //改變?cè)?
    secure:false // 是否使用https
    pathRewrite: { 
      '^/api': '/api' //路徑重寫 
      } 
  } 
}

2、使用axios請(qǐng)求數(shù)據(jù)時(shí)直接使用“/api”

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

以上配置只是在開發(fā)環(huán)境(dev)中解決跨域。要解決生產(chǎn)環(huán)境的跨域問題,則在config/dev.env.jsconfig/prod.env.js里也就是開發(fā)/生產(chǎn)環(huán)境下分別配置一下請(qǐng)求的地址API_HOST,開發(fā)環(huán)境中我們用上面配置的代理地址api,生產(chǎn)環(huán)境下用正常的接口地址

module.exports = merge(prodEnv, {
    NODE_ENV: '"development"',
    API_HOST:"/api/"
})
'use strict'
module.exports = {
    NODE_ENV: '"production"',
    API_HOST:"http://aa.com"
}

31、Vue首屏加載過慢的解決方法有哪些

vue首屏加載過慢的原因

  • 網(wǎng)速慢肯定會(huì)導(dǎo)致首屏加載過慢,但是在這里我們不做討論
  • vue項(xiàng)目作為一個(gè)單頁面應(yīng)用,如果不對(duì)路由進(jìn)行處理,在加載首頁的時(shí)候,就會(huì)將所有組件全部加載,并向服務(wù)器請(qǐng)求數(shù)據(jù),這必將拖慢加載速度;
  • 通過查看Network,發(fā)現(xiàn)整個(gè)網(wǎng)站加載試講長達(dá)10幾秒,加載時(shí)間最長的就是js、css文件和媒體文件及圖片

解決方案

  • vue-router 路由懶加載

  • 在項(xiàng)目開發(fā)中,我們會(huì)用到很多第三方庫,如果可以按需引入,我們可以只引入自己需要的組件,來減少所占空間,但也會(huì)有一些不能按需引入,我們可以采用CDN外部加載,在index.html中從CDN引入組件,去掉其他頁面的組件import,

  • 關(guān)閉sourcemap,sourcemap是為了方便線上調(diào)試用的,因?yàn)榫€上代碼都是壓縮過的,導(dǎo)致調(diào)試極為不便,而有了sourcemap,就等于加了個(gè)索引字典,出了問題可以定位到源代碼的位置。
    但是,這個(gè)玩意是每個(gè)js都帶一個(gè)sourcemap,有時(shí)sourcemap會(huì)很大,拖累了整個(gè)項(xiàng)目加載速度,為了節(jié)省加載時(shí)間,我們將其關(guān)閉掉

  • 開啟gzip壓縮,這個(gè)優(yōu)化是兩方面的,前端將文件打包成.gz文件,然后通過nginx的配置,讓瀏覽器直接解析.gz文件。

  • 加個(gè)loading效果:首頁加個(gè)好看的loading阻塞一下,讓用戶別等的那么心焦。

  • 如果首頁真的有瓶頸,可以考慮用node單獨(dú)做服務(wù)端渲染,而下面的子頁面仍用spa單頁的方式交互。

32、vue如何實(shí)現(xiàn)按需加載組件

https://www.cnblogs.com/-roc/p/9983177.html

33、 請(qǐng)說下封裝 vue 插件封裝過程

https://www.jb51.net/article/157120.htm

34、vue項(xiàng)目的多語言處理

Vue已經(jīng)有了這個(gè)多語種的插件,vue-i18n

35、vue中的watch介紹和場(chǎng)景

監(jiān)聽并處理data屬性的更新,對(duì)data屬性的監(jiān)聽,說明屬性是在data中聲明過的
屬性更新時(shí)調(diào)用監(jiān)聽函數(shù),可選參數(shù)分別為新值和舊值,對(duì)屬性重新設(shè)置值,只要跟原來的值相等就不會(huì)觸發(fā)函數(shù)調(diào)用,這一點(diǎn)跟計(jì)算屬性是相似的,

// 基礎(chǔ)用法
watch: {
        activeTab(newValue, oldValue) {
            console.log(newValue, oldValue);
            this.getList();
        }
}
// 函數(shù)體調(diào)用Vue實(shí)例的方法可簡(jiǎn)寫
watch: {
        activeTab: 'getList'
}

屬性初始化的值默認(rèn)不會(huì)觸發(fā)監(jiān)聽,解決辦法添加說明immediate:true,表示監(jiān)聽初始值,此時(shí)使用handler寫法

watch: {
        activeTab: {
            handler(newValue, oldValue) {
                console.log(newValue, oldValue);
                this.getList();
            },
            // 立即執(zhí)行handler函數(shù)
            immediate: true
        }
    }

當(dāng)被監(jiān)聽的屬性為對(duì)象時(shí),默認(rèn)不會(huì)監(jiān)聽對(duì)象內(nèi)部屬性的變化,而是只監(jiān)聽屬性被賦值時(shí)的變化,解決辦法添加說明deep:true(默認(rèn)為false),此時(shí)監(jiān)聽器會(huì)深度遍歷給對(duì)象的每一個(gè)屬性都帶上監(jiān)聽器,更新寫法

// 監(jiān)聽對(duì)象的所有屬性
watch: {
        activeTab: {
            handler(newValue, oldValue) {
                console.log(newValue, oldValue);
                this.getList();
            },
            // 深度監(jiān)聽
            deep: true
        }
    }
// 監(jiān)聽對(duì)象的某些屬性
watch: {
        'activeTab.index': {
            handler(newValue, oldValue) {
                console.log(newValue, oldValue);
                this.getList();
            }
        }
    }

另外組件中的監(jiān)聽器會(huì)隨組建的注銷而注銷,不會(huì)造成內(nèi)存溢出,但如果使用命令式的( vm.$watch)全局的監(jiān)聽器需要手動(dòng)注銷才行

?著作權(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)容

  • 1. Vue.js介紹 Vue.js是一個(gè)輕巧、高性能、可組件化的MVVM庫,同時(shí)擁有非常容易上手的API; V...
    tyu229閱讀 32,730評(píng)論 1 26
  • 1、active-class是哪個(gè)組件的屬性?嵌套路由怎么定義? 答:vue-router模塊的router-li...
    黃海佳閱讀 1,959評(píng)論 1 38
  • vue是什么? vue是構(gòu)建數(shù)據(jù)驅(qū)動(dòng)的web界面的漸進(jìn)式框架。Vue.js 的目標(biāo)是通過盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)...
    九四年的風(fēng)閱讀 8,813評(píng)論 2 131
  • 計(jì)算屬性如何使用 一般我們?cè)趯憊ue的時(shí)候,在模板內(nèi)寫的表達(dá)式非常便利,它運(yùn)用于簡(jiǎn)單的運(yùn)算,但是他也有一些復(fù)雜的邏...
    X秀秀閱讀 13,817評(píng)論 1 19
  • 原文:http://www.itdecent.cn/p/0cdf51904afb 計(jì)算屬性如何使用 一般我們?cè)趯?..
    L_b115閱讀 973評(píng)論 0 0

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