首页 > 解决方案 > Vue3 - 获取 API 后在 V-for 上调用函数

问题描述

const responseFromFetch = [{
  name:'apple',
  color: 'green',
},
{
  name:'apple',
  color: 'red',
},
{
  name:'apple',
  color: 'yellow',
},
{
  name:'orange',
  color: 'orange',
},
{
  name:'orange',
  color: 'green',
}]

假设上面的数据是来自fetch呼叫的响应。我想在列表中呈现它。代替:

//apple green
//apple red
//apple yellow
//orange orange
//orange green

我想:

 // apple
     //green
     //yellow
     //red
 // orange
     //orange
     //green

通话后fetch,我:

最后,我创建了一个getItemPerNamename参数的函数,但它返回undefined是因为它还fetch没有准备好,但是如果我把这个函数放在fetch调用里面,我不能返回这个函数放在模板里面。

const getItemPerName = (name) => responseFromFetch.filter(item=> item.name == name);

我的模板:

 <div v-for="(name, index) in removeDuplicates">
   <h1>{{ name}}</h1>
   <div v-for="item in getItemPerName(name)" ></div >
 </div>
setup() {
    fetchCall.then((response) =>  {
      sort alphabetic response by name
      remove duplicates

     //return cant access getItemPerName If I call the function here because of scope
    })
    const getItemPerName = (name) => responseFromFetch.filter(item=> item.name == name); //undefined because fetch its not ready
    
    onMounted(() => { 
        //return cant access getItemPerName If I call the function here because of scope
    })

    return {
        removeDuplicates,
        getItemPerName //undefined
    }}
}

标签: javascriptvuejs3vue-composition-api

解决方案


一种解决方案是使用在回调reactive中更新的道具:fetch

import { reactive, onMounted } from "vue"

export default {
  setup() {
    const uniqueItems = reactive({})

    onMounted(async () => {
      const receivedItems = await fetchCall()
      Object.assign(uniqueItems, groupColorsByName(receivedItems))
    })

    return {
      uniqueItems,
    }
  },
}

groupColorsByName() 将给定数组缩减为一个新对象,该对象将项目名称映射到一种Set颜色(去重):

const groupColorsByName = (itemsArray) =>
  itemsArray.reduce((p, c) => {
    p[c.name] = p[c.name] || {}
    p[c.name].colors = p[c.name].colors || new Set()
    p[c.name].colors.add(c.color)
    return p
  }, {})

然后,使用 渲染该对象v-for

<template>
  <div v-for="(item, name) in uniqueItems" :key="name">
    <h1>{{ name }}</h1>
    <div v-for="color in item.colors" :key="color">{{ color }}</div>
  </div>
</template>

演示


推荐阅读