Vuex

2023-02-03  本文已影响0人  欢西西西

Vuex是专门为Vuejs应用程序设计的状态管理工具,可以全局共享数据
能够高效的实现组件之间的通信,而且state也是响应式的

一、属性

1. State

存放全局对象,它的修改由mutation触发

const state = {
  showImg: false
};

2. Getters

计算属性,利用的就是vue的computed计算属性

const getters = {
  isHideImg: state => !state.showImg
};

3. Mutations

存放同步方法,用来更新state

const mutations = {
  setImgVisible(state, v) {
    state.showImg = v;
  }
};

4. Actions

存放异步操作,提交mutation,而不是直接变更状态(commit触发mutation,dispatch触发action)

const actions = {
  async setImgCfg({commit, state, getters, dispatch}) {
      let data = await fetch(url).then(res => res.json());
      commit('setImgVisible', data.visible === 1)
  }
};

5. 辅助函数

import { mapState, mapGetters, mapMutations, mapActions } from "vuex";

export default {
    computed: {
        ...mapState(['showImg']),
        ...mapGetters(['isHideImg']),
    },
    methods: {
        ...mapMutations(['setImgVisible']),
        ...mapActions(['setImgCfg']),
        onReload() {
            this.setImgCfg();
        },
        handleClick() {
            this.setImgVisible(true);
        }
    }
}

6. Modules

用来模块化管理store,每个模块拥有自己的state、getters、mutations、actions

const system = {
  namespaced: true,
  state: {},
  getters: {},
  mutations: {},
  actions: {},
};

const login = {
  namespaced: true,
  state: {},
  getters: {},
  mutations: {},
  actions: {},
};

const store = new Vuex.Store({
  modules: {
    system,
    login
  }
})

二、操作

store.state.system // module system的state
store.state.login // module login的state

// 触发system module的mutations中的updateA方法
store.commit("system/updateA"); 

// 触发system module的actions中的updateB方法
store.dispatch("system/updateB");

使用辅助函数

mapState("system/", ["expireDate"]) 
mapActions("system/", ["onLoginSuccess"])

可以使用createNamespacedHelpers创建基于命名空间的辅助函数

import {
   createNamespacedHelpers
} from 'vuex';
const {
   mapState,
   mapGetters,
   mapMutations,
   mapActions
} = createNamespacedHelpers('system');
export {
   mapState,
   mapGetters,
   mapMutations,
   mapActions
};

三、问题

① mutation和action有什么区别?
action 提交的是 mutation,而不是直接变更状态,action可以包含异步操作。

② mutations为什么只能是同步的?可以做异步操作吗?为什么还要再设计一个action?
mutation可以写异步代码,但是不规范。定义它只写同步任务的意义在于:每个mutation执行完后都能相应地得到一个新的状态,以便devTools跟踪状态,便于调试

image.png

③ 怎么处理页面刷新后vuex数据丢失的问题?
vuex数据保存在内存中,并不是持久化存储,需要借用localStorage
方式1:可以使用vuex-persist插件
方式2:监听刷新事件,网页刷新前把state存到localStorage,在app created钩子中优先取localStorage中的数据并调用replaceState

 created() {
    const STORE_KEY = "GT-O0";

    // 在页面刷新时保存vuex里的信息
    // beforeunload事件在页面刷新时先触发
    window.addEventListener("beforeunload", () => {
      localStorage.setItem(
        STORE_KEY,
        JSON.stringify({
          data: this.$store.state,
          expire: Date.now() + 1000 * 5, // 设置过期时间
        })
      );
    });

    // 优先读storage
    let saveStateData = localStorage.getItem(STORE_KEY);
    if (!saveStateData) {
      return this.initState();
    }
    try {
      saveStateData = JSON.parse(saveStateData);
      if (Date.now() > saveStateData.expire) {
        // 如果已过期
        this.initState();
        return;
      }
      // 未过期则使用之前的store
      this.$store.replaceState(
        Object.assign({}, this.$store.state, saveStateData.data)
      );
    } catch (err) {
      this.initState();
    } finally {
      localStorage.removeItem(STORE_KEY);
    }
  }

④ vuex是单向数据流还是双向数据流?
单向,我们无法在组件中直接修改state的数据,必须通过vuex提供的mutations或actions去修改

上一篇下一篇

猜你喜欢

热点阅读