我正在使用 Vue 3、Composition API 和 Pinia 構建一個 Pokemon 過濾搜索應用程式。我正在嘗試設定應用程式,以便從 Pokemon API 獲取的回應傳遞到 fetchPokemon() 函式內的商店(使用 Pinia 設定)。
const fetchPokemon = () => {
axios.get("https://pokeapi.co/api/v2/pokemon?offset=0")
.then((response) => {
store.addPokemon(response.data.results)
})
}
將回應傳遞給商店后,updatePokemon() 函式使用 filter 和 include 方法過濾掉商店中的 Pokemon 并將其與用戶輸入文本欄位(“state.text”)中的 Pokemon 匹配:
const updatePokemon = () => {
if(!state.text) {
return []
}
return store.getState.pokemons.filter((pokemon) =>
pokemon.name.includes(state.text)
)
}
執行應用程式時,我在 updatePokemon() 函式中收到以下錯誤:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'includes')
我假設這意味著用于搜索/過濾的 .includes() 方法不能用于此搜索。我應該如何處理過濾器并包含將商店中的口袋妖怪與用戶輸入的口袋妖怪匹配的方法?
這是代碼:
松樹專賣店
import { defineStore } from 'pinia'
export const usePokemonStore = defineStore({
id: 'store',
state: () => ({
pokemons: []
}),
getters: {
getState(state) {
return state
}
},
actions: {
addPokemon(name) {
this.pokemons.push(name)
}
}
})
零件
<template>
<div >
<input type="text" placeholder="Enter Pokemon here"
v-model="text"/>
</div>
<div >
<div
v-for="(pokemon, idx) in filteredPokemon" :key="idx">
<router-link :to="`/about/${getPokemonId(pokemon.name)}`">
{{ pokemon.name }} - with id {{ getPokemonId(pokemon.name) }}
</router-link>
</div>
</div>
</template>
<script>
import axios from 'axios';
import { reactive, toRefs, computed } from 'vue';
import { usePokemonStore } from '@/store';
export default {
name: 'Home',
setup() {
const store = usePokemonStore()
const state = reactive({
text: "",
filteredPokemon: computed(()=> updatePokemon())
})
const updatePokemon = () => {
if(!state.text) {
return []
}
return store.getState.pokemons.filter((pokemon) =>
pokemon.name.includes(state.text)
)
}
const fetchPokemon = () => {
axios.get("https://pokeapi.co/api/v2/pokemon?offset=0")
.then((response) => {
store.addPokemon(response.data.results)
})
}
fetchPokemon()
const getPokemonId = (item) => {
console.log(item)
return store.pokemons.findIndex((p) => p.name === item) 1
}
return { ...toRefs(state), fetchPokemon, getPokemonId, updatePokemon, store }
}
}
</script>
更新
存盤 - 不采取行動
import { defineStore } from 'pinia'
export const usePokemonStore = defineStore({
id: 'store',
state: () => ({
pokemons: []
})
})
組件 - 沒有 store.addPokemon(...)
<template>
<div >
<input type="text" placeholder="Enter Pokemon here"
v-model="text"/>
</div>
<div >
<div
v-for="(pokemon, idx) in filteredPokemon" :key="idx">
<router-link :to="`/about/${getPokemonId(pokemon.name)}`">
{{ pokemon.name }} - with id {{ getPokemonId(pokemon.name) }}
</router-link>
</div>
</div>
</template>
<script>
import axios from 'axios';
import { reactive, toRefs, computed } from 'vue';
import { usePokemonStore } from '@/store';
export default {
name: 'Home',
setup() {
const store = usePokemonStore()
const state = reactive({
// pokemons: [],
text: "",
filteredPokemon: computed(()=> updatePokemon())
})
const updatePokemon = () => {
if(!state.text) {
return []
}
return store.pokemons.filter((pokemon) =>
pokemon.name.includes(state.text)
)
}
const fetchPokemon = () => {
axios.get("https://pokeapi.co/api/v2/pokemon?offset=0")
.then((response) => {
store.pokemons = response.data.results
})
}
fetchPokemon()
const getPokemonId = (item) => {
console.log(item)
return store.pokemons.findIndex((p) => p.name === item) 1
}
return { ...toRefs(state), fetchPokemon, getPokemonId, store }
}
}
</script>
uj5u.com熱心網友回復:
首先,你根本不需要getState。
你可以usePokemonStore().pokemons直接使用。呼叫函式回傳的物件usePokemonStore()包括:
- 所有狀態屬性
- 所有動作
- 所有吸氣劑。
以下是根據名稱是否包含過濾后的口袋妖怪陣列的方法state.text:
setup() {
const store = usePokemonStore();
const state = reactive({
text: "",
filteredPokemons: computed(() => store.pokemons.filter(
pokemon => pokemon.name.includes(state.text)
))
});
return {
...toRefs(state)
}
}
作業示例:
const { createApp, reactive, toRefs, computed, onMounted } = Vue;
const { defineStore, createPinia } = Pinia;
const usePokemons = defineStore('pokemon', {
state: () => ({ pokemons: [] })
});
const pinia = createPinia();
createApp({
pinia,
setup() {
const store = usePokemons(pinia);
const state = reactive({
searchTerm: '',
filteredPokemons: computed(() => store.pokemons.filter(
pokemon => pokemon.name.includes(state.searchTerm)
))
});
onMounted(() => {
fetch('https://pokeapi.co/api/v2/pokemon?offset=0')
.then(r => r.json())
.then(r => store.pokemons = r.results)
});
return {
...toRefs(state)
}
}
}).mount('#app')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/vue-demi"></script>
<script src="https://unpkg.com/[email protected]/dist/pinia.iife.prod.js"></script>
<div id="app">
<input v-model="searchTerm">
<div v-for="pokemon in filteredPokemons">
{{ pokemon.name }}
</div>
</div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/442209.html
