vuex的使用

1.模块化使用时

模块内:

//方法一:使用export default统一抛出
const user = {
  state: {
    admins_info: ''
  },
  mutations: {
    SET_ADMINS(state, admins) {
      state.admins_info = admins
    }
  },
  actions: {
    SET_ADMINS(context, admins) {
      context.commit('SET_ADMINS', admins)
    }
  }
}
export default user


//方法二:使用export单个抛出
const state = {
  admins: ''
}
const mutations = {
  SET_ADMINS: (state, admins) => {
    state.admins = admins
  }
}
const actions = {
  SET_ADMINS(context, admins) {
   context.commit('SET_ADMINS', admins)
  }
}
export default {
  //成为一个带命名空间的模块
  namespaced: true,
  state,
  mutations,
  actions
}

getter,mutation,action 他们默认都是注册在全局命名空间的,所以我们默认是可以和使用根状态一样去使用他们,但是这样不可避免会出现命名冲突的问题,所以使模块有更高的封装性与复用性,我们可以通过添加 namespaced: true 使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

页面使用:

import { auth } from '@/api/login'
import { mapState } from 'vuex'

export default {
  name: 'Login',
  data() {
    return {}
  },
  methods: {
    login(){
      auth().then(response => {
        //当使用方法一导出时
        this.$store.dispatch('SET_ADMINS', response.data})
        //当使用方法二导出时
        this.$store.dispatch('user/SET_ADMINS', response.data})
      })
    }
  },
  computed: {
    //当使用方法一导出时
    ...mapState({
      admins_info: state => state.user.admins_info
    })
    //当使用方法二导出时,也可以用上面那个方法
    ...mapState('user', {
      admins_info: state => state.admins_info
    })
  }
}

store 里

// import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
// import createPersistedState from 'vuex-persistedstate'  vuex的持久化存储
import VuexPersistence from 'vuex-persist'  //vuex的持久化存储

// Vue.use(Vuex)
const vuexLocal = new VuexPersistence({
  storage: window.localStorage
})
const store = new Vuex.Store({
  modules: {
    app,
    settings,
    user
  },
  getters,
  plugins: [vuexLocal.plugin]  //vuex的持久化存储
  // plugins: [VuexPersistence()]----vuex的持久化存储
})

export default store

2.辅助函数

//当是将vuex模块化时,有三个模块app,user,setting,此时需要在state后加上模块名,action需要加上空间名
...mapState({
       admins_info: state => state.user.admins_info.admins,
       sidebar: state => state.app.sidebar,
       device: state => state.app.device,
       fixedHeader: state => state.settings.fixedHeader
    })

...mapActions({'closeSideBar':'app/closeSideBar',SET_ADMINS:'user/SET_ADMINS'}),
this.closeSideBar({ withoutAnimation: false })//调用action



//当没有模块化时,直接state就行
  ...mapState({
    add: state => state.add,
    counts: state => state.counts
  })
  

//当没有模块化时,并且赋值前后属性名一样时(...mapState,...mapGetters,...mapActions),可以简写成如下:
  ...mapState([
    'add',
    'counts'
  ])
...mapGetters(['filteredList'])
...mapActions(['closeSideBar']),


//...mapState,处理后的state数据
...mapState({
      admins_info: state => state.user.admins_info.admins,
      NO(state) {
        return {no:state.user.admins_info.admins.no}
      }
    })
// getter
this.$store.getters['moduleB/bFullName']; 

...mapGetters({
  bGetter2: 'moduleB/bFullName'
})


// mutation 
this.$store.commit('moduleB/SET_B_NAME', {
  name: 'QQ'
});

...mapMutations({
  setBname: 'moduleB/SET_B_NAME'
}),


// action
this.$store.dispatch('moduleB/ASYNC_SET_NAME', { name: "JJ" });

...mapActions({
  aSetAge: 'moduleB/ASYNC_SET_NAME',
}),

每次都要写模块名,这样写下来很烦,所以这些辅助函数给我们提供了一个参数位来绑定命名空间。

// moduleB 模块内的 bName
...mapState('moduleB', {
  name: state => state.bName
})

// 同理 mapAction mapMutation 也可以这个样子
...mapAction('moduleB',[
  '/ASYNC_SET_NAME'
])

除了这个之外,如果你当前组件用的 vuex 状态都是一个模块的话,我们可以使用 createNamespacedHelpers 创建基于某个命名空间辅助函数,如下:

import { createNamespacedHelpers } from 'vuex'

const { mapState, mapActions } = createNamespacedHelpers('moduleB') // moduleName

这样创建之后,我们就可以用之前的写法来访问到模块的状态。

...mapState({
  bName: state => state.bName,
}),

3.在带命名空间的模块内访问全局内容

如果你希望使用全局 state 和 getter,rootState 和 rootGetter 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。

若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。具体看下面代码:

modules: {
  foo: {
    namespaced: true,

    getters: {
      // 在这个模块的 getter 中,`getters` 被局部化了
      // 你可以使用 getter 的第四个参数来调用 `rootGetters`
      someGetter (state, getters, rootState, rootGetters) {
        getters.someOtherGetter // -> 'foo/someOtherGetter 模块内的 getter'
        rootGetters.someOtherGetter // -> 'someOtherGetter 全局的getter'
      },
      someOtherGetter: state => { ... }
    },

    actions: {
      // 在这个模块中, dispatch 和 commit 也被局部化了
      // 他们可以接受 `root` 属性以访问根 dispatch 或 commit
      someAction ({ dispatch, commit, getters, rootGetters }) {
        getters.someGetter // -> 'foo/someGetter'
        rootGetters.someGetter // -> 'someGetter'

        dispatch('someOtherAction') // -> 'foo/someOtherAction' 模块内的 action
        dispatch('someOtherAction', null, { root: true }) // ->'someOtherAction' 全局的 action 

        commit('someMutation') // -> 'foo/someMutation' 模块内的 action
        commit('someMutation', null, { root: true }) // -> 'someMutation' 全局 mutation
      },
      someOtherAction (ctx, payload) { ... }
    }
  }
}

4.将模块内的 action 注册为全局

这个感觉和维护模块的封装性有点冲突,但是既然作者提出来了,那就学吧,当我们想要我们模块内的某个 action 提升为全局 action 的时候,在他声明的时候,添加 root: true,并将 action 的定义放到 hanler 函数中,具体如下:

const actions = {
    // 模块内 action
    [ASET_AGE]({ commit }, payload) {
        setTimeout(() => {
            commit('SET_B_NAME', payload.name);
        }, 2000)
    },
    // 提升到全局的 action 
    globalAction: {
        root: true,
        handler({ commit }, payload) {
            debugger
            setTimeout(() => {
                commit('SET_B_NAME', payload.name);
            }, 2000)
        }
    }
}

部分内容来自https://segmentfault.com/a/1190000019924674

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容

  • State 单一状态树 Vuex使用单一状态树——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据...
    oWSQo阅读 1,092评论 0 0
  • Vuex是什么? 按vuex官网的说法,vuex是专为vue.js开发的状态管理模式,它采用集中式存储管理应用的所...
    千里一线缘阅读 488评论 0 0
  • 配置 vuex 和 vuex 本地持久化 目录 vuex是什么 vuex 的五个核心概念State 定义状态(变量...
    稻草人_9ac7阅读 891评论 0 5
  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 730评论 0 3
  • 很多家长提到孩子学习的问题,无数的吐槽,孩子磨磨蹭蹭啦,孩子笨死啦,说个话费死劲啦,写个作业东张西望啦,林林总总,...
    我是瓜爸阅读 488评论 0 1