3.1 路由组件与非路由组件的区别?
1.放置的位置不同:路由组件一般放置在pages文件夹中,非路由组件一般放置在components文件夹中。
2.使用的形式不同:路由组件一般需要在router文件夹中注册,非路由组件一般是以标签的形式使用。
3.相同点:路由注册完成以后,不管是路由组件,还是非路由组件,他们身上都有$route和$router属性。$route一般用来获取路由信息(路径,query参数、params参数等),$router一般进行编程式路由导航跳转(push、replace等)。
3.2 路由跳转的两种形式。
1.声明式路由导航:使用router-link标签进行路由的跳转。
2.编程式路由导航:使用$router的push/replace方法进行跳转。
区别:编程式路由导航除了可以进行页面跳转,还可以进行一些业务逻辑。
3.3 路由传参的两种形式
1.params参数:属于路径中的一部分,注意点:在配置路由时需要占位
routes:[
{
//占位
path:'/search/:keyword',
name:'search',
component:Search
}
]
2.query参数:不属于路径中的一部分。
3.4 路由传参的三种写法
给search组件以params参数传递keyword和以query参数传递k为例
1.字符串写法
this.$router.push('/search/' + this.keyword + '?k=' + this.keyword.toUpperCase())
2.模板字符串写法
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)
3.对象写法(常用)
this.$router.push({
name:'search',
params:{keyword:this.keyword},
query:{k:this.keyword.toUpperCase()}
})
3.5 有关路由的面试题
1.路由传递参数(对象写法)path是否可以结合params参数一起使用?
答:params参数不能和path一起使用,params参数只能和name一起使用;query参数可以和name或path一起使用。
2.如何指定params参数可传可不传?
答:当指定了params参数的占位后,如果不传递params参数,会导致URL路径发生错误。解决方法:在指定占位时在最后加上问号(?),就可以解决不传递params,URL路径错误问题
routes:[
{
//占位后面加上问号
path:'/search/:keyword?',
name:'search',
component:Search
}
]
但是如果params参数传递的是空的字符串。上述加问号的方式还是不能解决URL路径错误问题。解决方法:在跳转时,参数传递使用undefined
this.$router.push({
name:'search',
//使用undefined
params:{keyword: '' || undefined},
query:{k: this.keyword.toUpperCase()}
})
3.路由组件能不能传递props参数?
答:能,传递的props参数通过组件中配置props属性接收即可使用。有三种方式,需要在路由文件中配置
1.第一种:布尔值形式,默认只能接收params参数
routes:[
{
path:'/search/:keyword?',
name:'search',
component:Search,
//布尔值形式
props:true
}
]
2.第二种:对象形式,可以给组件传递额外的值
routes:[
{
path:'/search/:keyword?',
name:'search',
component:Search,
//对象形式
props:{a:100,b:200}
}
]
3.第三种:函数形式(较常用),函数的参数可以获取到$route,进而可以获取params和query
routes:[
{
path:'/search/:keyword?',
name:'search',
component:Search,
//函数形式
props:($route) => {
return{
keyword:$route.params.keyword,
k:$route.query.k
}
}
}
]
3.6 编程式路由导航跳转时(参数不变),为什么多次执行会抛出NavigationDuplicated异常?怎么解决?
答:在vue-router的底层使用了promise来处理异常,当多次点击时抛出异常是vue的设计。
解决方法1(治标不治本,没有影响底层源码)
在调用push或replace方法跳转路由时,传递两个空箭头函数
this.$router.push({
name:'search',
params:{keyword:this.keyword},
query:{k:this.keyword.toUpperCase()},
},()=>{},()=>{})
解决方法2:重写push和replace方法(在配置路由信息中)
let originPush = VueRouter.prototype.push
let originReplace = VueRouter.prototype.replace
// 重写push方法,解决多次点击搜索报错问题
VueRouter.prototype.push = function(location,resolve,reject){
if(resolve && reject){
originPush.call(this,location,resolve,reject)
}else{
originPush.call(this,location,()=>{},()=>{})
}
}
// 重写replace方法
VueRouter.prototype.replace = function(location,resolve,reject){
if(resolve && reject){
originReplace.call(this,location,resolve,reject)
}else{
originReplace.call(this,location,()=>{},()=>{})
}
}