Vue面試題


1.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變更的雙向綁定效果.

 

2.請詳細說下你對vue生命周期的理解

答案:總共分為8個階段創建前/后,載入前/后,更新前/后,銷毀前后。

創建前/后:beforeCreated階段,vue實例的掛載元素$el和數據對象data

都為undefined,還未初始化。在created階段,Vue實例的數據對象data有了,

$el還沒有。

 

載入前/后:在beforeMount階段,vue實例的$el和data都初始化了,但還是掛載之前

為虛擬DOM節點,data.message還未替換。在mounted階段,vue實例掛載完成,

data.message成功渲染。

 

銷毀前/后:在執行destory方法后,對data的改變不會再觸發周期函數,說明此時vue

實例已經解除了事件監聽以及和dom的綁定,但是dom結構依然存在.

 

3.封裝vue組件的過程.

答案:首先,組件可以提升整個項目的開發效率。能夠把頁面抽象成多個相對獨立的模塊,

解決了我們傳統項目開發:效率低、難維護、復用性性等問題。

然后,使用Vue.extend方法創建一個組件,然后使用Vue.component方法注冊組件。

子組件需要數據,可以在props中接收定義。而子組件修改好數據后,想把數據傳遞給父組件。

可以采用emit方法。

 

4.mvc和mvvm

答案:

MVC   模型-視圖-控制器(Model-View-Controller) Model和View永遠不能相互通信,

只能通過Controller傳遞。

Controller可以直接與Model對話(讀寫調用Model),Model通過Nottification和KVO機制

與Controller間接通信。

Controller可以直接與View對話,通過outlet,直接操作View,outlet直接對應到View中的控件,

View通過action向Controller報告事件的發生(如用戶Touch我了)

Controller是View的直接數據源(數據很可能是Controller從Model中取得並經過加工了)。

Controller是View的代理(delegate),以同步View與Controller。

      MVVM

Model  - ViewModel  -  View

什么是MVVM:一個MVC的增強版,我們正式連接了視圖和控制器,並將表示邏輯從Controller移

出放到一個新的對象里,即ViewModel。MVVM聽起來很復雜,但它本質上就是一個精心優化的

MVC架構。

   Model層是少不了的了,我們得有東西充當DTO(數據傳輸對象),當然,用字典也是可以的,

編程么,要靈活一些。Model層是比較薄的一層,如果學過Java的小伙伴的話,對JavaBean應該不陌生.

   ViewModel層,就是View和Model層的粘合劑,他是一個放置用戶輸入驗證邏輯,視圖顯示邏輯,發起網絡請求

和其他各種各樣的代碼的極好的地方。說白了,就是把原來ViewController層的業務邏輯和頁面邏輯

等剝離出來放到ViewModel層。

   View層,就是ViewController層,他的任務就是從ViewModel層獲取數據,然后顯示。

 

5.Vue首屏加載非常慢,如何解決?

答案:Vue首屏加載非常慢.

原因:當打包應用時,將所有JavaSript代碼打包在一個文件中,導致js代碼非常龐大,嚴重影響了頁面加載速度。

1.配置打包工具,將組件分別打包到不同的js代碼塊中

build/webpack.base.config.js

       output:{   

            path:config.bulid.assetsRoot,

            filename:'[name].js',

           //新增

        chunkFilename:"[name].js",

        publicPath:process.env.NODE_ENV=="production"

              ?config.bulid.assetsPublicPath

              :config.dev.assetsPublicPath

     }

 

2.當路由請求到該組件時,才動態加載組件的內容

路由字典中,路由配置和以前完全一樣

但是在引入組件對象時:

import Index  from  '@/views/Index.vue'

改為

const Index=()=>import('@/views/Index.vue')//僅定義函數暫未執行

//暫時不引人Index.vue

   當用戶在Vue中請求當前組件對應的路由地址時,由vue-router自動調用加載函數,

動態請求Index.vue組件對象

 

6.實現訂閱/發布者模式?

答案:

var  ublisher={ };

//定義發布者

publish.list=[];

//緩存列表  存放訂閱者回調函數

 

// 增加訂閱者

 

publisher.listen =function(fn){

 

    publisher.list.push(fn);

 

// 訂閱消息添加到緩存列表

 

}

 

// 發布消息

 

publisher.trigger =function(){    

 

for(vari = 0,fn; fn = this.list[i++];){

 

        var that =this

 

     fn.apply(null,arguments);

 

}

 

}

 

7. 什么是虛擬DOM樹:

  答案:

什么是: 僅包含可能變化的節點和可能變化的屬性的樹結構

 <body>

<div id=”app”>

     <img src=”logo.png”> alt  title id  ….

     <h1>{{uname}}</h1>id   class     title    name

     <hr>

     <h2>{{score}}</h2>

   </div>

{

  el:”#app”,

  children:[

{el:”h1”, innerText:uname},

{el:”h2”,innerText:score}

]

}

為什么: 內容少,便於快速遍歷比較不同

如何發揮作用: 

 

當data中模型變量改變時,會通知虛擬DOM樹

 

 虛擬DOM樹先緩存本次的修改在元素對象上

 

 將一批修改生成新的DOM子樹和原虛擬DOM樹做對比。

 

 一旦發現不同的元素或內容,就只更新有修改的元素

 

 虛擬DOM樹中,封裝了傳統DOM API: createElement() appendChild()  .innerHTML,避免了程序員編寫大量重復的代碼。

 

 

 

8. Vue 如何去除url中的 #

 

答案:

 

vue-router 默認使用 hash 模式,所以在路由加載的時候,項目中的 url 會自帶 #。如果不想使用 #, 可以使用 vue-router 的另一種模式 history

 

 

 

new Router({

 

  mode: 'history',

 

  routes: [ ]

 

})

 

需要注意的是,當我們啟用 history 模式的時候,由於我們的項目是一個單頁面應用,所以在路由跳轉的時候,就會出現訪問不到靜態資源而出現 404 的情況,這時候就需要服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面

 

 

9. Vue組件間如何通信

 

 答案:

 

組件通信

 

父組件向子組件通信

 

 

 

子組件通過 props 屬性,綁定父組件數據,實現雙方通信

 

 

子組件向父組件通信

 

 

 

將父組件的事件在子組件中通過 $emit 觸發

 

 

 

非父子組件、兄弟組件之間的數據傳遞

 

 

 

/*新建一個Vue實例作為中央事件總嫌*/

 

let event = new Vue();

 

 

 

/*監聽事件*/

 

event.$on('eventName', (val) => {

 

    //......do something

});

 

/*觸發事件*/

event.$emit('eventName', 'this is a message.')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM