Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 导航不允许重复导航到当前位置(“搜索”)_Javascript_Vue.js_Vuejs2 - Fatal编程技术网

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>