vuex状态管理模式(三)(actions,modules)

Vuex

actions
  • 概述
    • 异步操作解决方案
    • 提交的是mutation,而不是直接变更状态
    • 可以包含任意异步操作
  • 使用
    • store.dispatch
    • mapAction,扩展到methods
    • 组合Action,可返回promise
示例一 this.$store.dispatch

store/index.js

import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
const store = new Vuex.Store({
    state:{
        msg:"Hi vuex"
    },
     mutations:{
        changeMsg(state,payload){
            console.log(state);
            console.log(payload);
            state.msg="xiao chen"
            // state.msg= payload
        }
    },
    actions:{
        getMsg({commit}){
            setTimeout(()=>{
                commit("changeMsg")
            },1000)
        }
    },
});
export default store;

CompA.vue

<template>
  <div id="app">
    {{msg}}
    {{mymsg}}
    <button @click="handleAsyncChangeMsg">async change</button>
  </div>
</template>
<script>
import { mapState } from "vuex";
export default {
  data(){
    return{
    }
  },
  computed: { 
    ...mapState(["msg"]),
    ...mapState({
      mymsg:"msg",
    }),
  },
  methods: {
    handleAsyncChangeMsg(){
      this.$store.dispatch("getMsg");
    },
  },
}
</script>
<style></style>
示例二 …mapActions([“getMsg”])

store/index.js

import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
const store = new Vuex.Store({
    state:{
        msg:"Hi vuex",
    },
    mutations:{
        changeMsg(state,payload){
            console.log(state);
            console.log(payload);
            state.msg="xiao chen"
            // state.msg= payload
        }
    },
    actions:{
        getMsg({commit}){
            setTimeout(()=>{
                commit("changeMsg")
            },1000)
        }
    }
});
export default store;

CompA.vue

<template>
  <div id="app">
    {{msg}}
    {{mymsg}}
    <button @click="getMsg">getMsg</button>
  </div>
</template>

<script>
import { mapState,mapActions } from "vuex";
export default {
  data(){
    return{
     
    }
  },
  computed: { 
    ...mapState(["msg"]),
    ...mapState({
      mymsg:"msg",
    }),
  },
  methods: {
   ...mapActions(["getMsg"]),
  },
}
</script>

<style></style>
modules
  • 概述
    • 动机:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。
  • 使用
    • modules 每个module都有对应的store、mutaion、action。
示例

store/index.js

import Vuex from "vuex";
import Vue from "vue";
import actions from './actions'
// 使用插件
Vue.use(Vuex);
const moduleA = {
  state: {},
  actions: {},
  mutation: {},
};
const moduleB = {
  state: {},
  actions: {},
  mutation: {},
};
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB,
  },
});
export default store;
namespaced
  • 为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,需要加上所属的模块名。
  • src\store\user\index.js
import {register, login} from '@/api';
export default {
    namespaced: true,
    state: {
        info: null
    },
    mutations: {
        initUserInfo: state => {
            try {
                let data = JSON.parse(localStorage.getItem('user'));
                state.info = data;
            } catch (e) {}
        },
        updateUserInfo: (state, data) => {
            state.info = data;

            localStorage.setItem('user', JSON.stringify(data));
        },
        removeUserInfo: (state, data) => {
            state.info = null;
            localStorage.removeItem('user');
        }
    },
    actions: {
        register: ({}, data) => {
            return register(data);
        },

        login: async ({commit}, data) => {
            try {
                let rs = await login(data);

                commit('updateUserInfo', {
                    id: rs.data.id,
                    name: rs.data.name,
                    authorization: rs.headers.authorization
                });

                return rs;
            } catch (e) {
                throw e;
            }
        },
        logout: async ({commit}) => {
            commit('removeUserInfo');
        }
    }
}
  • src\store\index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import user from './user';
import board from './board';
import list from './list';
import card from './card';
import comment from './comment';

export default new Vuex.Store({
    state: {
        server: {
            staticPath: process.env.VUE_APP_SERVER_STATIC_PATH
        }
    },
    mutations: {
    },
    actions: {
    },
    modules: {
        user,
        board,
        list,
        card,
        comment
    }
})
  • 设置namespaced:true时,需要加上模块名
async loginSubmit() {
    if (this.user.name.trim() === '' || this.user.password.trim() === '') {
        return this.$message.error('用户名和密码不能为空');
    }

    try {
        await this.$store.dispatch('user/login', {
            ...this.user
        });

        this.$router.push({name: 'Home'});
    }catch (e) {}
}

你可能感兴趣的:(vue.js,前端,vue.js,vuex)