Pinia 错误:“getActivePinia()”被调用,但没有活动的 Pinia。你忘了安装pinia吗?

Pinia error: "getActivePinia()" was called but there was no active Pinia. Did you forget to install pinia?

提问人:Michael 提问时间:10/27/2023 最后编辑:yoduhMichael 更新时间:10/27/2023 访问量:76

问:

尽管我有一个操作可以根据数据是否已经获取(这使得它已经是反应性的)来改变“挂起”状态,但当我在组件内部使用它时,反应性不起作用,这在官方 Pinia 文档中有所提及:https://pinia.vuejs.org/ssr/#Using-the-store-outside-of-setup-。然后我尝试使用 storeToRefs 使“待处理”状态成为反应式,但我不断收到此错误:

Uncaught Error: [🍍]: "getActivePinia()" was called but there was no active Pinia. Did you forget to install pinia?
    const pinia = createPinia()
    app.use(pinia)
This will fail in production.

这是我的Pinia商店:

import { defineStore, storeToRefs } from 'pinia';

export const useStoreRecipes = defineStore('storeRecipes', {
    state: () => {
        return {
            data: [],
            pending: false,
        };
    },
    actions: {
        async loadRecipes() {
            try {
                this.pending = true;
                const res = await fetch('/api/recipe');
                if (res.ok) {
                    const data = await res.json();
                    this.data = data;
                } else {
                    console.error('Error: ', res.status, res.statusText);
                }
            } catch (err) {
                console.error(err);
            } finally {
                this.pending = false;
            }
        },
    },
});

const store = useStoreRecipes();

export const { pending } = storeToRefs(store);

我的主.js:

import '@/assets/scss/main.scss';
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import router from '@/router';
import App from './App.vue';

const app = createApp(App);
const pinia = createPinia();

app.use(pinia);
app.use(router);
app.mount('#app');

然后我在我的一个组件中使用“待处理”。

<template>
    <Swiper
        class="swiper"
        :breakpoints="swiperOptions.breakpoints"
        :pagination="{
            clickable: true,
        }"
        :loop="true"
        :modules="swiperOptions.modules">
        <template v-for="recipe in storeRecipes.data" :key="recipe.id">
            <SwiperSlide class="swiper__slide">
                <ItemCard :data="recipe" :pending="storeRecipes.pending" />
            </SwiperSlide>
            <div class="swiper-custom-pagination"></div>
        </template>
    </Swiper>
</template>

<script setup>
import { onMounted } from 'vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Pagination } from 'swiper/modules';
import 'swiper/css/free-mode';
import 'swiper/css/pagination';
import 'swiper/css';
import { useStoreRecipes } from '@/stores/recipes/storeRecipes.js';

import ItemCard from '@/components/ItemCard.vue';

const storeRecipes = useStoreRecipes();

onMounted(async () => {
    await storeRecipes.loadRecipes();
});
</script>

如何解决?

更新:

错误现在消失了,但“待处理”仍然表现得好像它没有反应。在这里,我在骨架负载上将道具传递给子组件。出于某种原因,骨架无限加载:

<template>
    <div class="card">
        <div class="card__item">
            <ItemCardSkeleton v-if="!pending" />
            <template v-else>
                <img
                    class="card__image"
                    :src="getSrc('.jpg')"
                    :alt="data.alt"
                    width="15.625rem" />
                <div class="card__content">
                    <h2 class="card__title">{{ data.title }}</h2>
                    <p class="card__text">{{ data.text }}</p>
                    <router-link class="card__link" :to="{ name: 'Home' }"
                        >View more</router-link
                    >
                </div>
            </template>
        </div>
    </div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import ItemCardSkeleton from '@/components/SkeletonLoaders/ItemCardSkeleton.vue';

const props = defineProps(['data', 'pending']);

const isLoaded = ref(false);

const getSrc = ext => {
    return new URL(
        `../assets/images/recipe/${props.data.image}${ext}`,
        import.meta.url
    ).href;
};

onMounted(() => {
    const img = new Image(getSrc('.jpg'));
    img.onload = () => {
        isLoaded.value = true;
    };
    img.src = getSrc('.jpg');
});
</script>
JavaScript vue.js vuejs3 反应式 pinia

评论


答:

1赞 yoduh 10/27/2023 #1

此代码需要从您的商店中删除

const store = useStoreRecipes();

export const { pending } = storeToRefs(store);

一个有趣的想法,但它不起作用。pinia 实例尚未处于活动状态。从你的商店中解构引用实际上应该在你的组件代码中完成:

<script setup>
import { useStoreRecipes } from '@/stores/recipes/storeRecipes.js';
import { storeToRefs } from 'pinia';

const storeRecipes = useStoreRecipes();

const { pending } = storeToRefs(store);
</script>

评论

0赞 Michael 10/27/2023
谢谢你的建议!尽管我做了这些更改,但我的“待处理”仍然表现得好像它不是反应性的。在这里,我将 props 传递给骨架加载器上的子组件:code const props = defineProps(['data', 'pending']); code <template> <div class="card__item"> <ItemCardSkeleton v-if="!pending" /> <template v-else> <div class="card__content"> <h2 class="card__title">{{ data.title }}</h2> <router-link class="card__link" :to="{ name: 'Home' }" >View more</router-link > </div> </template> </div> </template>
0赞 Michael 10/27/2023
框架加载器应在获取数据时显示,完成后,内容应显示
0赞 yoduh 10/27/2023
首先,你摆脱了错误吗?其次,代码很难在注释中阅读。请编辑您的问题,以包含新的/更新的信息和正确的代码格式。
0赞 Michael 10/27/2023
问题已更新。
0赞 Michael 10/27/2023
我认为如果我将 !pending 更改为 pending,问题就消失了。不过我看不到骨架,可能是因为获取过程太快了。