9 前端路由(二)
1、编程式导航
通过一个方法来动态触发,而非通过<router-link>标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>14-编程式导航</title> </head> <body> <div id="app"></div> <script src="./node_modules/vue/dist/vue.js"></script> <script src="./node_modules/vue-router/dist/vue-router.js"></script> <script type="application/javascript"> var App={ template:`<div> <button @click="paramsHandler">用户1</button> <router-link :to="{name:'userq',query:{userId:2}}">用户2</router-link> <router-view></router-view> </div>`, methods:{ paramsHandler(){ //编程式导航 this.$router.push({name:'userp',params:{userId:123}}) } }, }; var UserParams={ template:`<h3>我是用户1</h3>`, //在组件内获取路由信息 created(){ console.log(this.$route); //获取路由参数 userId=this.$route.params.userId //可以做一些Ajax请求 } }; var UserQuery={ template:`<h3>我是用户2</h3>`, created(){ //query方式的参数 userId=this.$route.query.userId //有参数后就可以做其他请求 } }; Vue.use(VueRouter); var router=new VueRouter({ routes:[ { //动态路由参数以冒号开头 path:'/user/:userId', name:'userp', component:UserParams }, { path:'/user', name:'userq', component:UserQuery } ] }); new Vue({ el:"#app", template:`<App/>`, components:{ App }, router, data(){ return {} } }) </script> </body> </html>
2、嵌套路由
即router-view中嵌套另一个router-view
动态路由匹配局限:子组件的结构不一致
在路由中添加children属性,来添加子路由,子路由path不需要写全也不需要/,会自动拼接,在子路由中可继续用children属性来添加子路由的子路由
父组件建议不写name属性,原因见下面警告处理,route-link不用v-bind绑定to属性,直接写to='/home'
在父组件中添加router-view标签,作为子组件渲染出口
让访问/路径时跳转到/home路径,给路由添加一个对象即可,包含redirect属性,有两种写法。建议方式二,原因见下面警告处理
当访问/home时,只会渲染出子组件按钮,不会渲染子组件的内容,我们给子组件添加一个path为''的子路由,并制定component,
如下配置即访问/home时会自动挂在Music组件内容
警告处理:
我们在使用子路由时,父路由不建议用name属性,我们用to='/path'方式来使用
<!DOCTYPE html> <html lang="cn"> <head> <meta charset="UTF-8"> <title>13-嵌套路由</title> <script src="./node_modules/vue-router/dist/vue-router.js"></script> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> </head> <body> <div id="app"></div> </body> <script type="text/javascript"> Vue.use(VueRouter); var Music={ template:`<div>我是音乐页面</div>` }; var Movie={ template:`<div>我是电影页面</div>` }; var Home={ template:`<div> <br/> <router-link :to="{name:'music'}">音乐</router-link> <router-link :to="{name:'movie'}">电影</router-link> <router-view></router-view> </div>`, }; var router= new VueRouter({ routes:[ //让访问/默认跳转到/home { path:'/', //写法一,官方不建议 // redirect:{name:'home'}, //写法二 redirect:'/home' }, { // name:'home', path:'/home', component:Home, //Home组件下的子路由 children:[ { //当访问/home时,Home组件的出口不会渲染任何内容,因没有匹配到合适的子路由 //如下方式处理 path:'', component:Music }, { name:'music', //斜杠会自动拼接 path:'music', component:Music }, { name:'movie', //斜杠会自动拼接 path:'movue', component:Movie, //子路由下可以继续写children来添加孙子路由 children:[] } ] }, ] }); var App={ template:`<div> <router-link to="/home">主页</router-link> <router-view></router-view> </div>` } new Vue({ el:"#app", router:router, template:`<App/>`, components:{ App:App } }) </script> </html>
3、动态路由匹配
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>16-动态路由匹配</title> </head> <body> <div id="app"></div> <script src="./node_modules/vue-router/dist/vue-router.js"></script> <script src="./node_modules/vue/dist/vue.js"></script> <script type="application/javascript"> Vue.use(VueRouter); var App={ template: ` <div> <router-link to="/timline">首页</router-link> <router-link to="/pins">沸点</router-link> <router-view></router-view> </div> ` }; var PublicCom={ template:`<div>我是{{msg}}</div>`, data(){ return { msg:'首页' } }, watch:{ '$route':function (to, from) { //to:到哪儿去 //from:从哪里来 //这里拿到相关参数后就可以进行数据请求,进而渲染DOM this.msg=to.params.id } } }; var Timline={ template:`<div> <router-link :to="{name:'publiccom',params:{id:'android'}}">安卓</router-link> <router-link :to="{name:'publiccom',params:{id:'ios'}}">IOS</router-link> <router-view></router-view> </div>` }; var Pins={ template:`<div>沸点</div>` }; var router=new VueRouter({ routes:[ { path:'/timline', component:Timline, children:[ { path:"", component:PublicCom },{ path:':id', name:'publiccom', component:PublicCom } ] }, { path:'/pins', component:Pins } ] }); new Vue({ el:"#app", template:`<App/>`, components:{ App:App }, router:router }) </script> </body> </html>
我们在父路由和子路由中使用同一个公共的布局组件,让这个公共组件自己去匹配当前的路由
父路由挂载上父组件后,由于父路由下面有个默认子路由,所以默认子路由会同步挂载上
在公共组件中去监听$route
to和from是两个对象,可以通过这两个对象拿到参数id,进而进行数据请求
4、keep-alive(缓存)在路由中的应用
在路由中来回切换时,组件重建和销毁,状态不会保存
为了保存这种状态,需要使用keep-alive标签,把子路由出口<router-view>标签放<keep-alive>标签中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>17 keep-alive在路由中的应用</title> </head> <body> <div id="app"></div> <script src="./node_modules/vue/dist/vue.js"></script> <script src="./node_modules/vue-router/dist/vue-router.js"></script> <script type="application/javascript"> var App = { template: `<div> <router-link to="/home">主页</router-link> <router-link to="/setting">设置</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div>` }; var Home={ template:`<div><h1>主页</h1></div>`, created(){ console.log("主页组件创建完成") }, mounted(){ console.log("主页组件挂载完成") }, destroyed(){ console.log("主页组件销毁完成") } }; var Setting = { template:`<div><h1>设置</h1> <button @click="checkbgc">点我变红</button> </div>`, methods:{ checkbgc(e){ e.target.parentElement.style.backgroundColor='red'; } }, created(){ console.log("设置组件创建完成") }, mounted(){ console.log("设置组件挂载完成") }, destroyed(){ console.log("设置组件销毁完成") } }; Vue.use(VueRouter); var router=new VueRouter({ routes:[ { path:'/home', component:Home }, { path:'/setting', component: Setting } ] }); new Vue({ el: "#app", template:`<App/>`, components: { App: App }, router:router }); </script> </body> </html>