【发布时间】:2023-02-09 06:35:12
【问题描述】:
我有以下定义 Pinia 存储的代码:
import { ref, computed, shallowRef } from 'vue'
import { defineStore } from 'pinia'
export const usePokemonStore = defineStore('pokemons', () => {
// define the pokemons list state
const pokemonsList = ref([]);
const pokemonsLoaded = ref([]);
const pokemonsLoadedNames = ref([]);
// computed
const pokemonsListLength = computed(() => pokemonsList.value.length)
const pokemonsLoadedLength = computed(() => pokemonsLoaded.value.length)
// actions
async function getList() {
const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=100000&offset=0');
const data = await res.json();
pokemonsList.value = data["results"];
}
async function loadPokemon(name) {
const URI = `https://pokeapi.co/api/v2/pokemon/${name}`
const res = await fetch(URI);
const data = await res.json();
pokemonsLoadedNames.value.push(data["name"])
pokemonsLoaded.value.push(data)
}
async function loadPokemons(offset, limit){
// basic check for limits
limit = limit > pokemonsListLength ? pokemonsListLength : limit;
limit = limit < 0 ? 10 : limit
// basic check for offset
offset = offset < 0 ? 0 : offset;
offset = offset > pokemonsListLength ? 0 : offset
for (let i = offset; i < offset+limit; i++){
// if the pokemon is already loaded skips the request for it
if (pokemonsLoadedNames.value.includes(pokemonsList.value[i].name)) {
continue;
}
// requests the pokemon given a name
loadPokemon(pokemonsList.value[i].name)
}
}
return {
pokemonsList,
pokemonsLoaded,
pokemonsListLength,
pokemonsLoadedLength,
pokemonsLoadedNames,
getList,
loadPokemon,
loadPokemons
}
})
我有以下组件,它利用该存储来获取口袋妖怪:
<template>
<div class="pokedex">
<PokemonImage class="pokemon-figure" pokemon="" />
<ul v-if="pokemonsToShow" class="pokemon-showcase">
<li class="pokemon-item" v-for="pokemon in pokemonsToShow">
<PokemonCard :pokemon="pokemon" />
</li>
</ul>
<div class="navigation">
<button v-show="page !== 1" @click="pageChange(-1)">Previous Page</button>
<button @click="pageChange(1)">Next Page</button>
</div>
{{ page }}
</div>
</template>
<script setup>
import { onBeforeMount, ref, computed, watch } from 'vue';
import { usePokemonStore } from '../stores/pokemon'
import PokemonCard from '../components/PokemonCard.vue'
import PokemonImage from '../components/PokemonImage.vue'
const pokeStore = usePokemonStore();
const page = ref(1)
const pokemonsToShow = ref([])
// offset and limit calculate based on the page
const limit = computed(() => 20 );
const offset = computed(() => page.value * limit.value - limit.value);
// initial load
onBeforeMount(async () => {
await pokeStore.getList()
await pokeStore.loadPokemons(0, limit.value)
pokemonsToShow.value = pokeStore.pokemonsLoaded.slice(0, pokeStore.pokemonsLoadedLength)
})
const pageChange = async (step) => {
page.value = page.value + step
await pokeStore.loadPokemons(offset.value, limit.value)
const start = offset.value;
const end = offset.value + limit.value;
console.log(start, end)
console.log(pokeStore.pokemonsLoaded)
pokemonsToShow.value = pokeStore.pokemonsLoaded.slice(start, end)
console.log(pokemonsToShow.value)
}
</script>
现在,当用户单击页面按钮时,page.value 会更新,因此偏移量和限制的计算值也会更新(实际上只有偏移量更新),如果页面是新的,我可以从中加载新的口袋妖怪我通过调用 pokeStore.loadPokemons(offset.value, limit.value) 函数并在 pageChange 函数中等待它来完成的。但是现在我想更改 pokemonsToShow,所以我想在存储中获取加载的 pokemons 数组的一部分,但每次我尝试对该数组进行切片时,我什么也得不到,即使当我使用 console.log(pokeStore.pokemonsLoaded) 打印数组时数组显示为使用新值更新,并且范围正确。
我希望数组能够正确切片,因为如果我在此函数调用中放置静态值:
pokemonsToShow.value = pokeStore.pokemonsLoaded.slice(2, 4)
}
它出于某种原因起作用,但不适用于动态计算的值
【问题讨论】: