Vuex面試題匯總(推薦)
什么是Vuex?
Vuex 是一個(gè)專(zhuān)為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),而更改狀態(tài)的唯一方法是提交mutation,例this.$store.commit('SET_VIDEO_PAUSE', video_pause,SET_VIDEO_PAUSE為mutation屬性中定義的方法。
Vuex解決了什么問(wèn)題?
解決兩個(gè)問(wèn)題
- 多個(gè)組件依賴(lài)于同一狀態(tài)時(shí),對(duì)于多層嵌套的組件的傳參將會(huì)非常繁瑣,并且對(duì)于兄弟組件間的狀態(tài)傳遞無(wú)能為力。
- 來(lái)自不同組件的行為需要變更同一狀態(tài)。以往采用父子組件直接引用或者通過(guò)事件來(lái)變更和同步狀態(tài)的多份拷貝。以上的這些模式非常脆弱,通常會(huì)導(dǎo)致無(wú)法維護(hù)的代碼。
什么時(shí)候用Vuex?
當(dāng)項(xiàng)目遇到以下兩種場(chǎng)景時(shí)
- 多個(gè)組件依賴(lài)于同一狀態(tài)時(shí)。
- 來(lái)自不同組件的行為需要變更同一狀態(tài)。
Vuex的5個(gè)核心屬性是什么?
分別是 state、getter、mutation、action、module 。
Vuex中狀態(tài)儲(chǔ)存在哪里,怎么改變它?
存儲(chǔ)在state中,改變Vuex中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。
Vuex中狀態(tài)是對(duì)象,使用時(shí)候注意什么?
因?yàn)閷?duì)象是引用類(lèi)型,復(fù)制后改變屬性還是會(huì)影響原始數(shù)據(jù),這樣會(huì)改變state里面的狀態(tài),是不允許,所以先用深度克隆復(fù)制對(duì)象,再修改。
怎么在組件中批量使用Vuex的state狀態(tài)?
使用mapState輔助函數(shù), 利用對(duì)象展開(kāi)運(yùn)算符將state混入computed對(duì)象中
import {mapState} from 'vuex'
export default{
computed:{
...mapState(['price','number'])
}
}
Vuex中要從state派生一些狀態(tài)出來(lái),且多個(gè)組件使用它,該怎么做,?
使用getter屬性,相當(dāng)Vue中的計(jì)算屬性computed,只有原狀態(tài)改變派生狀態(tài)才會(huì)改變。
getter接收兩個(gè)參數(shù),第一個(gè)是state,第二個(gè)是getters(可以用來(lái)訪(fǎng)問(wèn)其他getter)。
const store = new Vuex.Store({
state: {
price: 10,
number: 10,
discount: 0.7,
},
getters: {
total: state => {
return state.price * state.number
},
discountTotal: (state, getters) => {
return state.discount * getters.total
}
},
});
然后在組件中可以用計(jì)算屬性computed通過(guò)this.$store.getters.total這樣來(lái)訪(fǎng)問(wèn)這些派生轉(zhuǎn)態(tài)。
computed: {
total() {
return this.$store.getters.total
},
discountTotal() {
return this.$store.getters.discountTotal
}
}
怎么通過(guò)getter來(lái)實(shí)現(xiàn)在組件內(nèi)可以通過(guò)特定條件來(lái)獲取state的狀態(tài)?
通過(guò)讓getter返回一個(gè)函數(shù),來(lái)實(shí)現(xiàn)給getter傳參。然后通過(guò)參數(shù)來(lái)進(jìn)行判斷從而獲取state中滿(mǎn)足要求的狀態(tài)。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
getTodoById: (state) => (id) =>{
return state.todos.find(todo => todo.id === id)
}
},
});
然后在組件中可以用計(jì)算屬性computed通過(guò)this.$store.getters.getTodoById(2)這樣來(lái)訪(fǎng)問(wèn)這些派生轉(zhuǎn)態(tài)。
computed: {
getTodoById() {
return this.$store.getters.getTodoById
},
}
mounted(){
console.log(this.getTodoById(2).done)//false
}
怎么在組件中批量使用Vuex的getter屬性
使用mapGetters輔助函數(shù), 利用對(duì)象展開(kāi)運(yùn)算符將getter混入computed 對(duì)象中
import {mapGetters} from 'vuex'
export default{
computed:{
...mapGetters(['total','discountTotal'])
}
}
怎么在組件中批量給Vuex的getter屬性取別名并使用
使用mapGetters輔助函數(shù), 利用對(duì)象展開(kāi)運(yùn)算符將getter混入computed 對(duì)象中
import {mapGetters} from 'vuex'
export default{
computed:{
...mapGetters(
myTotal:'total',
myDiscountTotal:'discountTotal',
)
}
}
在Vuex的state中有個(gè)狀態(tài)number表示貨物數(shù)量,在組件怎么改變它。
首先要在mutations中注冊(cè)一個(gè)mutation
const store = new Vuex.Store({
state: {
number: 10,
},
mutations: {
SET_NUMBER(state,data){
state.number=data;
}
},
});
在組件中使用this.$store.commit提交mutation,改變number
this.$store.commit('SET_NUMBER',10)
在Vuex中使用mutation要注意什么。
mutation 必須是同步函數(shù)
在組件中多次提交同一個(gè)mutation,怎么寫(xiě)使用更方便。
使用mapMutations輔助函數(shù),在組件中這么使用
methods:{
...mapMutations({
setNumber:'SET_NUMBER',
})
}
然后調(diào)用this.setNumber(10)相當(dāng)調(diào)用this.$store.commit('SET_NUMBER',10)
Vuex中action和mutation有什么區(qū)別?
- action 提交的是 mutation,而不是直接變更狀態(tài)。mutation可以直接變更狀態(tài)。
- action 可以包含任意異步操作。mutation只能是同步操作。
- 提交方式不同,action 是用this.$store.dispatch('ACTION_NAME',data)來(lái)提交。mutation是用this.$store.commit('SET_NUMBER',10)來(lái)提交。
- 接收參數(shù)不同,mutation第一個(gè)參數(shù)是state,而action第一個(gè)參數(shù)是context,其包含了
{
state, // 等同于 `store.state`,若在模塊中則為局部狀態(tài)
rootState, // 等同于 `store.state`,只存在于模塊中
commit, // 等同于 `store.commit`
dispatch, // 等同于 `store.dispatch`
getters, // 等同于 `store.getters`
rootGetters // 等同于 `store.getters`,只存在于模塊中
}
Vuex中action和mutation有什么相同點(diǎn)?
第二參數(shù)都可以接收外部提交時(shí)傳來(lái)的參數(shù)。
this.$store.dispatch('ACTION_NAME',data)和this.$store.commit('SET_NUMBER',10)
在組件中多次提交同一個(gè)action,怎么寫(xiě)使用更方便。
使用mapActions輔助函數(shù),在組件中這么使用
methods:{
...mapActions({
setNumber:'SET_NUMBER',
})
}
然后調(diào)用this.setNumber(10)相當(dāng)調(diào)用this.$store.dispatch('SET_NUMBER',10)
Vuex中action通常是異步的,那么如何知道action什么時(shí)候結(jié)束呢?
在action函數(shù)中返回Promise,然后再提交時(shí)候用then處理
actions:{
SET_NUMBER_A({commit},data){
return new Promise((resolve,reject) =>{
setTimeout(() =>{
commit('SET_NUMBER',10)
},2000)
}
)
}
}
this.$store.dispatch('SET_NUMBER_A').then(() => {
// ...
})
Vuex中有兩個(gè)action,分別是actionA和actionB,其內(nèi)都是異步操作,在actionB要提交actionA,需在actionA處理結(jié)束再處理其它操作,怎么實(shí)現(xiàn)?
利用ES6的async和await來(lái)實(shí)現(xiàn)。
actions:{
async actionA({commit}){
//...
},
async actionB({dispatch}){
await dispatch ('actionA')//等待actionA完成
// ...
}
}
有用過(guò)Vuex模塊嗎,為什么要使用,怎么使用。
有,因?yàn)槭褂脝我粻顟B(tài)樹(shù),應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對(duì)象就有可能變得相當(dāng)臃腫。所以將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutations、actions、getters,甚至是嵌套子模塊,從上至下進(jìn)行同樣方式的分割。
在module文件新建moduleA.js和moduleB.js文件。在文件中寫(xiě)入
const state={
//...
}
const getters={
//...
}
const mutations={
//...
}
const actions={
//...
}
export default{
state,
getters,
mutations,
actions
}
然后再index.js引入模塊
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import moduleA from './module/moduleA'
import moduleB from './module/moduleB'
const store = new Vuex.Store({
modules:{
moduleA,
moduleB
}
})
export default store
在模塊中,getter和mutation接收的第一個(gè)參數(shù)state,是全局的還是模塊的?
第一個(gè)參數(shù)state是模塊的state,也就是局部的state。
在模塊中,getter和mutation和action中怎么訪(fǎng)問(wèn)全局的state和getter
- 在getter中可以通過(guò)第三個(gè)參數(shù)rootState訪(fǎng)問(wèn)到全局的state,可以通過(guò)第四個(gè)參數(shù)rootGetters訪(fǎng)問(wèn)到全局的getter。
- 在mutation中不可以訪(fǎng)問(wèn)全局的satat和getter,只能訪(fǎng)問(wèn)到局部的state。
- 在action中第一個(gè)參數(shù)context中的context.rootState訪(fǎng)問(wèn)到全局的state,context.rootGetters訪(fǎng)問(wèn)到全局的getter。
在組件中怎么訪(fǎng)問(wèn)Vuex模塊中的getter和state,怎么提交mutation和action?
- 直接通過(guò)this.$store.getters和this.$store.state來(lái)訪(fǎng)問(wèn)模塊中的getter和state。
- 直接通過(guò)this.$store.commit('mutationA',data)提交模塊中的mutation。
- 直接通過(guò)this.$store.dispatch('actionA,data')提交模塊中的action。
用過(guò)Vuex模塊的命名空間嗎?為什么使用,怎么使用。
默認(rèn)情況下,模塊內(nèi)部的action、mutation和getter是注冊(cè)在全局命名空間,如果多個(gè)模塊中action、mutation的命名是一樣的,那么提交mutation、action時(shí),將會(huì)觸發(fā)所有模塊中命名相同的mutation、action。
這樣有太多的耦合,如果要使你的模塊具有更高的封裝度和復(fù)用性,你可以通過(guò)添加namespaced: true 的方式使其成為帶命名空間的模塊。
export default{
namespaced: true,
state,
getters,
mutations,
actions
}
怎么在帶命名空間的模塊內(nèi)提交全局的mutation和action?
將 { root: true } 作為第三參數(shù)傳給 dispatch 或 commit 即可。
this.$store.dispatch('actionA', null, { root: true })
this.$store.commit('mutationA', null, { root: true })
怎么在帶命名空間的模塊內(nèi)注冊(cè)全局的action?
actions: {
actionA: {
root: true,
handler (context, data) { ... }
}
}
組件中怎么提交modules中的moduleA中的mutationA?
this.$store.commit('moduleA/mutationA',data)
怎么使用mapState,mapGetters,mapActions和mapMutations這些函數(shù)來(lái)綁定帶命名空間的模塊?
首先使用createNamespacedHelpers創(chuàng)建基于某個(gè)命名空間輔助函數(shù)
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions } = createNamespacedHelpers('moduleA');
export default {
computed: {
// 在 `module/moduleA` 中查找
...mapState({
a: state => state.a,
b: state => state.b
})
},
methods: {
// 在 `module/moduleA` 中查找
...mapActions([
'actionA',
'actionB'
])
}
}
Vuex插件有用過(guò)嗎?怎么用簡(jiǎn)單介紹一下?
Vuex插件就是一個(gè)函數(shù),它接收 store 作為唯一參數(shù)。在Vuex.Store構(gòu)造器選項(xiàng)plugins引入。
在store/plugin.js文件中寫(xiě)入
export default function createPlugin(param){
return store =>{
//...
}
}
然后在store/index.js文件中寫(xiě)入
import createPlugin from './plugin.js'
const plugin = createPlugin()
const store = new Vuex.Store({
// ...
plugins: [myPlugin]
})
在Vuex插件中怎么監(jiān)聽(tīng)組件中提交mutation和action?
- 用Vuex.Store的實(shí)例方法subscribe監(jiān)聽(tīng)組件中提交mutation
- 用Vuex.Store的實(shí)例方法subscribeAction監(jiān)聽(tīng)組件中提交action
在store/plugin.js文件中寫(xiě)入
export default function createPlugin(param) {
return store => {
store.subscribe((mutation, state) => {
console.log(mutation.type)//是那個(gè)mutation
console.log(mutation.payload)
console.log(state)
})
// store.subscribeAction((action, state) => {
// console.log(action.type)//是那個(gè)action
// console.log(action.payload)//提交action的參數(shù)
// })
store.subscribeAction({
before: (action, state) => {//提交action之前
console.log(`before action ${action.type}`)
},
after: (action, state) => {//提交action之后
console.log(`after action ${action.type}`)
}
})
}
}
然后在store/index.js文件中寫(xiě)入
import createPlugin from './plugin.js'
const plugin = createPlugin()
const store = new Vuex.Store({
// ...
plugins: [myPlugin]
})
在v-model上怎么用Vuex中state的值?
需要通過(guò)computed計(jì)算屬性來(lái)轉(zhuǎn)換。
<input v-model="message">
// ...
computed: {
message: {
get () {
return this.$store.state.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
這篇文章主要介紹了關(guān)于VUE的面試題(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-16- 這篇文章主要介紹了Vue.js的高級(jí)面試題(附答案),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-01-13
這篇文章主要介紹了12道vue高頻原理面試題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-12-27- 這篇文章主要介紹了web前端面試中關(guān)于VUE的面試題(含答案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)2019-11-08
這篇文章主要介紹了面試必備的13道可以舉一反三的Vue面試題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)2019-08-05- 這篇文章主要介紹了Vue面試題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-07-01
- 這篇文章主要介紹了Vue 高頻基礎(chǔ)面試題,在前端面試中經(jīng)常會(huì)遇到,今天小編特意整理分享到腳本之家平臺(tái),需要的朋友可以參考下2020-02-12




