gpt4 book ai didi

vue.js - 如何在 Vue 3 Composition API 中设置 Pinia getter

转载 作者:行者123 更新时间:2023-12-02 01:42:19 32 4
gpt4 key购买 nike

我正在使用 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() 方法不能用于此搜索。我应该如何处理过滤器并包含将商店中的 Pokemon 与用户输入的 Pokemon 相匹配的方法?

代码如下:

Pinia 商店

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 class="w-full flex justify-center">
<input type="text" placeholder="Enter Pokemon here"
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-2x text-blue-400"
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>

已更新

存储 - 没有 Action

import { defineStore } from 'pinia'

export const usePokemonStore = defineStore({
id: 'store',
state: () => ({
pokemons: []
})
})

组件 - 没有 store.addPokemon(...)

<template>
<div class="w-full flex justify-center">
<input type="text" placeholder="Enter Pokemon here"
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-2x text-blue-400"
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>

最佳答案

首先,您根本不需要getState

您可以直接使用usePokemonStore().pokemons。调用usePokemonStore()函数返回的对象包括:

  • 所有国家属性(property)
  • 所有 Action
  • 所有 setter/getter 。

下面是根据它们的名称是否包含 state.text 来获取过滤后的 pokemon 数组的方法:

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/pinia@2.0.11/dist/pinia.iife.prod.js"></script>
<div id="app">
<input v-model="searchTerm">
<div v-for="pokemon in filteredPokemons">
{{ pokemon.name }}
</div>
</div>

关于vue.js - 如何在 Vue 3 Composition API 中设置 Pinia getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71452197/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com