Wenn ich mehrmals suchen möchte, wird mir der NavigationDuplicated
Fehler angezeigt. Meine Suche befindet sich in der Navigationsleiste. Ich habe die Suche so konfiguriert, dass der Wert mithilfe eines Modells verwendet und dann als Parameter an die ContentSearched-Komponente übergeben wird. Anschließend wird der Wert der Suche in diesen Komponenten empfangen.
Ich weiß, dass der richtige Weg darin besteht, einen Emitter zu verwenden, aber ich weiß immer noch nicht, wie ich lernen soll, ihn zu verwenden. Um auf die Ausgabe zuzugreifen istcontext.emit('', someValue)
NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated", message: "Navigating to current location ("/search") is not allowed", stack: "Error↵ at new NavigationDuplicated (webpack-int…node_modules/vue/dist/vue.runtime.esm.js:1853:26)"}
NavBar.vue
<template>
<nav class="navbar navbar-expand-lg navbar-dark bg-nav" v-bind:class="{'navbarOpen': show }">
<div class="container">
<router-link to="/" class="navbar-brand">
<img src="../assets/logo.png" alt="Horizon Anime" id="logo">
</router-link>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" v-on:click.prevent="toggleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent" v-bind:class="{'show': show }">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<router-link class="nav-link" to="/" ><i class="fas fa-compass"></i> Series</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" :to="{name: 'EpisodesSection'}" ><i class="fas fa-compact-disc"></i> Episodios</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link" :to="{name: 'MovieSection'}" ><i class="fas fa-film"></i> Peliculas</router-link>
</li>
</ul>
<div class="search-bar">
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" v-model="query" type="search" placeholder="Buscar películas, series ..." aria-label="Search">
<button class="btn btn-main my-2 my-sm-0" @click.prevent="goto()" type="submit"><i class="fas fa-search"></i></button>
</form>
</div>
</div>
</div>
</nav>
</template>
<script>
import {value} from 'vue-function-api';
import {useRouter} from '@u3u/vue-hooks';
export default {
name: "NavBar",
setup(context){
const {router} = useRouter();
const query = value("");
let show = value(true);
const toggleNavbar = () => show.value = !show.value;
const goto = () =>{
let to = {name: 'ContentSearched' , params:{query: query}}
router.push(to);
};
return{
show,
toggleNavbar,
goto,
query
}
}
}
</script>
ContentSearched.vue
<template>
<div class="container">
<BoxLink/>
<main class="Main">
<div class="alert alert-primary" role="alert">
Resultados para "{{query}}"
</div>
<div v-if="isLoading">
<!-- <img class="loading" src="../assets/loading.gif" alt="loading"> -->
</div>
<div v-else>
<ul class="ListEpisodios AX Rows A06 C04 D02">
<li v-for="(content, index) in contentSearched" :key="index">
<div v-if="content.type === 'serie'">
<Series :series="content"/>
</div>
<div v-if="content.type === 'pelicula'">
<Movies :movies="content"/>
</div>
</li>
</ul>
</div>
</main>
</div>
</template>
<script>
import {onCreated} from "vue-function-api"
import {useState , useRouter , useStore} from '@u3u/vue-hooks';
import BoxLink from "../components/BoxLink";
import Movies from "../components/Movies";
import Series from "../components/Series";
export default{
name: 'ContentSearched',
components:{
BoxLink,
Movies,
Series
},
setup(context){
const store = useStore();
const {route} = useRouter();
const state = {
...useState(['contentSearched' , 'isLoading'])
};
const query = route.value.params.query;
onCreated(() =>{
store.value.dispatch('GET_CONTENT_SEARCH' , query.value);
});
return{
...state,
query,
}
}
};
</script>
quelle
$router.beforeEach'
Hook verwenden und in diesem verwenden,next(false)
um die Navigation zu beendenWenn Sie sich nicht wohl fühlen, wenn Sie alle Arten von Fehlern abfangen, ist diese Implementierung meiner Meinung nach rücksichtsvoller:
this.$router.push("path").catch(error => { if (error.name != "NavigationDuplicated") { throw error; } });
quelle
Wenn Sie router.push in Ihrem Code verwenden und sich nicht darum kümmern, dass die Navigation fehlschlägt, sollten Sie ihn mit catch abfangen:
router.push('/location').catch(err => {})
quelle
Ab 2020 globale Konfiguration:
Ich wollte nur
NavigationDuplicated
Fehler zum Schweigen bringen , ein leerer Fang kann gefährlich sein. Also habe ich das gemacht:const router = new VueRouter({/* ... */}) function patchRouterMethod (router, methodName) { router['old' + methodName] = router[methodName] router[methodName] = async function (location) { return router['old' + methodName](location).catch((error) => { if (error.name === 'NavigationDuplicated') { return this.currentRoute } throw error }) } } patchRouterMethod(router, 'push') patchRouterMethod(router, 'replace')
Fügen Sie dies einmal ein, wenn Sie den Vue-Router initialisieren.
quelle
im Handbuch:
Sie können einfacher verwenden
router.push("/", () => {});
quelle
Ich habe das gleiche Problem bei der Suche festgestellt. Meine Lösung besteht darin
timestamp
, diethis.$route.query
Parameter der Suchseite zu ergänzen .this.$router.push({ path: "/search", query: { q: this.searchQuery, t: new Date().getTime(), } });
Hoffe es hilft dir.
quelle
Sie haben hier mehrere Konzepte gemischt, von
router-link
s bis zur programmatischen Navigation, um Parameter in einem Statusspeicher abzufragen. Das macht es ein bisschen schwierig, Ihnen zu helfen und Ihnen zu sagen, was die "richtige" Lösung hier ist.Dennoch denke ich, dass der beste Ansatz für Sie darin besteht,
1) Ihre Route als zu definieren
{ path: "/search/:searchString", component: MySearchComponent, props: true }
2) Verwenden Sie ein Responsive
<router-link>
anstelle Ihresrouter.push
<input type="text" v-model="searchString"> <router-link :to="'/search/'+searchString" tag="button">search</router-link>
3) Zugriff auf die
searchString
in Ihrer Suchkomponente überprops: ['searchString']
undthis.searchString
props: ['searchString'], ... computed: { msg() { return `Searching for, ${this.searchString}!`; } }
Vollständiges Beispiel: https://codesandbox.io/s/vue-routing-example-9zc6g
Hinweis: Ich habe gerade die erste Codesandbox mit einem Gabel gegabelt, den
router
ich finden konnte, und entsprechend angepasst .quelle
Hier ist eine einfache und effiziente Lösung:
if(from.fullPath === to.fullPath){ return }
quelle