Vue中关于路由的几点


路由组件与非路由组件的区别:   
1.两者存放的位置不同components存非路由组件,pages存路由组件
2.使用方式不同。路由组件需要用vue-router,非路由用标签
3.注册完路由,非路由和路由都有$router,$route
$route:一般获取路由信息【路径,query参数,params等】
$router:一般进行编程式导航进行路由跳转【push|replace】

路由的跳转:

1、声明式导航:router-link进行跳转
2、编程式导航:push|replace 跳转
声明式能做的编程式也能做,编程式除了路由跳转还可以做一些其他业务逻辑

控制路由组件的显隐

1 我们可以根据组件身上的$router获取当前路由的信息,通过路径判断是否相等显示与隐藏 this.$router.path ==="/home/user"
2 配置路由的时候可以给路由添加路由元信息(meta),在里面添加属性,然后标签上判断显隐(页脚组件在注册登录组件不显示)
html:
    <Footer v-show="$route.meta.show">Footer>
router-index.js:
    export default new vueRouter({
            routes:[    
                {
                  path:'/home',
                  component:()=> import('@/pages/Home'),
                  meta:{show:true}
                },
               {
                 path:'/login',
                 component:()=> import('@/pages/Login'),
                 meta:{show:false}
              },
            ]
    })    

路由传参:

  参数有两种写法:querys和params 

// 第一种 字符串形式
// this.$router.push('/search/'+this.keyWord+'?k='+this.keyWord.toUpperCase())
// 第二种 模板字符串 需要在router-index里对路径进行修改
// this.$router.push(`/search/${this.keyWord}?k=${this.keyWord.toUpperCase()}`)
// 对象形式 需要在router-index加上name属性
//this.$router.push({name:'search',query:{k:this.keyWord.toUpperCase()},params:{keyword:this.keyWord}}

关于路由传参的几个问题:

//  1.如何指定params参数传参或不传
//      如果路由指定传参,但不传,路由跳转的url会有问题
//      如何指定params参数可传可不传:在配置路由时在占位的后面加个?(path:'/search/key?')
//  2.params可传可不传,若传的是空串该如何解决?
//      使用undefined解决
 //      this.$router.push({name:'search',query:{k:this.keyWord.toUpperCase()},params:{keyword:'' || undefined}})
//  3.路由组件能不能传递props数据?
     1.布尔值写法
           router-index.js中加上props:true(只能传params参数)                                                                         
            this.$router.push({name:'search',query:{k:this.keyWord.toUpperCase()},params:{keyword:this.keyWord}})
         2.对象写法
           router-index.js中加上props:{a:1,b:2}(给路由传递一些额外的数据)
         3.函数写法
             可以把params,query参数通过props传递
               router-index.js中加上props:($route)=>{return ({query:$route.params.keyword,params:$route.params.keyword})
              }
    4、编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误
       原因:最新的vue-router引入promise,有两个回调函数(resolve和reject)
                  1.通过给push方法传递相应的成功。失败回调函数,可以捕获到当前的错误,可以解决             //    2.通过底部代码,可以实现解决错误             //      this.$router.push({name:'search',query:{k:this.keyWord.toUpperCase()},params:{keyword:this.keyWord}},()=>{},()=>{})             //      这种写法治标不治本,将来在别的组件push|replace,编程式导航还有类似错误             //      this:当前组件实例对象             //      this.$router:属性值是vueRouter类的一个实例,在入口文件注册路由时,给组件添加$router|$route属性             //      push:vueRouter类的一个实例             //      要在router-index.js里重写push和replace方法



重写$router.push和replace方法
import Vue from 'vue'
import vueRouter from 'vue-router'
//使用路由组件
 Vue.use(vueRouter)
 // 先把vueRouter的原型对象的push|replace保存一份
 console.log(vueRouter.prototype);
 let originPush = vueRouter.prototype.push
 let originReplace = vueRouter.prototype.replace
 //   重写push|replace
 //   第一个参数:往哪里跳转
 vueRouter.prototype.push = function(location,resolve,reject){//不要用箭头函数
    if(resolve && reject){
       //call|apply区别
       //相同:都可以调用函数一次,都可以篡改函数的上下文一次
       //不同: call和apply传递参数,call的参数用逗号分割,apply传递数组
       originPush.call(this,location,resolve,reject)
    }else{
       originPush.call(this,location,()=>{},()=>{})
    }
 }
 vueRouter.prototype.replace = function(location,resolve,reject){
   if(resolve && reject){
      originReplace.call(this,location,resolve,reject)
   }else{
      originReplace.call(this,location,()=>{},()=>{})
   }
}
export default new vueRouter({})