使用 vuex 从 api 获取数据的最佳实践

Nan*_*gin 6 vue.js vuex

有两个页面(或相对于 vue 术语的组件)都需要相同的数据集,这些数据是通过 http 上的 api 提供的。访问这两个组件的顺序是未定义的(或依赖于用户行为),并且数据应该只获取一次,因为它不会发生很大变化。

我知道 astate存储实际数据,mutations 变异sstateactions 做异步请求、多变异协调等脏活的想法。

问题是:执行上述缓存逻辑的最佳实践是什么?

我想出了以下三种方法,但对我来说它们都不是完美的:

缺点:

  1. 我需要在到处访问数据之前调度操作,因为我不知道数据是否已经被获取。

    // ComponentA
    async mouted () {
        await this.store.dispatch('fetchData')
        this.someData = this.store.state.someData
    }
    
    // ComponentB
    async mouted () {
        await this.store.dispatch('fetchData')
        this.someData = this.store.state.someData
    }
    
    // vuex action
    {
       async fetchData ({ state, commit }) {
           // handles the cache logic here
           if (state.someData) return
           commit('setData', await apis.fetchData())
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 缓存逻辑散落在代码库中——臭~

    // ComponentA
    async mouted () {
        if (this.store.state.someData === undefined) {
            // handles the cache logic
            await this.store.dispatch('fetchData')
        }
        this.someData = this.store.state.someData
    }
    
    // ComponentB
    async mouted () {
        if (this.store.state.someData === undefined) {
            // handles the cache logic
            await this.store.dispatch('fetchData')
        }
        this.someData = this.store.state.someData
    }
    
    // vuex action
    {
       async fetchData ({ state, commit }) {
           commit('setData', await apis.fetchData())
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 可能是这三个中最完美的,但是我觉得用一个action dispatch的返回值作为数据有点奇怪。随着存储的增长,缓存逻辑将分散在所有操作中(会有越来越多的操作重复相同的缓存逻辑)

    // ComponentA
    async mouted () {
        this.someData = await this.store.dispatch('fetchData')
    }
    
    // ComponentB
    async mouted () {
        this.someData = await this.store.dispatch('fetchData')
    }
    
    // vuex action
    {
       async fetchData ({ state, commit }) {
           if (!state.someData) commit('setData', await apis.fetchData())
           return state.someData
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)

我更愿意将缓存逻辑放入我的“vue&vuex-independent”网络层。但随后网络层的“缓存”部分可能会成为另一个“vuex”存储。XD

小智 1

我最近遇到了类似的问题。并发现,无论如何,最好在你的行动中做出承诺。这有助于坚持vuex生命周期。所以你的代码可能如下所示:

{
    async fetchData ({ state, commit }) {
       if (!state.someData) commit('setData', await apis.fetchData())
       commit('setData', state.someData)
    }
 }
Run Code Online (Sandbox Code Playgroud)

然后使用在您的组件中getters使用state.someData而不是分配它。