Saltar al contenido

¿Cómo enviar a vue-router sin agregar al historial?

Solución:

Hay una manera perfecta de manejar esta situación.

Puede utilizar la protección en el componente para controlar la ruta en el nivel de gránulos

Realice los siguientes cambios en su código

En el componente de la pantalla principal

Agregue este beofreRouteLeave guard en las opciones del componente, antes de salir a la ‘pantalla de resultados’, está configurando la ruta para que pase solo por la pantalla de carga

beforeRouteLeave(to, from, next) {
   if (to.path == "/result") {
      next('/loading')
    }
    next();
  }, 

En el componente de la pantalla de carga

Si la ruta vuelve del resultado a la carga, no debería aterrizar aquí y saltar directamente a la pantalla principal.

beforeRouteEnter(to, from, next) {
    if (from.path == "/result") {
      next('/main')
    }
     next();
  },

En la pantalla de carga, el guardia beforeRouteEnter NO tiene acceso a esto, porque se llama al guardia antes de que se confirme la navegación, por lo que el nuevo componente de entrada aún no se ha creado. Entonces, aprovechando esto, no recibiré las llamadas infinitas disparado al enrutar desde la pantalla de resultados

En el componente de pantalla de resultados

si usa volver, entonces no debería aterrizar en la carga y saltar directamente a la pantalla principal

beforeRouteLeave(to, from, next) {
    if (to.path == "/loading") {
      next("https://foroayuda.es/")
    }
    next();
  },

Acabo de crear una pequeña aplicación vue para reproducir el mismo problema. Funciona en mi local según su pregunta. Espero que resuelve tu problema así como.

Esta es una decisión difícil considerando lo poco que sabemos sobre lo que ocurre en su ruta de carga.

Pero…

Nunca tuve la necesidad de construir una ruta de carga, solo cargar componentes que se procesan en múltiples rutas durante la etapa de inicio / recopilación de datos.

Un argumento para no tener una ruta de carga sería que un usuario podría navegar directamente a esta URL (accidentalmente) y luego parece que no tendría suficiente contexto para saber dónde enviar al usuario o qué acción tomar. Aunque esto podría significar que se cae a una ruta de error en este punto. En general, no fue una gran experiencia.

Otra es que si simplifica sus rutas, la navegación entre rutas se vuelve mucho más simple y se comporta como se espera / desea sin el uso de $router.replace.

Entiendo que esto no resuelve la pregunta de la forma en que lo hace. Pero sugiero repensar esta ruta de carga.

Aplicación

<shell>
    <router-view></router-view>
</shell>

const routes = [
  { path: "https://newbedev.com/", component: Main },
  { path: '/results', component: Results }
]

const router = new VueRouter({
  routes,
})

const app = new Vue({
  router
}).$mount('#app')

Cascarón

<div>
    <header>
        <nav>...</nav>
    </header>
    <main>
        <slot></slot>
    </main>
</div>

Pagina principal

<section>
    <form>...</form>
</section>

{
    methods: {
        onSubmit() {
            // ...

            this.$router.push('/results')
        }
    }
}

Página de resultados

<section>
    <error v-if="error" :error="error" />
    <results v-if="!error" :loading="loading" :results="results" />
    <loading v-if="loading" :percentage="loadingPercentage" />
</section>

{
    components: {
        error: Error,
        results: Results,
    },
    data() {
        return {
            loading: false,
            error: null,
            results: null,
        }
    },
    created () {
        this.fetchData()
    },
    watch: {
        '$route': 'fetchData'
    },
    methods: {
        fetchData () {
            this.error = this.results = null
            this.loading = true

            getResults((err, results) => {
                this.loading = false

                if (err) {
                    this.error = err.toString()
                } else {
                    this.results = results
                }
            })
        }
    }
}

Componente de resultados

Básicamente, el mismo componente de resultados que ya tiene, pero si loading es cierto, o si results es nulo, como lo prefiera, puede crear un conjunto de datos falso para iterar y crear versiones de esqueleto, si lo desea. De lo contrario, puede mantener las cosas como las tiene.

creo router.replace es el camino a seguir, pero aún hay algunas líneas de pensamiento (no probadas):


Básicamente en $router cambiar renderiza el componente de carga hasta que emite load:stop, luego hace que el router-view


import { Vue, Component, Watch, Prop } from "vue-property-decorator";

@Component<RouteLoader>({
    render(h){
        const rv = (this.$slots.default || [])
        .find(
            child => child.componentOptions
            //@ts-ignore 
            && child.componentOptions.Ctor.extendedOptions.name === "RouterView"
        )
        if(rv === undefined) 
            throw new Error("RouterView is missing - add <router-view> to default slot")

        const loader = (this.$slots.default || [])
        .find(
            child => child.componentOptions
            //@ts-ignore 
            && child.componentOptions.Ctor.extendedOptions.name === this.loader
        )
        if(loader === undefined) 
            throw new Error("LoaderView is missing - add <loader-view> to default slot")
        const _vm = this 
        const loaderNode = loader.componentOptions && h(
            loader.componentOptions.Ctor,
            {
                on: {
                    // "load:start": () => this.loading = true,
                    "load:stop": () => _vm.loading = false
                },
                props: loader.componentOptions.propsData,
                //@ts-ignore
                attrs: loader.data.attrs
            }
        )
        return this.loading && loaderNode || rv
    }
})
export default class RouteLoader extends Vue {
    loading: boolean = false
    @Prop({default: "LoaderView"}) readonly loader!: string
    @Watch("$route")
    loads(nRoute: string, oRoute: string){
        this.loading = true
    }
}

@Component<Loader>({
    name: "LoaderView",
    async mounted(){

        await console.log("async call")
        this.$emit("load:stop")
        // this.$destroy()
    }
})
export class Loader extends Vue {}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *