天天看点

VueX 做状态管理( state , mutations , getters , actions 概念)

概念:

  • store 状态,表示:具体的数据,是数据的初始化
  • 在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可,触发变化也仅仅是在组件的 methods 中提交 mutation。
  • 使用: $store.state.userContext.id
  • getter , Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。
  • 就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
  • 使用: $store.getters.val.subVal
  • mutation ,更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。 Mutation 必须是同步函数,mutation 都是同步事务
  • Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type)
  • 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
  • 使用1: $store.commit(‘increment’,1)
  • 使用2: store.commit({

    type: ‘increment’,

    amount: 10

    })

  • Action , Action 类似于 mutation,不同在于:
  • . Action 提交的是 mutation,而不是直接变更状态。
  • . Action 可以包含任意异步操作。
  • Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象
  • 使用1: store.dispatch(‘increment’,1)
  • 使用2:store.dispatch({

    type: ‘incrementAsync’,

    amount: 10

    })

1 引入Vuex

VueX 做状态管理( state , mutations , getters , actions 概念)

2 定义index.js 注入

state , mutations , getters , actions

VueX 做状态管理( state , mutations , getters , actions 概念)

3 例子 : 定义NavMenu.js

VueX 做状态管理( state , mutations , getters , actions 概念)

NavMenu.js

/**
 * 系统菜单
 * @date 2019/8/12 17:55
 */
export default {
  state: {
    navMenu: []
    // {
    //   name: '系统首页',
    //   menuCode: 'index',
    //   icon: 'el-icon-s-home',
    //   auth: ["BRAND", "STORE"]
    // },
    /**
     {
        name: '物料信息',
        menuCode: 'materialIndex',
        icon: 'iconfont-icon iconsanpinw',
        isIndexMenu: true,
        auth: ["BRAND", "STORE"]
      },
     {
        name: '入库记录',
        menuCode: 'inventoryIndex',
        icon: 'iconfont-icon icondaichuk',
        isIndexMenu: true,
        auth: ["BRAND", "STORE"]
      },
     {
        name: '预警中心',
        menuCode: 'forewarningIndex',
        icon: 'iconfont-icon iconclock_fill',
        isIndexMenu: true,
        auth: ["BRAND", "STORE"]
      },
     {
        name: '出库记录',
        menuCode: 'inventoryTraceIndex',
        icon: 'iconfont-icon icondingdan1',
        isIndexMenu: true,
        auth: ["BRAND", "STORE"]
      },
     {
        name: '统计报表',
        menuCode: 'brandReportIndex',
        icon: 'iconfont-icon iconmonit ',
        isIndexMenu: true,
        auth: ["BRAND"]
      },
     {
        name: '统计报表',
        menuCode: 'storeReportIndex',
        icon: 'iconfont-icon iconmonit ',
        isIndexMenu: true,
        auth: ["STORE"]
      },
     {
        name: '物料入库',
        menuCode: 'pushInventoryForm',
        icon: 'iconfont-icon icondingdanwu',
        isIndexMenu: false,
        auth: [ "STORE"]
      },
     {
        name: '个人中心',
        menuCode: 'userInfoIndex',
        icon: 'iconfont-icon iconaddr',
        isIndexMenu: false,
        auth: ["BRAND", "STORE"]
      },
     {
        name: '设置',
        menuCode: 'configurationIndex',
        icon: 'iconfont-icon iconrepairfill',
        isIndexMenu: true,
        auth: ["BRAND", "STORE"]
      },
     {
        name: '切换账号',
        menuCode: 'logout',
        icon: 'iconfont-icon iconclock_fill',
        isIndexMenu: false,
        auth: ["BRAND", "STORE"]
      }
     ]
     */
  },

  mutations: {
    navMenu(state, navMenu) {
      state.navMenu = navMenu;
    }
  },

  actions: {
    loadNavMenu({commit, state}, vue) {
      //sessionStorage 没有token 那么不加载
      const token = sessionStorage.getItem(vue.$env.LOGIN_TOKEN);
      if (!token) {
        return;
      }
      return vue.$ajax.get('auth/current_view/nav')
        .then(res => {
          if (res.code !== 'ok') {
            throw res.msg;
          }
          commit('navMenu', res.data);
          return res.data;
        });
    }
  },
  getters: {
    /**
     * 侧边导航栏
     * @date 2019/8/13 10:14
     */
    drawerMenu({navMenu}) {
      return navMenu;
    },
    /**
     * 主页菜单
     * @date 2019/8/13 10:17
     */
    indexMenu({navMenu}) {
      //要选择的菜单
      return navMenu.filter(item => {
        // return ['物料信息','入库记录','预警中心','出库记录','统计报表'].includes(item.name);
        return ['materialIndex',
          'inventoryIndex',
          'forewarningIndex',
          'inventoryTraceIndex',
          'storeReportIndex',
          'brandReportIndex'].includes(item.menuCode);
      });
    }
  }
}

           

注: getters 里可以获取store里的NavMenu进行一些重定义,不会修改原store,这里我们可以自己添加或修改数据

VueX 做状态管理( state , mutations , getters , actions 概念)

使用方法

引入mapGetters 到组件

VueX 做状态管理( state , mutations , getters , actions 概念)

通过计算属性注入到组件

VueX 做状态管理( state , mutations , getters , actions 概念)

getters会监听store的变化, 重新执行计算属性

定义NavMenu的mutations

VueX 做状态管理( state , mutations , getters , actions 概念)

mutations只能 同步提交

使用方法

VueX 做状态管理( state , mutations , getters , actions 概念)

定义NavMenu的actions

VueX 做状态管理( state , mutations , getters , actions 概念)

actions可以一异步提交store

使用方法

VueX 做状态管理( state , mutations , getters , actions 概念)

由于两次异步提交, 需要同步返回然后跳转路由 , 这里用promise.all 做同步执行

异步提交成功store里的NavMenu修改成, 所有引用了NavMenu的计算属性全部重新执行