如何将Axios与Vue 3 Composition API一起使用



我正在尝试基于以下教程,使用Vue 3和Composition API构建Pokemon过滤搜索应用程序:https://www.youtube.com/watch?v=QJhqr7jqxVo.(GitHub:https://github.com/ErikCH/PokemonVue)

搜索组件中使用的fetch方法包括一个reduce((函数,用于根据API响应中分配给每个Pokemon的特定id来处理urlIdLookup:

const state = reactive({
pokemons: [],
filteredPokemon: computed(()=> updatePokemon()), 
text: "",
urlIdLookup: {}

});
fetch("https://pokeapi.co/api/v2/pokemon?offset=0")
.then((res) => res.json())
.then((data) => {
console.log(data);
state.pokemons = data.results;
state.urlIdLookup = data.results.reduce((acc, cur, idx)=> 
acc = {...acc, [cur.name]:idx+1 }
,{})
console.log('url',state.urlIdLookup+1)

});

urlIdLookup然后进入用于显示所选口袋妖怪信息的路线:

<div
class="ml-4 text-2xl text-blue-400"
v-for="(pokemon, idx) in filteredPokemon"
:key="idx"
>
<router-link :to="`/about/${urlIdLookup[pokemon.name]}`">
{{ pokemon.name }}
</router-link>
</div>

我希望使用Axios来处理来自Pokemon API的请求和响应,而不是使用上面的fetch设置。在项目中安装Axios并将其导入组件后,我添加了一种新的fetchPokemon方法:

const fetchPokemon = () => {
axios.get('https://pokeapi.co/api/v2/pokemon?offset=0')
.then(response => {
state.pokemons = response.data
})
}
onMounted(() => {
fetchPokemon()
})

在这个新的获取方法中使用Axios时,我希望处理类似于以前的获取设置的urlIdLookup,但如果可能的话,不使用reduce()方法和非结构化累加器。我如何使用Axios来检索每个口袋妖怪的urlId,然后将该urlId传递到";关于";模板中的路由?

以下是完整的组件:

<template>
<div class="w-full flex justify-center">
<input placeholder="Enter Pokemon here" type="text" 
class="mt-10 p-2 border-blue-500 border-2" v-model="text" />
</div>
<div class="mt-10 p-4 flex flex-wrap justify-center">

<div
class="ml-4 text-2xl text-blue-400"
v-for="(pokemon, idx) in filteredPokemon"
:key="idx"
>
<router-link :to="`/about/${urlIdLookup[pokemon.name]}`">
{{ pokemon.name }}
</router-link>
</div>
</div>
</template>
<script>
import axios from 'axios';
import { reactive, toRefs, computed, onMounted } from "vue";
export default {
setup() {
const state = reactive({
pokemons: [],
filteredPokemon: computed(()=> updatePokemon()), 
text: "",
urlIdLookup: {}

});
const fetchPokemon = () => {
axios.get('https://pokeapi.co/api/v2/pokemon?offset=0')
.then(response => {
state.pokemons = response.data
})
}
onMounted(() => {
fetchPokemon()
})
// fetch("https://pokeapi.co/api/v2/pokemon?offset=0")
//   .then((res) => res.json())
//   .then((data) => {
//     console.log(data);
//     state.pokemons = data.results;
//     state.urlIdLookup = data.results.reduce((acc, cur, idx)=> 
//        acc = {...acc, [cur.name]:idx+1 }
//     ,{})
//     console.log('url',state.urlIdLookup+1)

//   });
function updatePokemon(){
if(!state.text){
return [] 
}
return state.pokemons.filter((pokemon)=> 
pokemon.name.includes(state.text)
)
}
return { ...toRefs(state), fetchPokemon, updatePokemon };
}
};
</script>

如果我理解正确,请查看以下片段:

const { reactive, toRefs, computed, onMounted } = Vue
const { axioss } = axios
const app = Vue.createApp({
setup() {
const state = reactive({
pokemons: [],
filteredPokemon: computed(() => updatePokemon()),
text: "",
urlIdLookup: {},
});
const fetchPokemon = () => {
axios
.get("https://pokeapi.co/api/v2/pokemon?offset=0")
.then((response) => {
state.pokemons = response.data.results; // 👈 get just results
});
};
fetchPokemon();

// 👇 function to get index
const getPokemonId = (item) => {
return state.pokemons.findIndex((p) => p.name === item);
};
function updatePokemon() {
if (!state.text) {
return [];
}
return state.pokemons.filter((pokemon) =>
pokemon.name.includes(state.text)
);
}
// 👇 return new function
return { ...toRefs(state), fetchPokemon, updatePokemon, getPokemonId };
},
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.26.1/axios.min.js" integrity="sha512-bPh3uwgU5qEMipS/VOmRqynnMXGGSRv+72H/N260MQeXZIK4PG48401Bsby9Nq5P5fz7hy5UGNmC/W1Z51h2GQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="demo">
<div class="w-full flex justify-center">
<input
placeholder="Enter Pokemon here"
type="text"
class="mt-10 p-2 border-blue-500 border-2"
v-model="text"
/>
</div>
<div class="mt-10 p-4 flex flex-wrap justify-center">
<div
class="ml-4 text-2xl text-blue-400"
v-for="(pokemon, i) in filteredPokemon"
:key="i"
>
<!-- // 👇 call function to get index -->
<router-link :to="`/about/${getPokemonId(pokemon.name)}`">
{{ pokemon.name }} - id {{ getPokemonId(pokemon.name) }}
</router-link>
</div>
</div>
</div>

似乎id是不必要的,为什么不使用name be id呢?如果你想使用interger是必须的,您可以foreach结果集索引是每个项目的id,然后

<router-link :to="`/about/${pokemon.id}`">
{{ pokemon.name }}
</router-link>

最新更新