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({})