这套题还不错,感兴趣的猿可以试一试:前端开发工程师

Vuex的基础知识

01. 基本概念

(1)是什么

  • Vuex是专门为Vue服务的状态管理插件,用于管理页面的数据状态、提供统一数据操作的生态系统
    • 相当于数据库mongoDBMySQL等,任何组件都可以存取仓库中的数据
  • Vuex采用MVC模式中的Model层,规定所有的数据必须通过action--->mutaion--->state 这个流程来改变状态

(2)为什么

  • 多个组件通过Vuex进行通信,降低耦合
  • 方便维护,增强可读性

(3)怎么办

  • 安装:npm install vuex --save

  • 新建:src/store/index.js

    import Vue from 'vue';
    import Vuex from 'vuex';
    Vue.use(Vuex);
    //创建Vuex实例对象
    const store = new Vuex.Store({
        state:{},
        getters:{},
        mutations:{},
        actions:{}
    })
    export default store;
     
  • 引入:在main.js中引入Vuex

    import Vue from 'vue';
    import App from './App.vue';
    import store from './store';
    const vm = new Vue({
        store: store,
        render: h => h(App)
    }).$mount('#app') 
     

02. 5个核心属性

(1)state

  • 概念:

    • Vuex的核心,用于保存状态
    • 存储在state中的状态只能通过mutation进行更改
    state: {
        state1: '',
        state2: ''
    }
     
  • 使用:

    // 方式一:访问 store 实例,获取该数据
    this.$store.state.state1
    
    // 方式二:使用 mapState 辅助函数,将 state 混入 compouted 对象中
    import { mapState } from 'vuex'
    computed: {
        ...mapState(['state1', 'state2']) 
    }
    this.state1 // 使用方式同data属性、computed属性
     

(2)getters

  • 概念:

    • getters 可以对State进行计算操作,它就是Store的计算属性
    • getters 可以在多组件之间复用
    getters: {
        // 接收 state 作为第一个参数
        getState1(state){
            return state.state1;
        },
        // 可以接受其他 getter 作为第二个参数
        getState2(state, getters){
            return state.state2 + getters.getState1
        }
    }
     
  • 使用

    // 方式一
    this.$store.getters.getState
    
    // 方式二:使用 mapGetters 辅助函数,将 getters 混入 compouted 对象中
    import { mapGetters } from 'vuex'
    computed:{
        ...mapGetters(['getState'])
      	// 或者,指定别名
      	...mapGetters({
        	myGetters: 'getState1' // 映射为自定义名称
     	})
    }
    this.getState
    // 或者,通过别名访问
    this.myGetters
     

(3)mutations

  • 概念:

    • 改变Vuex中的状态的唯一途径就是显式地提交 commit —— mutation

    • mutation 必须是同步函数

    • mutation 可以有两个参数

      • 第一个参数是 state,就是 store 的 state

      • 第二个参数是 payload,就是提交 mutation 的时候额外传入的参数

        如果要传递的参数包含多个字段,这个payload应该是一个对象

    mutations: {
    	CHANGE_STATE1(state, newVal) {
    		state.state1 = newVal
    	},
    	CHANGE_STATE2(state, payload){
    		state.state2 += payload.num
    	}
    }
     
  • 使用:

    // 方式一:
    this.$store.commit('CHANGE_STATE1', newVal)
    this.$store.commit('CHANGE_STATE2', { count: 10 })
    
    // 方式二:使用 mapMutations 辅助函数,将 mutation 混入 methods 方法中
    import { mapMutations } from 'vuex'
    methods: {
      ...mapMutations(['CHANGE_STATE1'])
      // 或者,指定别名
      ...mapMutations({
        myMutations: 'CHANGE_STATE2' // 映射为自定义名称 
      })
    }
    this.CHANGE_STATE1(newVal)
    // 或者
    this.myMutations({ num: 10 })
     

(4)actions

  • 概念:

    • 处理异步请求需要放在actions

    • Action 提交的是 mutation,而不是直接变更状态

      • 改变状态state只能通过mutations
    • Action 函数的参数是一个与 store 实例具有相同方法和属性的 context 对象

      • 通过这个 context 对象,可以调用当前store的属性和方法
    actions: {
        asyncChange1(context, newVal) {
            // 模拟异步
            setTimeout(() => {
                context.commit('CHANGE_STATE1', newVal);
            }, 1500)
        },
        // 也可以将对象内部的属性和方法 通过解构的方式 进行使用
        asyncChange2({ commit }, payload) {
            commit("CHANGE_STATE2", payload);
        }
    }
     
  • 使用:

    // 方式一:
    this.$store.dispatch('asyncChange1', newVal)
    
    // 方式二:使用 mapActions 辅助函数,将 actions 混入 methods 方法中
    import { mapActions } from 'vuex'
    methods: {
        ...mapActions(['asyncChange1'])
        // 指定别名
        ...mapActions({
            myActions: 'asyncChange2'
      })
    }
    this.asyncChange1(newVal)
    // 通过别名使用
    this.myActions({ count: 10 })
     

(5)modules

  • 概念

    • 使用单一状态树,应用的所有状态会集中到一个比较大的对象
    • 当应用变得非常复杂时,store 对象就有可能变得相当臃肿
    • 所以将 store 分割成模块(module)
      • 每个模块拥有自己的 state、mutations、actions、getters,甚至是嵌套子模块,从上至下进行同样方式的分割
    // 定义 moduleA
    const moduleA = {
        state: {},
        mutations: {},
        getters: {},
        actions: {}
    }
     
  • 使用

    import moduleA from './module/moduleA';
    const store = new Vuex.Store({
        modules: {
            moduleA // moduleA中的所有属性都会被注册到全局中
        },
        state: {},
        mutations: {},
        getters: {},
        actions: {}
    })