当前位置: 首页 > 知识库问答 >
问题:

Vuex:根据已获取的数据使用axios获取数据

祖奇
2023-03-14

我正在通过Vuex商店中的axios从外部API获取数据,它为我提供了一个包含对象的数组——比方说——cities

每个城市都有一个zipCode,我需要用它获取城市详细信息。我想将这个details对象作为一个新键添加到cities数组中。

现在我正在获取所有城市,并使用另一个Vuex操作获取城市详细信息。

所有城市的行动

fetchCities: ({ commit, state, dispatch }) => {
  let baseUrl = "https://my-url/cities";

  let config = {
    headers: {
      accept: "application/json",
      Authorization: ...
    },
    params: {
      param1: "a",
      param2: "b"
    }
  };

  axios
    .get(baseUrl, config)
    .then(function(response) {
      commit("UPDATE_CITIES_RAW", response.data.items);
    })
    .catch(function(error) {
      console.log(error);
    });
  dispatch("fetchCityDetails");
},

获取所有城市后的变异

UPDATE_CITIES_RAW: (state, payload) => {
  state.citiesRaw = payload;
},

数组中的每个对象都有一个zipCode,我正在用它获取这个城市的详细信息。

我试图在动作中循环citiesRaw数组,以获取细节并提交每次迭代的更改,但此时状态中的数组为空,因为动作在变异之前被调用。

获取城市详细信息的操作

fetchCityDetails: ({ commit, state }) => {
  let baseUrl = "https://my-url/cities/"

  let config = {
    headers: {
      accept: "application/json",
      Authorization: ...
    }
  };

  // citiesRaw is empty at this point
  state.citiesRaw.forEach(e => {
    let url = baseUrl + e.zipCode;

    axios
      .get(url, config)
      .then(function(response) {
        commit("UPDATE_CITY_DETAILS", {
          response: response.data,
          zipCode: e.zipCode
        });
      })
      .catch(function(error) {
        console.log(error);
      });
  });
},

等待第一次读取然后更新数组的最佳方法是什么?

我应该使用相同的数组还是创建一个新的数组?

或者有没有更好的方法来获取基于Vuex存储中获取的数据?

更新

在异步函数完成之前修复了调度(谢谢@Y-Gherbi),我还重构了获取细节的方法:

  1. 组件调度

新行动

fetchCities: ({ commit, state, dispatch }) => {
  let baseUrl = "https://my-url/cities";

  let config = {
    headers: {
      accept: "application/json",
      Authorization: ...
    },
    params: {
      param1: "a",
      param2: "b"
    }
  };

  let url = baseUrl;

  axios
    .get(url, config)
    .then(function(response) {
        commit("UPDATE_CITIES", response.data.items);
        state.cities.forEach(city => {
          dispatch("fetchCityDetails", city.zipCode);
        });
      }
    })
    .catch(function(error) {
      console.log(error);
    });
},
fetchCityDetails: ({ commit }, zipCode) => {
  let baseUrl = "https://my-url/cities";

  let config = {
    headers: {
      accept: "application/json",
      Authorization: ...
    },
  };

  let url = baseUrl + "/" + zipCode;

  axios
    .get(url, config)
    .then(function(response) {
      commit("UPDATE_CITY_DETAILS", {
        cityDetails: response.data,
        zipCode: zipCode
      });
    })
    .catch(function(error) {
      console.log(error);
    });
}

新突变

UPDATE_CITIES: (state, cities) => {
  // I don't need all data & I want to rename the keys from the response,
  // so I create a new object
  cities = cities.map(city => {
    let obj = {};
    obj.zipCode = city.zip_code
    obj.key1 = city.key_1;
    obj.key2 = city.key_2;

    return obj;
  });
  state.cities.push(...cities);
},
UPDATE_CITY_DETAILS: (state, payload) => {
  let cities = state.cities;
  // add one details-object for each city
  cities = cities.map(city => {
    if (city.zipCode == payload.zipCode) {
      city.cityDetails = payload.cityDetails;
    }
    return city;
  });
  state.cities = cities;
}

问题仍然存在:是否有更好/更优化的方法来实现这种获取?

共有1个答案

洪育
2023-03-14

我认为有更好、更优雅的方法来处理这个问题,但只是帮助您解决这个bug(在一个空数组上循环,这个空数组应该是一个城市数组)

修理

尝试在提交函数之后的下一行移动调度函数。数组citiesRaw)是空的,因为您在调用数据之前调用了操作(因为axios.get是异步的)

替代解决方案

正如您所说,城市显示在一个表中,表中有可扩展的行,用于显示城市详细信息。获取100-1000个城市的数据相当多,但这仍然是对后端的一次调用。但是,从性能和带宽(如果这是大数据使用的正确术语)的角度来看,对所有这些项目进行循环并对每一个项目进行请求可能会有问题。

我个人会在用户实际需要这些数据时处理每个请求。在您的情况下,每当用户单击一行以展开它时。

把它放在商店里?

无论何时,您想在商店中存储城市详细信息都取决于您。您可以将其保存在组件中,但我个人会将其用作某种缓存机制。

当用户单击某行时,检查是否已获取详细信息

if(!state.cityDetails[key]) {
    axios.get().then(res => {
    // Commit a mutation that saves the fetched details
    })
} else {
    // Use the 'cached' cityDetails
}

你的商店可以看起来像这样:

{
    cityDetails: {
        'keyCouldBeIdOrZipcode': {...},
        'anOtherAlreadyFetchedCity': {...}
    }
}

很抱歉输入错误和格式错误。在电话上输入密码很可怕

 类似资料:
  • 问题内容: 我想从Github用户和他的仓库中获取全局信息(并获得固定的仓库会很棒)。我尝试通过异步等待来实现,但这是正确的吗?我有4次reRender(4次控制台日志)。提取所有数据后是否可以等待所有组件重新渲染? 问题答案: 批处理多个状态更新,但前提是状态更新是在事件处理程序中同步发生的,而不是or 。 此行为类似于类,因为在您的情况下,由于发生了两个状态更新调用,因此它执行两个状态更新周期

  • 问题内容: 我想获取基于条件选择的数据帧行数。我尝试了以下代码。 输出: 输出显示数据帧中每一列的计数。相反,我需要获得满足以上所有条件的单一计数?这该怎么做?如果您需要有关我的数据框的更多说明,请告诉我。 问题答案: 您要的是所有条件都为真的条件,所以答案是len,除非我误解了您的要求

  • 我正在创建一个电子学习网站,那里有你可以选择的课程卡片。这是我的密码 课程ist.vue 我的问题是我无法从API链接获取数据- 我想知道我做错了什么。我也尝试使用{{list}}来获取数据,但没有成功。我现在的目标是得到所有的数据,即使它看起来很乱。抱歉我英语不好,谢谢你!

  • 我仍然是java和spring的初学者,我已经在mysql中存储了一个名为< code>Offers的表,我试图逐行获取数据< code >其中Status == 0,我的表看起来像这样: 当我尝试运行我的代码时,它的返回 org.springframework.beans.factory。BeanCreationException:创建在类路径资源[org/springframework/boo

  • 问题内容: 我正在尝试使用$ resource从静态json文件中获取数据,这是代码段: 在控制器中 但是现在,我遇到了一个错误: 你能帮我解决我的问题吗? 问题答案: 您不需要为默认方法指定动作参数(这些方法是“ get”,“ save”,“ query”,“ remove”,“ delete”)。在这种情况下,您可以按原样使用method(这仅需要更改服务定义): PS还有一个提示是,如果您需

  • 给定web服务器上图像的路径: 如果我添加了: 我如何获取数据?