前言

简单记录一下Vuex使用

什么时候使用

当我们的多个vue实例(页面)或者组件绑定了同一个变量时,我们应该怎么处理?

  1. 如果是父子组件,我们可以使用props和emit来解决;
  2. 如果是兄弟组件(没有关联的两个页面),我们可以考虑使用全局变量,甚至是eventHub等全局监听对象;(使用vue.prototype.xxx挂载的变量并不是相应式的, 可以在全局Vue实例的data中添加变量)
  3. 当然Vue官方建议的是使用Vuex去解决;

使用规则

  1. 修改state需要通过提交mutation事件来实现;
  2. mutation的实现必须是同步操作;
  3. 对于异步操作需要通过分发action来实现;(async action => mutataion => state)

Vuex与全局变量的区别

  1. Vuex的状态存储是响应式的;
  2. 修改state时需要通过提交mutation来完成;

vuex中state的修改为什么需要使用mutation来完成?

  1. 使用mutation来修改state,可以更好的监听每个state值得变化;(可以再对应修改位置,添加打印,或进行数据的处理,更方便的监听和调试);
  2. 更好的兼容官方调试工具devtool;(通过监听mutation事件来实现);

为什么需要使用action来完成异步的mutataion操作?

  1. mutation类似于创建一个事件,函数相当于事件的回调函数;
  2. 当回调函数为异步函数时,我们无法确定多个mutation的执行顺序;
  3. 当我们处理事务相关的操作,无法确定修改顺序;
  4. 不方便使用devtools来调试state, 难以确定执行顺序, devtools是通过监听mutation事件来实现的;
  5. action可以使用promise-then、async-await来保证mutation的执行顺序;

Vuex的导出了哪些对象?

  1. Store: 用于创建Store存储实例;
  2. install: 注册到Vue暴露的方法;
  3. mapxxx: 简化vuex的引用;
  4. createNamespacedHelpers: 简化具有命名空间的模块引用;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    declare const _default: {
    Store: typeof Store;
    install: typeof install;
    mapState: typeof mapState,
    mapMutations: typeof mapMutations,
    mapGetters: typeof mapGetters,
    mapActions: typeof mapActions,
    createNamespacedHelpers: typeof createNamespacedHelpers,
    };
    export default _default;

创建Vuex.Store实例

  • 以一个简单登录验证为例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    import Vue from 'vue'
    import Vuex from 'vuex'
    import createPersistedState from 'vuex-persistedstate'
    import { login } from '../api/auth/login'
    import { setCookie } from '../libs/cookie'
    import md5 from '../libs/md5'

    Vue.use(Vuex)

    export default new Vuex.Store({
    state: {
    user: {
    uuid: '',
    username: 'xxx',
    nickname: 'developer',
    headImage: '',
    auth: []
    }
    },
    mutations: {
    setUserInfo(state, { uuid, username, nickname }) {
    state.user = Object.assign(state.user, { uuid, username, nickname })
    }
    },
    actions: {
    async login({ commit, state }, { username, password }) {
    const inputInfo = { username: username, password: md5(password) }
    const ret = await login(inputInfo)
    if (ret && ret.uuid) {
    commit('setUserInfo', ret)
    setCookie('token', ret.token)
    return true
    }
    return false
    }
    },
    plugins: [createPersistedState({ // 避免页面刷新后重新初始化state
    storage: window.localStorage
    })]
    })

在Vue实例中怎么引用?

  1. 在入口文件main.js中注册后,Store下的state、mutation、action就被挂载到Vue.$store下了,可以直接调用;
  2. 如果引入的数量较多时,可以使用Vuex导出的mapxxx方法来批量引入;
  3. 在computed中进行引用,更好的监听状态的修改;

参考链接

官方Vuex链接

总结