学习b站上的小马视频。
动态路由可以设置动态参数等,适合REST风格的接口,或者用于url级别的分页等功能。
这里设置一个类似导航条或者分页条的路由。
<template> <div id="app"> <!--在这里设置去不同页面的路由--> <p> <router-link to="/">主页</router-link> <router-link to="/player/1">第一页</router-link> <router-link to="/player/2">第二页</router-link> </p> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
在这里配置组件的路由映射。
import Vue from 'vue' import Router from 'vue-router' //导入要映射到的组件们 import Hello from '../page/xiaoma/Hello' import Player from '../page/xiaoma/Player' Vue.use(Router); export default new Router({ routes: [ { path: '/',//主页,显然这是一个静态路由 name: 'Hello', component: Hello }, { path: '/Player/:uid',//这是一个带参数uid的动态路由 name: 'Player', component: Player } ] })
使用了动态路由的组件,在钩子函数中根据路由参数来请求指定的资源。
<template> <div> <h5>这里是第{{page}}页</h5> <p>我是{{detail.name}},我的年龄是{{detail.age}}</p> </div> </template> <script> export default { name: "Player", data() { return { page: 0, detail: {} } }, //组件加载一次之后就不会再加载了(第x页->第x页),所以不应该写在mounted里 //但是这部分也不能去掉,否则组件第一次加载时没法获取到数据(主页->第x页) mounted() { //在这里获取动态路由的参数 this.page = this.$route.params.uid; //然后通过这个参数请求到内容 this.detail = this.getDetail(this.page); }, //而是写在下面这个方法中,这样每次路由发生更新前都会调用这个方法 beforeRouteUpdate(to, from, next) { //在这里获取动态路由的参数(注意这里从第一个参数中获取) this.page = to.params.uid; //然后通过这个参数请求到内容 this.detail = this.getDetail(this.page); //这里next()不传参会正常执行管道中的下一个钩子 next(); }, methods: { getDetail(i) { //这里应该向服务器请求对应的资源,这里直接简单的模拟成switch返回 switch (i.toString()) { case '1': return {uid: 1, name: "唐僧", age: 25}; case '2': return {uid: 2, name: "孙悟空", age: 19}; default: return {uid: -1}; } } } } </script> <style scoped> </style>
嵌套路由往往在前面的动态路由的基础上,如uid为某个值的用户的某些资源的访问(如简介、状态等)。
这个例子里App.vue和上面的一样。
在前面的基础上,为这个组件的路由配置子路由,映射到相应的组件上去。
import Vue from 'vue' import Router from 'vue-router' //导入要映射到的组件们 import Hello from '../page/xiaoma/Hello' import Player from '../page/xiaoma/Player' import Profile from '../page/xiaoma/Player/Profile' import Status from '../page/xiaoma/Player/Status' Vue.use(Router); export default new Router({ routes: [ { path: '/',//主页,显然这是一个静态路由 name: 'Hello', component: Hello }, { path: '/Player/:uid',//这是一个带参数uid的动态路由 name: 'Player', component: Player, //设置其子路由,形成嵌套路由 children: [ {path: 'profile', component: Profile}, {path: 'status', component: Status} ] } ] })
/player/:uid
的子路由/player/:uid/profile
对应的组件,这里是用户的简介页。这里都不再去写请求的部分,实际上应该去发送请求返回一些详细数据。
<template> <div> <h3>简介页面:我是{{$route.params.uid}}号</h3> </div> </template> <script> export default { name: "Profile" } </script> <style scoped> </style>
/player/:uid
的子路由/player/:uid/status
对应的组件,这里是用户的状态页。
<template> <div> <h3>状态页面:{{$route.params.uid}}在线</h3> </div> </template> <script> export default { name: "Status" } </script> <style scoped> </style>
注意,因为在这个组件的路由上嵌套了子路由,那就要在这个组件上设置子组件视图(<router-view/>
标签)以形成动态的子组件关系。
<template> <div> <h5>这里是第{{page}}页</h5> <p>我是{{detail.name}},我的年龄是{{detail.age}}</p> <router-link v-bind:to="profileURL">去简介页</router-link> <router-link v-bind:to="statusURL">去状态页</router-link> <hr> <!--这里再嵌套一个router-view以展示这个组件的子组件--> <router-view></router-view> </div> </template> <script> export default { name: "Player", data() { return { page: 0, detail: {}, //添加简介页和状态页的URL,这里是变量(因为是动态页面,这个组件是复用的) profileURL: "", statusURL: "" } }, mounted() { this.page = this.$route.params.uid; this.detail = this.getDetail(this.page); //动态URL的确定 this.profileURL = "/player/" + this.page + "/profile"; this.statusURL = "/player/" + this.page + "/status"; }, beforeRouteUpdate(to, from, next) { this.page = to.params.uid; this.detail = this.getDetail(this.page); //动态URL的确定 this.profileURL = "/player/" + this.page + "/profile"; this.statusURL = "/player/" + this.page + "/status"; next(); }, methods: { getDetail(i) { //这里应该向服务器请求对应的资源,这里直接简单的模拟成switch返回 switch (i.toString()) { case '1': return {uid: 1, name: "唐僧", age: 25}; case '2': return {uid: 2, name: "孙悟空", age: 19}; default: return {uid: -1}; } } } } </script> <style scoped> </style>