Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

232
Views
¿Necesito importar accesorios de la tienda Pinia varias veces en un componente Vue?

Estoy trabajando en mi primer proyecto Vue. Estoy acostumbrado a React y vanilla js, pero solo me estoy dando cuenta de algunos conceptos en Vue aquí.

En particular, importar accesorios de estado y acción de una tienda Pinia, y aparentemente tener que importarlos varias veces en un solo componente Vue (algo que no necesito hacer en React).

En este ejemplo, estoy importando un valor de conteo simple y una función de incremento, y trato de usarlos en algunos lugares diferentes:

 <script setup> // I import everything initially in setup, which works fine, // and these props (currentCount and incrementCount) // can be used in my template: import { storeToRefs } from 'pinia'; import { useStore } from '@/stores/store'; const { currentCount } = storeToRefs(useStore()); const { incrementCount } = useStore(); </script> <template> <main> Current count: {{ currentCount }} <button @click="incrementCount">Increment</button> </main> </template> <script> // I can't use store values from setup here. // This doesn't work: // console.log(currentCount); // I also can't import store values here. // I get the following error: // "getActivePinia was called with no active Pinia" // const { currentCount } = storeToRefs(useStore()); export default { mounted() { // I have to import store values here for them to work: const { currentCount } = storeToRefs(useStore()); console.log(currentCount); }, watch: { // weirdly, this reference to watching "currentCount" works: currentCount() { // I also have to import store values here for them to work: const { currentCount } = storeToRefs(useStore()); console.log(currentCount); }, }, }; </script>

Como puede ver, si quiero usar los valores de la tienda en mi plantilla, en el montaje y en un observador (por lo que usaría el gancho useEffect de React), tengo que importar los accesorios de la tienda 3 veces en total.

¿Es esto correcto/normal? ¿Existe una forma más sencilla de lograr lo que estoy haciendo, en la que solo importe accesorios una vez? Quiero estar seguro de que no me he perdido algo y no estoy haciendo algo de una manera inusual.

¡Gracias por cualquier ayuda y consejo!

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Pinia se diseñó teniendo en cuenta la API de composición.
Por lo tanto, su uso previsto está dentro de la función setup() , donde solo lo importaría una vez.

Para usarlo fuera de una función de setup() , tiene dos rutas principales:

  • dentro de los componentes, puede simplemente devolverlo desde setup() y estará disponible en cualquier gancho/método/captador. Ya sea como this.store o spread:
 import { useStore } from '@/store' import { toRefs } from 'vue' // or from '@vue/composition-api' in Vue2 export default { setup: () => ({ ...toRefs(useStore()) }) } /* this makes every state prop, getter or action directly available on current component instance. In your case, `this.currentCount`. Obviously, you can also make the entire store available as `this.someStore`: setup: () => ({ someStore: useSomeStore() }) // now you can use `this.someStore` anywhere */
  • un enfoque más general es exportar la instancia de pinia (devuelta por createPinia() ), desde main.(js|ts) , importarla donde necesite la tienda y luego llamar a useStore() pasando la instancia de pinia como argumento.
    Esto se puede hacer en cualquier lugar, incluso fuera de los componentes.
    Ejemplo genérico:
 import { pinia } from 'main.js' import { useSomeStore } from '@/store' const someStore = useSomeStore(pinia);

Probablemente también debería mencionar el ayudante de mapState proporcionado por pinia . Le permite seleccionar solo algunas de las claves expuestas a la instancia actual. Ejemplo:

 import { mapState } from 'pinia' // ... computed: { ...mapState(useSomeStore, [ 'currentCount']) } // Now `this.currentCount` is available

Nota: mapState tiene un nombre extraño, ya que le permite acceder a más que solo accesorios de state (también getters y actions ). Fue nombrado mapState para que coincida con el asistente similar de vuex .


Un enfoque aún más general es agregar su tienda como global, utilizando la API de registro de complementos en Vue2:

 import { useSomeStore } from '@/store'; import { createPinia } from 'pinia'; const pinia = createPinia(); const someStorePlugin = { install(Vue, options) { Vue.prototype.someStore = useSomeStore(options.pinia) } }; Vue.use(someStorePlugin, { pinia }); new Vue({ pinia });

Después de esto, cada componente de su instancia de Vue tendrá this.someStore disponible, sin necesidad de importarlo.

Nota: no he probado agregar una tienda en globales (y definitivamente desaconsejo hacerlo; debe evitar los globales), pero espero que funcione.

about 4 years ago · Juan Pablo Isaza Report

0

Si desea combinar las tiendas pinia con la API de opciones, una forma de hacerlo es usar la función setup() dentro de las opciones para llamar a useStore :

 <script> import { useStore } from '@/stores/store'; export default { setup() { const store = useStore(); return {store} }, watch: { store.currentBrightness(newVal, oldVal){ // your code } }, methods: { // inside methods use this.store }, mounted() { console.log(this.store.currentCount); } } </script>

Algunos podrían considerar esto como una mezcla no deseada de API de composición y opciones, pero en mi opinión, es una solución bastante buena para las tiendas pinia.

about 4 years ago · Juan Pablo Isaza Report

0

Nechoj, tiene la respuesta más directa. Además, si tiene varias tiendas, siempre puede importar las tiendas según sea necesario en un componente principal y luego usar inyectar solo agregar algunas partes. Por ejemplo, tengo una ruta de datos que se llama a través de una API, no la necesito en todas partes todo el tiempo, así que la llamo a un padre y luego uso inyectar para usar esas rutas en un menú desplegable que podría ser un bisnieto componente. No necesito toda esa tienda de utilidades, solo las rutas. Página de inicio:

 import { useUtilsStore } from "src/stores/utilsStore"; const passengerRoutes = computed(() => utilsStore.getPassengerRoutes); provide("passengerRoutes", passengerRoutes);

componente nieto:

 const compRoutes = inject("passengerRoutes");
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!