vue前台(二)解决编程式路由,多次点击,报错的问题

描述: 编程式路由跳转到当前路由(参数不变), 会抛出NavigationDuplicated的警告错误
              声明式路由跳转内部已经处理

                

        原因:vue-router3.1.0之后, 引入了push()的promise的语法
             如果没有通过参数指定成功或者失败回调函数就返回一个promise来指定成功/失败的回调
             且内部会判断如果要跳转的路径和参数都没有变化, 会抛出一个失败的promise

        解决: 1:在跳转时指定成功或失败的回调函数, 或者catch处理错误
              2: 修正Vue原型上的push和replace方法 (优秀)

 

 

header.vue

html部分

<div class="searchArea">
        <form action="###" class="searchForm">
          <input type="text" id="autocomplete" class="input-error input-xxlarge" v-model="keyword"/>
          <button class="sui-btn btn-xlarge btn-danger" type="button" @click="toSearch">搜索</button>
        </form>
      </div>

 

js部分

data(){
    return {
      keyword:''
    }
  },
  methods:{
    toSearch(){
      //字符窜写法,用的不多
      // this.$router.push(`/search/${this.keyword}?keyword=${this.keyword.toUpperCase()}`)

      // 如果使用对象:
      // 传递params参数必须和name配合
      // path和params无法配合使用
      // path和query是可以使用的
      // name和query也是可以的
      // 以后尽量写name
      this.$router.push({
        // path:'/search',
        name:'search',
        query:{
          keyword1:this.keyword.toUpperCase()
        },
        params:{
          //如果传递params参数是一个空串,那么路径会有问题,传过去如果是undefined就没事
          keyword:this.keyword || undefined
        }
      }) //.catch(()=>{})用来处理多次push点击报错问题,但是不能一劳永逸

      
    
  }

方法一:直接在后面加.catch(()=>{}), 因为push()返回的是一个promise

方法二,直接在VueRouter的原型中添加方法,解决

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)


//终极解决多次触发push或者repalce,报错的问题
//NavigationDuplicated

const originPush = VueRouter.prototype.push
const originReplace = VueRouter.prototype.replace

VueRouter.prototype.push = function(location,onResolved,onRejected){
  if(onResolved === undefined && onRejected === undefined){
    // originPush.call目的是让VueRouter实例化对象去调用
    //如果不加,那就是window在调用
    return originPush.call(this,location).catch(() => {})
  }else{
    return originPush.call(this,location,onResolved,onRejected)
  }
}

VueRouter.prototype.replace = function(location,onResolved,onRejected){
  if(onResolved === undefined && onRejected === undefined){
    // originPush.call目的是让VueRouter实例化对象去调用
    //如果不加,那就是window在调用
    return originReplace.call(this,location).catch(() => {})
  }else{
    return originReplace.call(this,location,onResolved,onRejected)
  }
}


import routes from '@/router/routes'

export default new VueRouter({
  routes
})

 

原因:vue-router3.1.0之后, 引入了push()的promise的语法
如果没有通过参数指定成功或者失败回调函数就返回一个promise来指定成功/失败的回调
且内部会判断如果要跳转的路径和参数都没有变化, 会抛出一个失败的promise

 

 

二定义home内部的组件

在home内部定义这些非路由组件 brand,floor, like, listcontainer,rank,recommend,typenav, 注意要拷贝图片过来

其中typenav,商品分类导航组件,search组件也要用到,将typenav弄到components中去复用, 在main.js中全局注册

// 引入公共组件typenav
import  TypeNav  from '@/components/TypeNav'
Vue.component('TypeNav', TypeNav)

 

 

 

 

 

 

 
 
posted @ 2020-07-16 09:41  全情海洋  阅读(1102)  评论(0编辑  收藏  举报