2018-09-21 vue面試題

計算屬性如何使用

一般我們在寫vue的時候,在模板內寫的表達式非常便利,它運用于簡單的運算,但是他也有一些復雜的邏輯,包括運算、函數調用等,那么就用到了計算屬性,他依賴于data中數據變化的? data 中數據變化的時候? ? 計算屬性就會重新執行,視圖也會更新。

計算屬性的 set? get 如何使用

每一個計算屬性都包含一個getter 和一個setter?;

絕大多數情況下,我們只會用默認的getter 方法來讀取一個計算屬性,在業務中很少用到setter,所以在聲明一個計算屬性時,可以直接使用默認的寫法,不必將getter 和setter 都聲明。

但在你需要時,也可以提供一個setter 函數, 當手動修改計算屬性的值就像修改一個普通數據那樣時,就會觸發setter 函數,

watch 如何使用

之前做一個H5的項目。需求是當用戶在輸入完了手機號和驗證碼之后,登錄按鈕才可以點擊。?

在沒有使用vue之前,我們可能是通過input的change事件來判斷,用戶是否輸入了內容,然后修改按鈕的狀態。現在有了vue,就省事了很多,我們只需要在watch中,監聽數據模型的值改變即可。

在input 上綁定一個v-mode="pass"綁定一個數據名, 在data里寫入綁定的事件名,通過watch來監聽輸入內容的改變,但是如果,監聽的是一個對象?里面有一個deep屬性可以在選項參數中指定deep:true.也叫深度監聽??

<input v-model="passw2" placeholder="請再次輸入密碼" />

計算屬性和watch的區別

在我們運用vue的時候一定少不了用計算屬性computed和watch?

computed計算屬性是用來聲明式的描述一個值依賴了其它的值。當你在模板里把數據綁定到一個計算屬性上時,Vue 會在其依賴的任何值導致該計算屬性改變時更新 DOM。這個功能非常強大,它可以讓你的代碼更加聲明式、數據驅動并且易于維護。?

watch監聽的是你定義的變量,當你定義的變量的值發生變化時,調用對應的方法。

就好在div寫一個表達式name,data里寫入num和lastname,firstname,在watch里當num的值發生變化時,就會調用num的方法,方法里面的形參對應的是num的新值和舊值,

而計算屬性computed,計算的是Name依賴的值,它不能計算在data中已經定義過的變量。

prop 驗證,和默認值

我們在父組件給子組件傳值得時候,為了避免不必要的錯誤,可以給prop的值進行類型設定,讓父組件給子組件傳值得時候,更加準確,prop可以傳一個數字,一個布爾值,一個數組,一個對象,以及一個對象的所有屬性。

組件可以為 props 指定驗證要求。如果未指定驗證要求,Vue 會發出警告

比如傳一個number類型的數據,用defalt設置它的默認值,如果驗證失敗的話就會發出警告。

prop 如何傳一個對象的所有屬性

方法一:使用不帶參數的v-bind寫法

v-bind中沒有參數,而組件中的props需要聲明對象的每個屬性

方法二:使用帶參數的v-bind寫法

v-bind后跟隨參數todo,組件中的props需要聲明該參數,也就是v-bind后跟隨參數todo,

組件就可以通過todo來訪問對象的屬性

插槽,具名插槽,插槽默認內容

單個插槽;在父組件寫一個標簽,在子組件通過slot來接受標簽里的內容,他只能用一個slot。單個插槽可以放置在組件的任意位置,但是就像它的名字一樣,一個組件中只能有一個該類插槽。

具名插槽:在父組件標簽寫入slot,子組件里面寫name名字,他們兩個名字要相對應,才能通過名字在找到對應的位置。相對應的,具名插槽就可以有很多個,只要名字(name屬性)不同就可以了。

作用域插槽

舉個例子,比如我寫了一個可以實現條紋相間的列表組件,發布后,使用者可以自定義每一行的內容或樣式(普通的slot就可以完成這個工作)。而作用域插槽的關鍵之處就在于,父組件能接收來自子組件的slot傳遞過來的參數,子組件與父組件的數據動態交互的一種常見案例

父組件中必須要有template元素,且必須有scope特性,scope特性中是臨時變量名,

接收從子組件中傳遞上來的屬性,屬性可以是任意定義的。

動態組件

在我們平時使用vue中的模板的時候,許多時候都是直接定義成一個固定的模板,但是,vue中提供了一個動態模板,可以在任意模板中切換,就是用vue中<component>用:is來掛載不同的組件。

我們在components中注冊了三個模板,當我們點擊當前按鈕的時候,就會將模板切換模板,可以說是非常方便了。如果要把組件切換過程中的將狀態保留在內存中,可以添加一個 keep-? alive 指令參數,防止重復渲染DOM。

動態組件上使用keep-alive

<keep-alive>是Vue的內置組件,能在組件切換過程中將狀態保留在內存中,防止重復渲染DOM。

11子組件訪問父組件實例子 $parent

this.$parent

在子組件中判斷this.$parent獲取的實例是不是父組件的實例

在子組件中console.log(this.$parent) ?打印出this.$parent

在父組件中console.log(this)? 打印出this

看看打印出來的兩個實例是不是同一個

如果是同一個 ?就可以在子組件中通過this.$parent.屬性名和方法名,來調用父組件中的數據或者方法

12 父組件訪問子組件變量? this.$refs.usernameInput

給子組件添加ref屬性然后,通過vm.$refs來調用子組件的methods中的方法或者獲得data

父組件: 在子組件中加上ref即可通過this.$refs.ref.method調用

13 vue雙向數據綁定原理

view更新data其實可以通過事件監聽即可,比如input標簽監聽 'input' 事件就可以實現了。所以我們著重來分析下,當數據改變,如何更新視圖的。

數據更新視圖的重點是如何知道數據變了,只要知道數據變了,那么接下去的事都好處理。如何知道數據變了,就是通過Object.defineProperty( )對屬性設置一個set函數,當數據改變了就會來觸發這個函數,所以我們只要將一些需要更新的方法放在這里面就可以實現data更新view了。

視圖view到data? :可以通過事件監聽即可,比如input標簽監聽 'onchange' 事件就可以實現了

data到view:通過Object.defineProperty( )對屬性設置一個set函數,當數據改變了就會來觸發這個函數,所以我們只要將一些需要更新的方法放在這個set函數里面就可以實現data更新view了。

14 vue 組件通信

1) 父傳遞子

父:自定義屬性名 + 數據(要傳遞)=> :value="數據"

子:props ["父組件上的自定義屬性名“] =>進行數據接收

1) 子傳遞父

? 子:this.$emit('自定義事件名稱', 數據)? 子組件標簽上綁定@自定義事件名稱='回調函數'

? ? 父:methods: {? ? 回調函數() {? ? ? //邏輯處理? }? }

1) 兄弟組件

? 通過中央通信 let? bus? =? new? Vue()

? ? ? ? ? A:methods :{ 函數{bus.$emit(‘自定義事件名’,數據)}? 發送

? ? ? ? ? B:created (){bus.$on(‘A發送過來的自定義事件名’,函數)}? 進行數據接受

15 vue 生命周期

vue實例從被創建到銷毀的一系列過程就叫vue生命周期.也就是從開始創建、初始化數據、編譯模版、掛載DOM→渲染、更新、渲染、卸載等一系列過程。

BeforeCreate? 實例創建之前調用

Created? ? ? 實例創建成功,此時data中的數據已經初始化

beforeMount? 掛載之前的狀態

Mounted? ? ? 已經掛載的狀態

BeforeUpdate? 數據更新前的狀態

Updated? ? ? 數據更 新完成時的狀態

beforeDestory? 在vue實例銷毀之前調用,

Destoryed? ? 在vue實例銷毀之后調用,vue實例指示的所有東西都會解綁定,所有的事件監聽器會被移除,所有的子實例也會被銷毀。

16 ?vue webpack打包項目修改哪些配置

Config文件夾下面的index.js 設置里面的assetsPublicpath屬性值為./?

如果圖片太大的話,可以設置bulid文件夾下面的webpack.base.conf.js,設置圖片的limit將它的值設大點,

Utils.js添加publicpath為../../

17 ?vue路由傳參數

使用query方法傳入的參數使用this.$router.query接受

使用params方式傳入的參數使用this.$router.params接受

一、用name傳遞參數

在路由文件src/router/index.js里配置name屬性。

routes:?[

????{

??????path:?'/',

??????name:?'Hello',

??????component:?Hello

????}

]

模板里(src/App.vue)用$router.name的形勢接收,比如直接在模板中顯示:

<p>{{ $route.name}}</p>

二、通過<router-link> 標簽中的to傳參

<router-link>標簽中的to屬性進行傳參,需要注意的是這里的to要進行一個綁定,寫成:to。

<router-link?:to="{name:xxx,params:{key:value}}">valueString</router-link>

18 ? 路由導航守衛

全局鉤子函數? : beforeEach()? 每次每一個路由改變的時候都得執行一遍

組件內的鉤子函數? :

to: (Route路由對象) ?即將要進入的目標?路由對象? ???

from: (Route路由對象)??當前導航正要離開的路由

next: (Function函數) ??一定要調用該方法來?resolve?這個鉤子

beforeRouteEnter 路由之前調用

beforeRouteUpdate 復用時調用

beforeRouteLeave? 離開路由時調用

19 什么是vuex,使用vuex的好處

Vuex是一個專為 Vue.js 應用程序開發的狀態管理模式。

好處:

? ? 可以做狀態管理? 采用localstorage保存信息,數據便一直存儲在用戶的客戶端中

? ? 使用場景:適合在巨大后復雜的項目中使用,

20 state,getter,mutation,action,module,plugins? 各自的用途,和用法

State:{? count: 0? }? 保存著所有的全局變量

Getter: 對state中的數據派生出一些狀態,例如對數據進行過濾。(可以認為是store中的計算屬性),會對state中的變量進行過濾再保存,只要state中的變量發生了改變,它也會發生變化,不變化的時候,讀的緩存。

Mutation:更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。

一條重要的原則就是要記住 mutation 必須是同步函數。

Action: Action 類似于 mutation, 不同點在于,Action 提交的是 mutation,而不是直接變更狀態。Action 可以包含任意異步操作,mutation只能是同步。

有點不同的是Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters。

Module: //模塊,可以寫很多模塊,最后都引入到一個文件。分散管理。

生成實例的時候 都放在Store的modules中

plugins:插件(Plugins)是用來拓展webpack功能的,它們會在整個構建過程中生效,執行相關的任務。

21 vuex中使用persistedstate 插件進行長久儲存 (需要自己寫代碼測試)

安裝? npm?install?vuex-persistedstate?--save

store.js引入

import VuexPersistence from "vuex-persist";

創建一個對象:

const vuexLocal = new VuexPersistence({

? ? storage:window.localStorage

})

安裝進vuex插件:

export default new Vuex.Store({

? ? state:{

? ? ? ? info:{}

? ? },

? ? mutations:{

? ? ? ? setInfo(state,info){

? ? ? ? ? ? state.info=info;

? ? ? ? }

? ? },

? ? plugins:[VuexPersistence()]

})

默認存儲到localStorage

想要存儲到sessionStorage,配置如下

import createPersistedState from "vuex-persistedstate"const store = new Vuex.Store({

? plugins: [createPersistedState({

? ? ? storage: window.sessionStorage

? })]

})

22 vue開發中遇到的問題

1、setInterval路由跳轉繼續運行并沒有及時進行銷毀

 比如一些彈幕,走馬燈文字,這類需要定時調用的,路由跳轉之后,因為組件已經銷毀了,但是setInterval還沒有銷毀,還在繼續后臺調用,控制臺會不斷報錯,如果運算量大的話,無法及時清除,會導致嚴重的頁面卡頓。

 解決方案:在組件生命周期beforeDestroy停止setInterval

beforeDestory() {

? ? clearInterval(this.timer);

? ? MessageBox.close()? ? ? ? ? ? ? ?

}

2、vuejs循環插入圖片?

在寫循環的時候,寫入如下代碼:

<div class="bio-slide" v-for="item in items">?

? ? <img src="{{item.image}}"></div>

此時在控制臺會出現警告?

[Vue Warn]: src=”{{item.image}}”: interpolation in “src” attribute will cause a 404 request. Use v-bind:src instead.這里意思是在“src”屬性插值將導致404請求。使用v-bind:src代替。?

所以替換成如下:

<div class="bio-slide" v-for="item in items">?

? ? <img v-bind:src="item.image">

</div>

這里需要主要,v-bind在寫的時候不能再用{{}},

3、組件的異步加載(按需加載組件)

  在平時的demo中,你可能不會遇見這個需求,當頁面很多,組件很多的時候,你會發現你的頁面在首次加載的時候,異常的慢,這個是因為vue首次加載的時候把可能一開始看不見的組件也一次加載了,這個時候就需要對頁面優化了,就需要異步組件了。如何去寫異步組件呢,實際上很簡單,只需要在你的路由index,js里加上require就可以了,像下面這樣,這也是所謂的按需加載組件的實現原理。

4、vuex組件中訪問state報錯

  TypeError: Cannot read property ‘state’ of undefined”

  在組件中使用this.$store.state.test訪問state的屬性報錯,是因為store的實例并未注入到所有的子組件,需修改main.js

  new Vue({

  el: '#app',

  store, //將store注入到子組件

  router,

  components: { App },

  template: '<App/>'

  })

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • vue是什么? vue是構建數據驅動的web界面的漸進式框架。Vue.js 的目標是通過盡可能簡單的 API 實現...
    九四年的風閱讀 8,746評論 2 131
  • 一、什么是MVVM? MVVM是一個model+view+viewModel框架。MVVM是一種設計思想。Mode...
    花開有聲是我閱讀 3,494評論 1 79
  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數內部變量的函數。在本質上,閉包就 是將函數內部和函數外...
    xuguibin閱讀 9,748評論 1 52
  • 序 今年大前端的概念一而再再而三的被提及,那么大前端時代究竟是什么呢?大前端這個詞最早是因為在阿里內部有很多前端開...
    一縷殤流化隱半邊冰霜閱讀 11,278評論 19 92
  • ——不奢談夢想,那過于清高,只求能胡思亂想,把天花亂墜當作最后一根稻草。 有時, 我想把全世界的聲音都收集起來, ...
    像風的夢閱讀 431評論 0 0