Javascript 导航不允许重复导航到当前位置(“搜索”)
当我想多次搜索时,它会显示Javascript 导航不允许重复导航到当前位置(“搜索”),javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,当我想多次搜索时,它会显示NavigationDuplicated错误。我的搜索在导航栏中,我配置搜索的方式是使用模型获取值,然后将值作为参数传递给ContentSearched组件,然后在该组件中接收搜索值 我知道正确的方法是使用发射器,但我仍然不知道如何学习使用它。要访问emit是上下文。emit(“”,someValue) NavigationDuplicated{u name:“NavigationDuplicated”,name:“NavigationDuplicated”,消息:“不
NavigationDuplicated
错误。我的搜索在导航栏中,我配置搜索的方式是使用模型获取值,然后将值作为参数传递给ContentSearched组件,然后在该组件中接收搜索值
我知道正确的方法是使用发射器,但我仍然不知道如何学习使用它。要访问emit是上下文。emit(“”,someValue)
NavigationDuplicated{u name:“NavigationDuplicated”,name:“NavigationDuplicated”,消息:“不允许导航到当前位置(“/search”),堆栈:“错误”↵ 在新的NavigationDuplicated(webpack-int…node_modules/vue/dist/vue.runtime.esm.js:1853:26)“}
导航栏.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>
-
系列
-
情节
-
贝壳
从“vue函数api”导入{value};
从'@u3u/vue hooks'导入{useRouter};
导出默认值{
名称:“导航栏”,
设置(上下文){
const{router}=useRouter();
常量查询=值(“”);
让显示=值(真);
const toggleNavbar=()=>show.value=!show.value;
const goto=()=>{
let to={name:'ContentSearched',参数:{query:query}
路由器。推(到);
};
返回{
显示
toggleNavbar,
后藤,
查询
}
}
}
ContentSearched.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>
Resultados para“{query}”
-
从“vue函数api”导入{onCreated}
从'@u3u/vue hooks'导入{useState,useRouter,useStore};
从“./组件/BoxLink”导入BoxLink;
从“./组件/电影”导入电影;
从“./组件/系列”导入系列;
导出默认值{
名称:'ContentSearched',
组成部分:{
BoxLink,
电影,,
系列
},
设置(上下文){
const store=useStore();
const{route}=useRouter();
常量状态={
…useState(['contentSearched','isLoading'])
};
const query=route.value.params.query;
onCreated(()=>{
store.value.dispatch('GET\u CONTENT\u SEARCH',query.value);
});
返回{
……国家,
查询
}
}
};
您在这里混合了多个概念,从路由器链接到编程导航,再到查询状态存储的参数。这使得帮助您并告诉您这里的“正确”解决方案有点困难
尽管如此,我认为最好的方法是:
1) 将您的路线定义为
{
path: "/search/:searchString",
component: MySearchComponent,
props: true
}
2) 使用响应式
而不是路由器。按
<input type="text" v-model="searchString">
<router-link :to="'/search/'+searchString" tag="button">search</router-link>
完整示例:
注意,我刚刚用一个路由器分叉了第一个代码沙盒
,我可以找到,并相应地调整。如果您使用的是路由器。推入您的代码,并且您不关心导航失败,您应该使用catch:
router.push('/location').catch(err => {})
我认为,如果我们不打算进一步使用Router.push作为异步调用,那么最好的解决方案可以在根标签上解决
import Router from 'vue-router';
const originalPush = Router.prototype.push;
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
};
Vue.use(Router);
这发生在我身上,当时我有一个路由器链接
指向同一条路由。e、 g./products/1
用户可以单击产品,但是如果产品已被单击(并且组件视图已加载)并且用户尝试再次单击,则控制台中将显示错误/警告
你可以学到更多
vue路由器的主要贡献者之一Posva建议:
router.push('your-path').catch(err=>{})
但是,如果您不想让catch
块什么也不做,为了解决这个问题,您可以将路由器导航与当前路由进行比较,并且仅在它们不同时进行导航:
const path = `/products/${id}`
if (this.$route.path !== path) this.$router.push(path)
注意:$route
是vue路由器向每个组件提供的对象。有关更多信息,请参阅。如果您对捕获所有类型的错误感到不舒服,我认为此实现更为周到:
this.$router.push("path").catch(error => {
if (error.name != "NavigationDuplicated") {
throw error;
}
});
以下是一个简单高效的解决方案:
if(from.fullPath === to.fullPath){
return
}
在手册中:
router.push(location, onComplete?, onAbort?)
你可以更简单地使用
router.push("/", () => {});
我在搜索时遇到了同样的问题。我的解决方案是在搜索页面的this.$route.query
参数中添加时间戳
this.$router.push({
path: "/search",
query: {
q: this.searchQuery,
t: new Date().getTime(),
}
});
希望它能帮助您。从2021年起,全球配置:
我只想消除导航重复的错误,空捕获可能是危险的。所以我这样做了:
const router=new VueRouter({/*…*/})
const originalPush=router.push
router.push=功能推送(位置、onResolve、onReject)
{
if(onResolve | | onReject){
返回originalPush.call(this、location、onResolve、onReject)
}
返回originalPush.call(此,位置).catch((err)=>{
if(VueRouter.isNavigationFailure(err)){
返回错误
}
返回承诺。拒绝(错误)
})
}
在初始化vue路由器时插入此命令一次。
感谢@Oleg Abrazhaev的更新。我的解决方案是将扩展原型
与检查导航重复错误
相结合。其他错误和警告应可见。过了一会儿,我们
import { equals } from 'ramda'
export function register(Vue) {
const routerPush = Router.prototype.push
const routerReplace = Router.prototype.push
const isNavigationDuplicated = (currentRoute, nextRoute) => {
const { name: nextName, params: nextParams = {}, query: nextQuery = {} } = nextRoute
const { name, params, query } = currentRoute
return equals(nextQuery, query) && equals(nextParams, params) && equals(nextName, name)
}
Router.prototype.push = function push(location) {
if (!isNavigationDuplicated(this.currentRoute, location)) {
return routerPush.call(this, location)
}
}
Router.prototype.replace = function replace(location) {
if (!isNavigationDuplicated(this.currentRoute, location)) {
return routerReplace.call(this, location)
}
}
Vue.use(Router)
}
<template>
<div>searching ...</div>
</template>