getActivePinia被调用,但没有活跃的Pinia。Vue

huangapple go评论63阅读模式
英文:

getActivePinia was called with no active Pinia. Vue

问题

以下是您提供的代码部分的翻译:

pokemonDetails:

<script>
import { usePokemonStore } from '../stores/PokemonStore';
const pokemonStore = usePokemonStore();
export default {
  name: 'PokemonDetails',
  methods: {
    evolutions() {
      return [
        pokemonStore.evolutionOne,
        pokemonStore.evolutionTwo,
        pokemonStore.evolutionThree,
      ];
    },
    resetApp() {
      this.$router.push('/');
      pokemonStore.$reset();
    },
  },
};
</script>

<template>
  <template v-if="pokemonStore.findPokemon == false">
    <div class="firstDiv">
      <div class="secondDiv">
        <div>
          <strong>{{ pokemonStore.pokemonName }}</strong><img :src="pokemonStore.selfie" alt="pokemon图片" />
          <p>主要元素: {{ pokemonStore.type }}</p>
        </div>
        <div>
          <strong>技能:</strong>
          <ul>
            <li v-for="stat in pokemonStore.stats[0]">
              {{ stat.stat.name }}: +{{ stat.base_stat }}
            </li>
          </ul>
        </div>
      </div>
      <div class="divEvolutions">
        <strong>进化</strong>
        <ul class="evolutions">
          <li v-for="evolution in evolutions">
            <img :src="evolution.selfie" />
            {{ evolution.name }}
          </li>
        </ul>
      </div>
      <button v-on:click="resetApp" class="newSearch">新搜索</button>
    </div>
  </template>
</template>

<style lang="scss" scoped>
.firstDiv {
  text-align: center;
}
.secondDiv {
  display: grid;
  justify-items: center;
  align-items: center;
  grid-template-columns: repeat(2, 1fr);
  max-height: 600px;
  width: 400px;
  padding: 20px;
  border-radius: 1.5rem;
  background-color: $gray-200;
  div {
    display: flex;
    flex-direction: column;
  }
}
.divEvolutions {
  background-color: $gray-200;
  border-radius: 1.5rem;
  margin-top: 10px;
}
.evolutions {
  display: flex;
  justify-content: center;
  align-items: center;
  li {
    display: flex;
    flex-direction: column;
  }
}
.newSearch {
  margin-top: 10px;
  padding: 5px;
  border-radius: 1rem;
  background-color: $gray-200;
  transition-duration: 500ms;
  &:hover {
    background-color: black;
    color: $gray-200;
  }
}
</style>

pokemonStore.js:

import { defineStore } from 'pinia';

export const usePokemonStore = defineStore('pokemon', {
  state: () => ({
    findPokemon: true,
    pokemonName: '',
    speciesLink: '',
    selfie: '',
    type: '',
    stats: [],
    evolutionOne: {},
    evolutionTwo: {},
    evolutionThree: {},
  }),
  getters: {},
  actions: {
    addPokemon(
      name,
      species,
      selfie,
      type,
      stats,
      evolutionOne,
      evolutionTwo,
      evolutionThree
    ) {
      this.pokemonName = name;
      this.speciesLink = species;
      this.selfie = selfie;
      this.type = type;
      this.stats.push(stats);
      this.findPokemon = false;
      this.evolutionOne = evolutionOne;
      this.evolutionTwo = evolutionTwo;
      this.evolutionThree = evolutionThree;
    },
  },
});

main.js:

import { createApp } from 'vue';
import { createPinia } from 'pinia';

import App from './App.vue';
import router from './router';

import './assets/main.css';

const app = createApp(App);

app.use(createPinia());
app.use(router);

app.mount('#app');

我尝试在computed中调用我的存储:

computed: {
  pokemonStore() {
    return usePokemonStore();
  },
  evolutions() {
    return [
      this.pokemonStore.evolutionOne,
      this.pokemonStore.evolutionTwo,
      this.pokemonStore.evolutionThree,
    ];
  },
},

它能够正常工作,但我认为这不是最佳实践。

英文:

i get this error: Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
const pinia = createPinia()
app.use(pinia)
This will fail in production.
at useStore (pinia.mjs:1691:19)
at PokemonDetails.vue:3:22

what's wrong with my code?

pokemonDetails:

&lt;script&gt;
import { usePokemonStore } from &#39;../stores/PokemonStore&#39;;
const pokemonStore = usePokemonStore();
export default {
name: &#39;PokemonDetails&#39;,
methods: {
evolutions() {
return [
pokemonStore.evolutionOne,
pokemonStore.evolutionTwo,
pokemonStore.evolutionThree,
];
},
resetApp() {
this.$router.push(&#39;/&#39;);
pokemonStore.$reset();
},
},
};
&lt;/script&gt;
&lt;template&gt;
&lt;template v-if=&quot;pokemonStore.findPokemon == false&quot;&gt;
&lt;div class=&quot;firstDiv&quot;&gt;
&lt;div class=&quot;secondDiv&quot;&gt;
&lt;div&gt;
&lt;strong&gt;{{ pokemonStore.pokemonName }}&lt;/strong
&gt;&lt;img :src=&quot;pokemonStore.selfie&quot; alt=&quot;foto de pokemon&quot; /&gt;
&lt;p&gt;Elemento Principal: {{ pokemonStore.type }}&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;strong&gt;Habilidades:&lt;/strong&gt;
&lt;ul&gt;
&lt;li v-for=&quot;stat in pokemonStore.stats[0]&quot;&gt;
{{ stat.stat.name }}: +{{ stat.base_stat }}
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;divEvolutions&quot;&gt;
&lt;strong&gt;Evolu&#231;&#227;o&lt;/strong&gt;
&lt;ul class=&quot;evolutions&quot;&gt;
&lt;li v-for=&quot;evolution in evolutions&quot;&gt;
&lt;img :src=&quot;evolution.selfie&quot; /&gt;
{{ evolution.name }}
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;button v-on:click=&quot;resetApp&quot; class=&quot;newSearch&quot;&gt;Nova pesquisa&lt;/button&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;/template&gt;
&lt;style lang=&quot;scss&quot; scoped&gt;
.firstDiv {
text-align: center;
}
.secondDiv {
display: grid;
justify-items: center;
align-items: center;
grid-template-columns: repeat(2, 1fr);
max-height: 600px;
width: 400px;
padding: 20px;
border-radius: 1.5rem;
background-color: $gray-200;
div {
display: flex;
flex-direction: column;
}
}
.divEvolutions {
background-color: $gray-200;
border-radius: 1.5rem;
margin-top: 10px;
}
.evolutions {
display: flex;
justify-content: center;
align-items: center;
li {
display: flex;
flex-direction: column;
}
}
.newSearch {
margin-top: 10px;
padding: 5px;
border-radius: 1rem;
background-color: $gray-200;
transition-duration: 500ms;
&amp;:hover {
background-color: black;
color: $gray-200;
}
}
&lt;/style&gt;

pokemonStore.js:

import { defineStore } from &#39;pinia&#39;;
export const usePokemonStore = defineStore(&#39;pokemon&#39;, {
state: () =&gt; ({
findPokemon: true,
pokemonName: &#39;&#39;,
speciesLink: &#39;&#39;,
selfie: &#39;&#39;,
type: &#39;&#39;,
stats: [],
evolutionOne: {},
evolutionTwo: {},
evolutionThree: {},
}),
getters: {},
actions: {
addPokemon(
name,
species,
selfie,
type,
stats,
evolutionOne,
evolutionTwo,
evolutionThree
) {
this.pokemonName = name;
this.speciesLink = species;
this.selfie = selfie;
this.type = type;
this.stats.push(stats);
this.findPokemon = false;
this.evolutionOne = evolutionOne;
this.evolutionTwo = evolutionTwo;
this.evolutionThree = evolutionThree;
},
},
});

main.js:

import { createApp } from &#39;vue&#39;;
import { createPinia } from &#39;pinia&#39;;
import App from &#39;./App.vue&#39;;
import router from &#39;./router&#39;;
import &#39;./assets/main.css&#39;;
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount(&#39;#app&#39;);

i tried call my store in computed:

  computed: {
pokemonStore() {
return usePokemonStore();
},
evolutions() {
return [
this.pokemonStore.evolutionOne,
this.pokemonStore.evolutionTwo,
this.pokemonStore.evolutionThree,
];
},
},

it works, but i believe is don't the best practices

答案1

得分: 8

商店不应在安装到Vue应用程序之前使用Pinia。

use... 组合是由Pinia的 defineStore 创建而不是存储对象的原因是,这样可以避免竞争条件。

这里在Pinia安装之前在pokemonDetails导入上调用了 usePokemonStore。在模板中引用了 pokemonStore,而它不是组件实例的一部分。对于使用选项API的组件,应该是:

  name: 'PokemonDetails',
data() {
return { pokemonStore: usePokemonStore() }
},
英文:

Stores aren't supposed to be used before Pinia is installed to Vue application.

The reason why use... composables are created by Pinia defineStore instead of store objects is that this allows to avoid race conditions.

Here usePokemonStore is called on pokemonDetails import before Pinia install. pokemonStore is referred in the template while it's not a part of component instance. For a component with options API it should be:

  name: &#39;PokemonDetails&#39;,
data() {
return { pokemonStore: usePokemonStore() }
},

答案2

得分: 3

我在最近的一个情节中经历了这个,当你尝试在创建pinia之前访问pinia时会发生这种情况。

我定义了一个名为global.ts的文件,其中包含下面的指令:

import { createPinia } from 'pinia'
export const piniaInstance = createPinia()

然后在我的user store.ts文件中,我导入了已经在全局创建的pinia实例,并将其包含在store中,直接将store导出到任何请求的位置。

import { UsuarioData } from "@/recursos/classes/Usuario";
import { defineStore } from "pinia";
import { piniaInstance } from '@/recursos/global'
import { userStorageKey } from '@/recursos/constantes'

const usuarioStore = defineStore('usuario', {
  state() {
    return {
      dadosUsuario: new UsuarioData()
    }
  },
  actions: {
    deslogar() {
      localStorage.removeItem(userStorageKey)
      this.dadosUsuario = new UsuarioData()
      console.log('usuario após deslogar', this.dadosUsuario)
    },
    logar(dadosUsuario: UsuarioData) {
      localStorage.setItem(userStorageKey, dadosUsuario.Token)
      this.dadosUsuario = dadosUsuario
    }
  },
  getters: {
    obterUsuario() : UsuarioData {
      return this.dadosUsuario
    },
    obterTokenAcesso() : string {
      return this.dadosUsuario.Token
    }
  }
})(piniaInstance); // pinia instance

export default usuarioStore

这对我有效。即使我有多个stores,我也可以在stores中调用pinia实例并将其作为参数传递。

记得在你的main.ts/js文件中也要导入pinia实例。

import '@/assets/styles/app.css'
import { createApp } from 'vue'
import { piniaInstance } from '@/recursos/global'
import App from './App.vue'
import router from './recursos/router'

const app = createApp(App)
app.use(router).use(piniaInstance)
app.mount('#app')
英文:

I went through this in a recent episode and this happens when you try to access the pinia without having created it before.

I defined a file called global.ts that contains the instructions below

import { createPinia } from &#39;pinia&#39;
export const piniaInstance = createPinia()

Then in my user store.ts file I imported the pinia instance already created globally and included it in the store, thus directly exporting the store to any location requested.

import { UsuarioData } from &quot;@/recursos/classes/Usuario&quot;;
import { defineStore } from &quot;pinia&quot;;
import { piniaInstance } from &#39;@/recursos/global&#39;
import { userStorageKey } from &#39;@/recursos/constantes&#39;
const usuarioStore = defineStore(&#39;usuario&#39;, {
state() {
return {
dadosUsuario: new UsuarioData()
}
},
actions: {
deslogar() {
localStorage.removeItem(userStorageKey)
this.dadosUsuario = new UsuarioData()
console.log(&#39;usuario ap&#243;s deslogar&#39;, this.dadosUsuario)
},
logar(dadosUsuario: UsuarioData) {
localStorage.setItem(userStorageKey, dadosUsuario.Token)
this.dadosUsuario = dadosUsuario
}
},
getters: {
obterUsuario() : UsuarioData {
return this.dadosUsuario
},
obterTokenAcesso() : string {
return this.dadosUsuario.Token
}
}
})(piniaInstance); // pinia instance
export default usuarioStore

this worked for me. Even if I have several stores, I can call the pinia instance within the stores and pass it as a parameter

remember to import the pinia instance into your main.ts/js file as well

import &#39;@/assets/styles/app.css&#39;
import { createApp } from &#39;vue&#39;
import { piniaInstance } from &#39;@/recursos/global&#39;
import App from &#39;./App.vue&#39;
import router from &#39;./recursos/router&#39;
const app = createApp(App)
app.use(router).use(piniaInstance)
app.mount(&#39;#app&#39;)

答案3

得分: 0

检查一下是否在混合使用选项(Options)和组合式(Composition API)的组件,并在没有考虑的情况下进行复制粘贴。在旧的选项(Options)API组件中使用 pinia 是不同的。

英文:

Check you aren't mixing options and composition API components up and copy/pasting without thinking. Using pinia on an old options API component is different.

答案4

得分: 0

在项目终端中:

  1. npm uninstall -g @pinia
  2. npm list -g @pinia

你将会得到这个错误

npm ERR! code EINVALIDTAGNAME
npm ERR! Invalid tag name &quot;@pinia&quot; of package &quot;@pinia&quot;: Tags may not have any characters that encodeURIComponent encodes.
npm ERR! A complete log of this run can be found in:
npm ERR!     /home/spark/.npm/_logs/2023-07-15T07_29_36_570Z-debug-0.log
  1. npm uninstall @pinia
  2. npm cache clean --force
  3. rm -rf node_modules
  4. npm install @pinia

这将修复

如果你得到这个错误

npm ERR! code EINVALIDTAGNAME
npm ERR! Invalid tag name &quot;@pinia&quot; of package &quot;@pinia&quot;: Tags may not have any characters that encodeURIComponent encodes.
npm ERR! A complete log of this run can be found in:
npm ERR!     /home/spark/.npm/_logs/2023-07-15T07_30_56_791Z-debug-0.log

再次添加以下内容

rm -rf node_modules,
npm cache clean --force,
npm install

这将改变项目 pinia 版本,如果你是协作的,请根据最佳情况更改,以避免在托管时遇到其他问题。

英文:

In project terminal:

  1. npm uninstall -g @pinia
  2. npm list -g @pinia

you will get this error
npm ERR! code EINVALIDTAGNAME
npm ERR! Invalid tag name "@pinia" of package "@pinia": Tags may not have any characters that encodeURIComponent encodes.

npm ERR! A complete log of this run can be found in:
npm ERR! /home/spark/.npm/_logs/2023-07-15T07_29_36_570Z-debug-0.log

  1. npm uninstall @pinia
  2. npm cache clean --force
  3. rm -rf node_modules
  4. npm install @pinia

this will fix

if you get this error
npm ERR! code EINVALIDTAGNAME
npm ERR! Invalid tag name "@pinia" of package "@pinia": Tags may not have any characters that encodeURIComponent encodes.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/spark/.npm/_logs/2023-07-15T07_30_56_791Z-debug-0.log

add this again
rm -rf node_modules,
npm cache clean --force,
npm install

this will change the project pinia version if you are collabing change it with what is best to not get into other issue when hosting.

答案5

得分: -1

应该添加<script>标签。
组合 API 是必不可少的<script setup>。

英文:

You should be add <script> tag.
Composition API is essential <script setup>

huangapple
  • 本文由 发表于 2023年2月19日 11:15:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497775.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定