Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

233
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda