有什么好的方法初始化 vuex 异步后台获取的值

tomiaa
  • 70

比如有多个页面需要用到vuex中的一个值,而这个值是来自接口返回的数据,我只想在初始化时调用一次这个接口就行,但是vuex中要求再action中获取,这样的话不就每个页面都要判断一次这个值是否存在并且despatch,有什么好的方法只在初始化时就调用一次这个接口?

回复
阅读 1.9k
6 个回答

第一次请求的时候存到sessionStorage或localStorage,state的数据从sessionStorage或localStorage获取,下次就直接可以获取数据,不需要判断存不存在,且可以只调一次接口

1.如果是仅需要在页面初始化时获取,直接在入口文件App.vue里调用接口即可
2.如果是每个页面切换时需要判断数据是否存在,可以在vue-router的钩子函数中进行判断数据是否存在 然后根据情况调用接口

1: 在一个中间页获取一次,之后的页面可以不用获取,但是这种没办法处理 页面刷新的问题
2: 在根 组件上 获取数据,数据获取完之后在 渲染页面 ,可能会导致渲染变慢

从接口中获取数据 写到 vuex 中不一定要写到 action 中,只不过是一个接口调用而已

灵活使用 数据缓存单例模式

vuex 中的 action 在单页面应用情况下默认不会调用多次,主要看你在哪些地方调用了,如果是通用的方法,只需要在入口处 dispatch 即可。

拽拽
  • 2
新手上路,请多包涵

Vuex主要是用于跨组件之间传递数据的,如果是要跨页面传递数据最好还是使用本地缓存和cookie,
其实楼上已经有我想说的了,就是利用本地缓存或者cookie维护vuex里面的值。在getter的方法里面,先判断本地有没有想要的值,如果没有就请求接口。

其实如果可以不用vuex的话,你封装一下cookie或者本地缓存,也可以实现类似vuex的效果。

第一次的结果缓存在state中,action中先判断缓存,命中缓存直接回吐,至于初始一次性实例化多个组件一起触发action可以写个简单的队列来共用一个请求进行处理,给个我目前在用方案的例子。
这个方案在初始化时触发再多action真实请求只会发出一条,并共享回吐数据

import Vue from 'vue';
import {userCommonDocumentGet} from '../../../../../api/node/user/common.js';
import {requestQueue} from '../../../../../utils/index.js';

export default {

  // this.$store.state.
  state: {
    common: {
      document: {}
    }
  },

  // this.$store.dispatch('', {})
  actions: {
    // 获取公共文档,key是唯一的 reread决定是否忽略缓存重读接口
    commonDocumentGet({state}, {key, reread = false, options = {}}) {
      if (state.common.document[key] && !reread) {
        return state.common.document[key];
      }
      return requestQueue('commonDocumentGet' + key, () => userCommonDocumentGet({key}, options), res => {
        Vue.set(state.common.document, key, res.data);
        return res.data;
      })
    }
  },

requestQueue函数也参考下


const requestQueueCache = {};

/**
 * 抗并发请求缓存队列
 * @param key     唯一键名 用来识别请求的接口和参数
 * @param request 要请求的方法 如果要传参自行二次封装 () => agentSettingGet({params: 1})
 * @param done    成功监听 return的数据会返回给队列所有请求
 * @returns {Promise<>}
 */
export function requestQueue(key, request, done) {
  return new Promise((resolve, reject) => {
    if (!requestQueueCache[key]) {
      requestQueueCache[key] = [];
      request().then(res => {
        const resData = done ? done(res) : res;
        for (const req of (requestQueueCache[key] || [])) {
          req.resolve(resData)
        }
        delete requestQueueCache[key];
      }).catch(err => {
        for (const req of (requestQueueCache[key] || [])) {
          req.reject(err)
        }
        delete requestQueueCache[key];
      })
    }
    requestQueueCache[key].push({resolve, reject})
  })
}
宣传栏