Vuex面試題彙總

什麼是Vuex?

參考答案

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,而更改狀態的惟一方法是提交mutation,例this.$store.commit('SET_VIDEO_PAUSE', video_pauseSET_VIDEO_PAUSE爲mutation屬性中定義的方法 。vue

Vuex解決了什麼問題?

參考答案

解決兩個問題vuex

  • 多個組件依賴於同一狀態時,對於多層嵌套的組件的傳參將會很是繁瑣,而且對於兄弟組件間的狀態傳遞無能爲力。
  • 來自不一樣組件的行爲須要變動同一狀態。以往採用父子組件直接引用或者經過事件來變動和同步狀態的多份拷貝。以上的這些模式很是脆弱,一般會致使沒法維護的代碼。

何時用Vuex?

參考答案

當項目遇到如下兩種場景時bash

  • 多個組件依賴於同一狀態時。
  • 來自不一樣組件的行爲須要變動同一狀態。

Vuex的5個核心屬性是什麼?

參考答案 分別是 state、getter、mutation、action、module 。

Vuex中狀態儲存在哪裏,怎麼改變它?

參考答案 存儲在state中,改變Vuex中的狀態的惟一途徑就是顯式地提交 (commit) mutation。

Vuex中狀態是對象,使用時候注意什麼?

參考答案 由於對象是引用類型,複製後改變屬性仍是會影響原始數據,這樣會改變state裏面的狀態,是不容許,因此先用深度克隆複製對象,再修改。

怎麼在組件中批量使用Vuex的state狀態?

參考答案

使用mapState輔助函數, 利用對象展開運算符將state混入computed對象中異步

import {mapState} from 'vuex'
export default{
    computed:{
        ...mapState(['price','number'])
    }
}
複製代碼

Vuex中要從state派生一些狀態出來,且多個組件使用它,該怎麼作,?

參考答案 使用getter屬性,至關Vue中的計算屬性computed,只有原狀態改變派生狀態纔會改變。

getter接收兩個參數,第一個是state,第二個是getters(能夠用來訪問其餘getter)。async

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
        }
    },
});
複製代碼

而後在組件中能夠用計算屬性computed經過this.$store.getters.total這樣來訪問這些派生轉態。ide

computed: {
    total() {
        return this.$store.getters.total
    },
    discountTotal() {
        return this.$store.getters.discountTotal
    }
}
複製代碼

怎麼經過getter來實如今組件內能夠經過特定條件來獲取state的狀態?

參考答案

經過讓getter返回一個函數,來實現給getter傳參。而後經過參數來進行判斷從而獲取state中知足要求的狀態。函數

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)
        }
    },
});
複製代碼

而後在組件中能夠用計算屬性computed經過this.$store.getters.getTodoById(2)這樣來訪問這些派生轉態。ui

computed: {
    getTodoById() {
        return this.$store.getters.getTodoById
    },
}
mounted(){
    console.log(this.getTodoById(2).done)//false
}
複製代碼

怎麼在組件中批量使用Vuex的getter屬性

參考答案

使用mapGetters輔助函數, 利用對象展開運算符將getter混入computed 對象中this

import {mapGetters} from 'vuex'
export default{
    computed:{
        ...mapGetters(['total','discountTotal'])
    }
}
複製代碼

怎麼在組件中批量給Vuex的getter屬性取別名並使用

參考答案

使用mapGetters輔助函數, 利用對象展開運算符將getter混入computed 對象中spa

import {mapGetters} from 'vuex'
export default{
    computed:{
        ...mapGetters(
            myTotal:'total',
            myDiscountTotal:'discountTotal',
        )
    }
}
複製代碼

在Vuex的state中有個狀態number表示貨物數量,在組件怎麼改變它。

參考答案

首先要在mutations中註冊一個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 必須是同步函數

在組件中屢次提交同一個mutation,怎麼寫使用更方便。

參考答案

使用mapMutations輔助函數,在組件中這麼使用

methods:{
    ...mapMutations({
        setNumber:'SET_NUMBER',
    })
}
複製代碼

而後調用this.setNumber(10)至關調用this.$store.commit('SET_NUMBER',10)

Vuex中action和mutation有什麼區別?

參考答案
  • action 提交的是 mutation,而不是直接變動狀態。mutation能夠直接變動狀態。
  • action 能夠包含任意異步操做。mutation只能是同步操做。
  • 提交方式不一樣,action 是用this.$store.dispatch('ACTION_NAME',data)來提交。mutation是用this.$store.commit('SET_NUMBER',10)來提交。
  • 接收參數不一樣,mutation第一個參數是state,而action第一個參數是context,其包含了
    {
        state,      // 等同於 `store.state`,若在模塊中則爲局部狀態
        rootState,  // 等同於 `store.state`,只存在於模塊中
        commit,     // 等同於 `store.commit`
        dispatch,   // 等同於 `store.dispatch`
        getters,    // 等同於 `store.getters`
        rootGetters // 等同於 `store.getters`,只存在於模塊中
    }
    複製代碼

Vuex中action和mutation有什麼相同點?

參考答案

第二參數均可以接收外部提交時傳來的參數。 this.$store.dispatch('ACTION_NAME',data)this.$store.commit('SET_NUMBER',10)

在組件中屢次提交同一個action,怎麼寫使用更方便。

參考答案

使用mapActions輔助函數,在組件中這麼使用

methods:{
    ...mapActions({
        setNumber:'SET_NUMBER',
    })
}
複製代碼

而後調用this.setNumber(10)至關調用this.$store.dispatch('SET_NUMBER',10)

Vuex中action一般是異步的,那麼如何知道action何時結束呢?

參考答案

在action函數中返回Promise,而後再提交時候用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中有兩個action,分別是actionA和actionB,其內都是異步操做,在actionB要提交actionA,需在actionA處理結束再處理其它操做,怎麼實現?

參考答案

利用ES6的asyncawait來實現。

actions:{
    async actionA({commit}){
        //...
    },
    async actionB({dispatch}){
        await dispatch ('actionA')//等待actionA完成
        // ... 
    }
}
複製代碼

有用過Vuex模塊嗎,爲何要使用,怎麼使用。

參考答案

有,由於使用單一狀態樹,應用的全部狀態會集中到一個比較大的對象。當應用變得很是複雜時,store 對象就有可能變得至關臃腫。因此將 store 分割成模塊(module)。每一個模塊擁有本身的 state、mutations、actions、getters,甚至是嵌套子模塊,從上至下進行一樣方式的分割。

在module文件新建moduleA.js和moduleB.js文件。在文件中寫入

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接收的第一個參數state,是全局的仍是模塊的?

參考答案 第一個參數state是模塊的state,也就是局部的state。

在模塊中,getter和mutation和action中怎麼訪問全局的state和getter?

參考答案
  • 在getter中能夠經過第三個參數rootState訪問到全局的state,能夠經過第四個參數rootGetters訪問到全局的getter。
  • 在mutation中不能夠訪問全局的satat和getter,只能訪問到局部的state。
  • 在action中第一個參數context中的context.rootState訪問到全局的state,context.rootGetters訪問到全局的getter。

在組件中怎麼訪問Vuex模塊中的getter和state,怎麼提交mutation和action?

參考答案
  • 直接經過this.$store.gettersthis.$store.state來訪問模塊中的getter和state。
  • 直接經過this.$store.commit('mutationA',data)提交模塊中的mutation。
  • 直接經過this.$store.dispatch('actionA,data')提交模塊中的action。

用過Vuex模塊的命名空間嗎?爲何使用,怎麼使用。

參考答案

默認狀況下,模塊內部的action、mutation和getter是註冊在全局命名空間,若是多個模塊中action、mutation的命名是同樣的,那麼提交mutation、action時,將會觸發全部模塊中命名相同的mutation、action。

這樣有太多的耦合,若是要使你的模塊具備更高的封裝度和複用性,你能夠經過添加namespaced: true 的方式使其成爲帶命名空間的模塊。

export default{
    namespaced: true,
    state,
    getters,
    mutations,
    actions
}
複製代碼

怎麼在帶命名空間的模塊內提交全局的mutation和action?

參考答案

將 { root: true } 做爲第三參數傳給 dispatch 或 commit 便可。

this.$store.dispatch('actionA', null, { root: true })
this.$store.commit('mutationA', null, { root: true })
複製代碼

怎麼在帶命名空間的模塊內註冊全局的action?

參考答案
actions: {
    actionA: {
        root: true,
        handler (context, data) { ... }
    }
  }
複製代碼

組件中怎麼提交modules中的moduleA中的mutationA?

參考答案
this.$store.commit('moduleA/mutationA',data)
複製代碼

怎麼使用mapState,mapGetters,mapActions和mapMutations這些函數來綁定帶命名空間的模塊?

參考答案

首先使用createNamespacedHelpers建立基於某個命名空間輔助函數

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插件有用過嗎?怎麼用簡單介紹一下?

參考答案

Vuex插件就是一個函數,它接收 store 做爲惟一參數。在Vuex.Store構造器選項plugins引入。 在store/plugin.js文件中寫入

export default function createPlugin(param){
    return store =>{
        //...
    }
}
複製代碼

而後在store/index.js文件中寫入

import createPlugin from './plugin.js'
const plugin = createPlugin()
const store = new Vuex.Store({
  // ...
  plugins: [myPlugin]
})
複製代碼

在Vuex插件中怎麼監聽組件中提交mutation和action?

參考答案
  • 用Vuex.Store的實例方法subscribe監聽組件中提交mutation
  • 用Vuex.Store的實例方法subscribeAction監聽組件中提交action 在store/plugin.js文件中寫入
export default function createPlugin(param) {
    return store => {
        store.subscribe((mutation, state) => {
            console.log(mutation.type)//是那個mutation
            console.log(mutation.payload)
            console.log(state)
        })
        // store.subscribeAction((action, state) => {
        //     console.log(action.type)//是那個action
        //     console.log(action.payload)//提交action的參數
        // })
        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文件中寫入

import createPlugin from './plugin.js'
const plugin = createPlugin()
const store = new Vuex.Store({
  // ...
  plugins: [myPlugin]
})
複製代碼

在v-model上怎麼用Vuex中state的值?

參考答案

須要經過computed計算屬性來轉換。

<input v-model="message">
// ...
computed: {
    message: {
        get () {
            return this.$store.state.message
        },
        set (value) {
            this.$store.commit('updateMessage', value)
        }
    }
}
複製代碼
相關文章
相關標籤/搜索