Vue路由
注意:随着版本更新,vue版本需要对应合适的vue-router版本才能正常工作,比如这里当我安装vue-router时,
npm install vue-router
它默认安装的版本是4.0以上的,在我这个vue2.0版本会各种报错,跟vuex也要对应合适的版本一样,否则会报错,所以安装的时候需要指定版本
npm install vue-router@3.4.9
同vuex一样,在安装好后需要一个router文件夹管理路由,里面的index.js文件由于创建路由,通过VueRouter创建一个路由器。routes是定义的路由匹配规则,需要交给router管理。
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
export default new VueRouter({
routes : [
{
path:"/about",
component:AboutCom
},
{
path:"/home",
component:HomeCom,
children:[
{
// path:'/news',这里的/一定要删除是个坑,不然子路由组件渲染不出来
path:'news',
component:NewCom
},
{
// path:'/message',这里的/一定要删除是个坑,不然子路由组件渲染不出来
path:'message',
component:MessageCom,
children:[
{
//传递params参数 需要路由定义时声明
// path:"detail/:id/:title/:content",
//传递query参数不需要声明
path:"detail",
component:DetailCom,
name:'xiangqing' ,
props(route){
console.log(route)
const {id,title,content} = route.query
return {id,title,content}
}
}
]
},
]
},
]
})
main.js里需要引入这个路由器并挂载到vue实例vc
import router from './router'
new Vue({
el:"#app",
router,
render: h => h(App),
})
上面代码是整体代码,一步一步来,
在APP组件里 有两个链接,about和home,这解析出来其实就是a标签 About组件和Home组件由路由控制显示,所以这两个组件是路由组件,就需要在router里定义这两个组件,现在pages文件夹里定义好这两个组件 pages/Home和pages/About,然后在路由器里引入组件开始定义匹配规则
import AboutCom from '../pages/AboutCom'
import HomeCom from '../pages/HomeCom'
routes : [
{
path:"/about",
component:AboutCom
},
{
path:"/home",
component:HomeCom,
这样在页面里,通过router-link作为a标签,同时router-view作为占位,到时候路由匹配到哪个组件就展示哪个组件
<router-link to="/about">about</router-link>
<!-- <a href="">home</a> -->
<router-link to="/home">home</router-link>
<router-view></router-view>
这样一级路由就完成了。
接下来是二级路由Home组件里 ,又有导航区 和展示区
在home的路由里通过children定义子路由
{
path:"/home",
component:HomeCom,
children:[
{
// path:'/news',这里的/一定要删除是个坑,不然子路由组件渲染不出来
path:'news',
component:NewCom
},
{
// path:'/message',这里的/一定要删除是个坑,不然子路由组件渲染不出来
path:'message',
component:MessageCom,
注意
path:'news',
没有/,这是坑,加了的话组件等会儿就展示不出来,其余跟一级组件同理,接着是三级路由,
接着在message里通过children定义子路由
path:'message',
component:MessageCom,
children:[
{
//传递params参数 需要路由定义时声明
// path:"detail/:id/:title/:content",
//传递query参数不需要声明
path:"detail",
component:DetailCom,
其余地方跟一级路由同理,这样一个嵌套路由就完成了。
接下来是给路由传参
传递params参数
params参数在地址栏表现为
传递params参数需要在路由定义时声明接收params参数
//传递params参数 需要路由定义时声明
path:"detail/:id/:title/:content",
在页面的router-link里是使用模板字符串传递的
<router-link :to="`/home/message/detail/${msg.id}/${msg.title}/${msg.content}`">{{msg.title}}</router-link>
params参数藏在$sroute.params里,所以页面要获取这些params可以
<li>id:{{$route.params.id}}</li>
传递query参数
传递query参数在路由定义时不用声明,在浏览器地址栏表现为
在路由定义时
//传递query参数不需要声明
path:"detail",
在页面的router-link也是模板字符串
<router-link :to="`/home/message/detail/?id={msg.id}&title=${msg.title}&content={msg.content}`">{{msg.title}}</router-link>
query参数藏在$sroute.query里,所以页面要获取这些params可以
<li>id:{{$route.query.id}}</li>
命名路由简化跳转方式
可以在路由定义时给路由命名,方式时name:"名字“
path:"detail",
component:DetailCom,
name:'xiangqing' ,
在页面的router-link进行跳转时就可以这样写
<!-- 通过命名路由的方式传参 -->
<router-link :to="{
name:'xiangqing',
query:{
id:msg.id,
title:msg.title,
content:msg.content
}
}">
{{msg.title}}
</router-link>
当然这里也可以由params加入,具体是看路由定义时规定的时哪些值由params传递,哪些由query传递,这样就省略了path一长串。
路由的props配置
想象这样一个场景,点击一条消息进入消息的详情页,需要展示消息的id,title,content等,由于这些信息全保存在$route里所以可以在页面通过params或者query取出
params:
<li>id:{{$route.params.id}}</li>
<li>消息:{{$route.params.title}}</li>
<li>内容:{{$route.params.content}}</li>
query:
<li>id:{{$route.query.id}}</li>
<li>消息:{{$route.query.title}}</li>
<li>内容:{{$route.query.content}}</li>
这样代码过于冗余,可以在computed里进行处理再显示,不再赘述,另一种方法是在路由定义时通过props的方式传递,同时在组件里通过props[‘id’,‘title’,‘content’]接收,一般父组件给子组件传值就是这种方式,具体做法是在路由定义时
props:{carName:"奔驰"}这是通过props映射自定义的静态数据
props:true表示映射params参数为props传给路由组件
如果还想映射query参数为props传给路由组件,则必须把props写成
props(route){
const {id,title,content} = route.query
return {id,title,content}
}
这里的route是直接放在router管理的,才能取到这个route,放在外面定义好交给router管理的取不到。在页面组件需要定义props接收参数
<script>
export default {
props:['id','title','content']
}
</script>
在页面就可以直接用数据了
<li>id:{{id}}</li>
<li>消息:{{title}}</li>
<li>内容:{{content}}</li>
编程式路由导航
replace – 替换当前记录 不能返回 通过点击事件跳转
this.$router.push(path)、
this.$router.replace(path)、
this.$router.back()、
this.$router.go(-1)、
this.$router.go(1)
pushShow(msg){
this.$router.push({ name:'xiangqing',
query:{
id:msg.id,
title:msg.title,
content:msg.content
}
})
}
缓存路由组件
有这样一个需求,点击News 显示NewCom组件,点击Message显示MessageCom组件,在NewCom组件里输入东西后,点击Message后,再点击News会导致NewCom组件输入内容清空,这是因为在路由的切换过程中,伴随着组件的挂载和卸载,为了使NewCom组件输入框里的内容保持不变,就许哟啊一个keep-alive包裹这个组件的router-view,这样就行了
<keep-alive>
<router-view></router-view>
</keep-alive>
但是,这样做会使得MessageCom的组件也在切换过程中不销毁,为了解决这个问题 只保证NewComers组件不销毁,可以这样添加一个include
<keep-alive include="NewCom">
<router-view></router-view>
</keep-alive>
这个NewCom对应的是这个组件的名字NewCom,NewCom.vue
export default({
name:"NewCom",
})