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

442
Views
Vue 3: espere hasta que el padre termine con la obtención de datos para obtener datos secundarios y mostrar el cargador

Estoy buscando una forma reutilizable de mostrar un cargador de página completa (la barra lateral siempre está visible, pero el cargador debe cubrir la parte del contenido de la página) hasta que se hayan realizado todas las recuperaciones de API necesarias.

Tengo un componente principal LaunchDetails envuelto en un componente PageLoader

LaunchDetails.vue

 <template> <PageLoader> <router-link :to="{ name: 'launches' }"> Back to launches </router-link> <h1>{{ name }}</h1> <section> <TabMenu :links="menuLinks" /> </section> <section> <router-view /> </section> </PageLoader> </template> <script> import TabMenu from "@/components/general/TabMenu"; export default { data() { return { menuLinks: [ { to: { name: "launchOverview" }, display_name: "Overview" }, { to: { name: "launchRocket" }, display_name: "Rocket" }, ], }; }, components: { TabMenu, }, created() { this.$store.dispatch("launches/fetchLaunch", this.$route.params.launch_id); }, computed: { name() { return this.$store.getters["launches/name"]; }, }, }; </script>

PageLoader.vue

 <template> <Spinner v-if="isLoading" full size="medium" /> <slot v-else></slot> </template> <script> import Spinner from "@/components/general/Spinner.vue"; export default { components: { Spinner, }, computed: { isLoading() { return this.$store.getters["loader/isLoading"]; }, }, }; </script>

La plantilla LaunchDetails tiene otra vista de enrutador. En estas páginas secundarias, se realizan nuevas solicitudes de recuperación en función de los datos de las solicitudes de LaunchDetails .

RocketDetails.vue

 <template> <PageLoader> <h2>Launch rocket details</h2> <RocketCard v-if="rocket" :rocket="rocket" /> </PageLoader> </template> <script> import LaunchService from "@/services/LaunchService"; import RocketCard from "@/components/rocket/RocketCard.vue"; export default { components: { RocketCard, }, mounted() { this.loadRocket(); }, data() { return { rocket: null, }; }, methods: { async loadRocket() { const rocket_id = this.$store.getters["launches/getRocketId"]; if (rocket_id) { const response = await LaunchService.getRocket(rocket_id); this.rocket = response.data; } }, }, }; </script>

Lo que necesito es una forma de obtener datos en el componente principal ( LaunchDetails ). Si estos datos se almacenan en la tienda vuex, el componente secundario ( LaunchRocket ) obtiene los datos necesarios de la tienda y ejecuta las solicitudes de recuperación. Mientras se hace esto, me gustaría tener un cargador de página completa o un cargador de página completa mientras se carga el componente principal y un cargador que contenga el lienzo anidado.

En este punto, la tienda vuex realiza un seguimiento de una propiedad isLoading , manejada con interceptores axios.

Todo el código es visible en este sandbox

(Nota: en este ejemplo, podría obtener el rocket_id de la URL, pero este no será el caso en mi proyecto, por lo que realmente estoy buscando una manera de obtener estos datos de la tienda vuex)

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Le presento a su salvador Suspense , esta función se ha agregado en vue v3 pero aún es una función experimental. Básicamente, cómo funciona, crea un suspenso en el componente principal y puede mostrar una carga cuando se resuelve todo el componente en cualquier profundidad de su aplicación. Tenga en cuenta que sus componentes deben ser un componente asíncrono, lo que significa que debe cargarse de forma perezosa o hacer que su función de configuración (api de composición) sea una función asíncrona para que devuelva un componente asíncrono, de esta manera puede obtener sus datos en el componente secundario y en el padre mostrar una reserva si es necesario.

Más información:https://v3.vuejs.org/guide/migration/suspense.html#introduction

over 4 years ago · Santiago Trujillo Report

0

Podrías usar Eventos:

 var Child = Vue.component('child', { data() { return { isLoading: true } }, template: `<div> <span v-if="isLoading">Loading &hellip;</span> <span v-else>Child</span> </div>`, created() { this.$parent.$on('loaded', this.setLoaded); }, methods: { setLoaded() { this.isLoading = false } } }); var Parent = Vue.component('parent', { components: { Child }, data() { return { isLoading: true } }, template: `<div> Parent <Child /> </div>`, mounted() { let request1 = new Promise((resolve, reject) => { setTimeout(resolve, 1000); }); let request2 = new Promise((resolve, reject) => { setTimeout(resolve, 2000); }); Promise.all([ request1, request2 ]).then(() => this.$emit('loaded')) } }); new Vue({ components: { Parent }, el: '#app', template: `<Parent />` });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"></div>

Esto puede considerarse un antipatrón, ya que une al padre con el hijo y se considera que los eventos se envían al revés. Si no quiere usar eventos para eso, una propiedad observada también funciona bien. La emisión de eventos que no son padre-hijo se eliminó en Vue 3, pero se puede implementar usando bibliotecas externas .

over 4 years ago · Santiago Trujillo 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!