【问题标题】:How to fetch, update and render data in Vue app using axios?如何使用 axios 在 Vue 应用程序中获取、更新和渲染数据?
【发布时间】:2021-05-10 14:25:46
【问题描述】:

我正在尝试从 axios get 请求中获取数据,然后尝试从另一个 axios get 请求的响应中更新它。但是,我无法呈现来自第二个请求的数据。

示例代码摘录为:

// api.js
  // fetch items - first api call
  fetchItems() {
    const ITEMS_ENDPOINT = `${ROOT_URL}/items`;
    return axios.get(ITEMS_ENDPOINT, config);
  },

  // fetch items info - 2nd api call
  fetchItemsInfo(itemId) {
    const ITEMS_INFO_ENDPOINT = `${ROOT_URL}/items/${itemId}`;
    return axios.get(ITEMS_INFO_ENDPOINT, config);
  },

// vue component
  methods: {
    async fetchItems() {
      const res = await api.fetchItems();
      this.items = res.data;
      console.log(this.items);
      // console output [{id:1, a:1}, {id:2, a:2}, {id:3, a:3}]
    },

    updateItems() {
      this.items.forEach(async (item) => {
          const itemId = item.id;
          const res = await api.fetchItemsInfo(itemId);
          const info = res.data;
          console.log(info);
          // console output {id:1, x:2}
          if (item.id === info.id) {
            item.x = info.x;
            console.log(item);
            // console output [{id:1, a:1, x:2}]
          }
      });
    },
  },

  async created() {
    await this.fetchItems();
    this.updateItems();
    console.log(this.items);
    // console output [{id:1, a:1, x:0}, {id:2, a:2, x:1}, {id:3, a:3, x:2}]
  },

// html
<ul>
      <li v-for="(item, index) in items" :key="index">
      <!-- out put is (only the data from 1st call is displayed): 
    1 || 1 ||
    2 || 2 ||
    3 || 3 ||
    -->
        {{ item.id }} || {{ item.a }} || {{ item.x }} 
      </li>
</ul>

只显示来自第一次 api 调用的数据,而不是来自第二次调用的数据。 我可以记录来自created 钩子的数据,它会在控制台中按预期显示。 如果我使用单击(按钮单击)方法调用updateItems 函数,则数据按预期呈现。但是,我希望在页面加载时加载它。

即使我从 updateItems 更新 vuex 状态并渲染状态获取器,我也会得到相同的行为。

如何也渲染第二次调用的数据?

非常感谢

【问题讨论】:

标签: javascript api vue.js vuejs2 axios


【解决方案1】:

问题是您正在向反应项添加新属性。这行不通。我认为这应该对您有用,因为您正在重新创建整个对象而不是添加新属性

updateItems() {
  this.items = this.items.map(async item => {
    const { data: info } = await api.fetchItemsInfo(item.id);
    return {
      ...item,
      ...info
    }
  });
},

如果您知道属性名称,也可以根据需要使用Vue.set

Vue.set(item, 'property1', info.property1)
Vue.set(item, 'property2', info.property2)
etc...

我认为这将满足您的要求,但我也认为仅将详细信息添加到 fetch items 调用的响应中会比为每个项目发出额外请求要便宜得多。

【讨论】:

    【解决方案2】:

    根据 Thakur Karthik 的建议,我可以找到解决方法。 我将forEach改为for..of循环,在data中新建了一个数组,最后将this.items复制到新数组中。代码更新部分为:

    // .... 
        async updateItems() {
          for (const item of this.items) {
            const itemId = item.id;
            const res = await api.fetchItemsInfo(itemId);
            const info = res.data;
            console.log(info);
            // console output {id:1, x:2}
    
            if (item.id === info.id) {
              item.x = info.x;
              console.log(item);
              // console output [{id:1, a:1, x:2}]
            }
            // create a new array and copy items to it
            this.updatedItems = this.items;
          }
    

    我能找到的第二个解决方案是调用 Vuex 存储操作来更新项目的状态而不是复制。上面的代码将是:

        async updateItems() {
         
            //.... rest of the code
    
            // call a vuex store action (`setItems`) to update the state items
            this.setItems(this.items)
          }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-03
      • 2019-01-26
      • 2019-11-05
      • 1970-01-01
      • 2020-11-16
      • 2021-12-18
      • 2021-05-26
      • 1970-01-01
      相关资源
      最近更新 更多