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)
        }
    }
}
复制代码
相关文章
相关标签/搜索