1.$route与$router的区别
$route: 一般获取路由信息【路径、query、params等】
$router:一般进行编程式导航进行路由跳转【push、replace】

2. 路由的跳转方式
声明式导航:router-link 使用to跳转
编程式导航:$router.push/replace`

3. 路由传参
params参数:属于路径当中的一部分,在配置路由的时候,需要占位
query参数:不属于路径当中的一部分,不需要占位

// 路由传参例子

// 第一种字符串形式, 需要在路由处加上 /:keyword
this.$router.push("/search/" + this.keyword + "?k=" + this.keyword.toUpperCase())
// 第二种:模板字符串
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)
// 第三种:对象
this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})

4. 路由面试题
面试题1:路由传递参数(对象写法)path是否可以结合params参数一起使用? ----不能
答:路由跳转传递参数时,对象写法可以是name、path的形式,但是path这种写法不能与params参数一起使用

//正确
this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
//
错误this.$router.push({path:"/search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})

面试题2:如何指定params参数可传可不传?

出现问题:若路由要求传递params参数(即 path: "/search/:keyword ),
但是未传递params参数(this.$router.push({name:"search",query:{k:this.keyword.toUpperCase()}})),
那么路径会出现问题:http://localhost:8080/#/?k=11
正确路径:http://localhost:8080/#/search/
答:在配置路由时,在占位的后面加上一个问号,即( path: "/search/:keyword? )



面试题3:params参数可以传递也可以不传递,但是如果传递是空串,如何解决?

出现问题:若传递的是空串,路径会出现问题:http://localhost:8080/#/?k=111
答:使用undefined解决

this.$router.push({name:"search",params:{keyword:''||undefined},query:{k:this.keyword.toUpperCase()}})`

面试题4:路由组件能不能传递props数据?   ---不常用
答:可以,三种写法

{
path: "/search/:keyword?",
name: "search",
component: () => import("@/pages/Search/index1.vue"),
meta: {show: true},
// 路由组件能不能传递props数据? -- 可以
// 布尔值写法 params
// props:true,
// 对象写法:额外给路由组件传递一些props
// props:{a:1,b:2}
//函数写法:可以把params参数和query参数,通过props传递给路由组件
// props:($route)=>{
// return {keyword:$route.params.keyword,k:$route.query.k}
// }
},

编程式导航跳转到当前路由(参数不变),多次执行会抛出 NavigationDuplicated 的警告错误---最新的vue-router引入了promise
声明式导航没有这类问题,因为vue-router底层已经处理好了
通过给push方法传递相应的成功、失败的回调函数,可以捕获到当前的错误,可以解决

this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}},()=>{},()=>{})

但是这种写法治标不治本------可以重写push和replace方法,如下在router.js中:

//先把VueRouter原型对象的push保留一份
`let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace`

//再重写push|replace
//第一个参数:告诉原来push方法,你往哪里跳转(传递哪些参数)
//第二个参数:成功的回调
//第三个参数:失败的回调
VueRouter.prototype.push = function(location,resolve,reject){
    console.log(this)
    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,()=>{},()=>{})
    }
}

此时多次执行不会抛出**NavigationDuplicated**的警告错误
this.$router.push({name:"search",params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})

this:当前组件实例
this.$router:当前的这个属性,属性值VueRouter类的一个实例,当在入口文件注册路由的时候,给组件实例添加$router|$route
push:VueRouter类的一个实例, VueRouter原型上的一个方法 VueRouter.prototype.push

Logo

前往低代码交流专区

更多推荐