文章目录
路由原理(hash)
路由安装和使用(vue2)
路由跳转
路由的传参和取值
嵌套路由
路由守卫
完整代码
路由原理(hash)
单页应用的路由模式有两种
1.哈希模式(利用hashchange 事件监听 url的hash 的改变)
- 哈希模式的原理
哈希模式下,哈希部分的改变不会触发浏览器向服务器发送新的请求,所有的路由都会发送到同一个HTML文件。这意味着,即使在前端进行页面导航,服务器也不需要额外的配置,因为所有的路由都会被前端路由器处理。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> 头部 <router-link to="ger">个人</router-link> <router-link to="login">登录</router-link> <button @click="logins">登录</button> <button @click="gers">个人</button> <br> <button @click="gersid">apl 带参数的个人</button> <router-link :to="{path:'/login',query:{id:queryid}}">带查询参数的登录link</router-link> <br> <router-link :to="{name:'login',params:{id:queryid}}">路由参登录link</router-link> <button @click="gersidhs">apl 带参数的个人</button> <hr> <!-- 下面是路由出口 --> <router-view :key="$route.fullPath"></router-view> 尾部 </div> </body> <script src="../js/vue2.7.js"></script> <script src="../js/vue-router.js"></script> <script> //安装路由,前提要导入路由js Vue.use(VueRouter) //创建一个登录子组件 var login={ template:` <div> 登录页面 </div> `, mounted(){ console.log(this.$route.query.id); console.log(this.$route.params.id); } } //创建一个登录子组件 var ger={ template:` <div> 个人页面 </div> `, mounted(){ console.log(this.$route.query.id); console.log(this.$route.params.id); } } //创建路由配置实例,主要实现 路径和子组件时间的映射 var myrouter =new VueRouter({ routes:[ {path:'/login',name:'login',component:login}, {path:'/ger',name:'ger',component:ger} ] }) var app=new Vue({ el:"#app", router:myrouter, data(){ return{ queryid:1 } }, methods:{ logins(){ this.$router.push({path:'/login'}); }, gers(){ this.$router.replace({ path:'/ger' }) }, gersid(){ this.$router.push({path:'/ger',query:{id:this.queryid}}) }, gersidhs(){ this.$router.push({name:'ger',params:{id:"6"}}); } } }) </script> </html>
3.history模式(使用此模式需要后台配合把接口都打到我们打包后的index.html上)
- hash模式的原理:
核心是锚点值的改变,我们监听到锚点值改变了就去局部改变页面数据,不做跳转。跟传统开发模式url改变后 立刻发起请求,响应整个页面,渲染整个页面比路由的跳转用户体验更好
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>单页面跳转的原理</title> </head> <body> <a href="#/login">登录</a> | <a href="#/register">注册</a> <div id="app"></div> <script type="text/javascript"> var appDom = document.getElementById("app"); window.addEventListener("hashchange",function(){ console.log(location.hash); switch(location.hash){ case '#/login': appDom.innerHTML = "登录"; break; case '#/register': appDom.innerHTML="注册"; break; } }) </script> </body> </html>
路由安装和使用(vue2)
- 导入路由插件
<script src="js/vue-router.js" type="text/javascript" charset="utf-8"></script>
- 安装路由插件到Vue中
Vue.use(VueRouter);
- 创建VueRouter对象
var Login = Vue.extends({ template:` <div> 我是登录页面 </div> ` }); // 创建VueRouter对象,并配置路由 var myRouter = new VueRouter({ // 配置路由 routes:[ // 指定路由链接、路由名称、路由页面(组件) {path:'/login',name:'login',component:Login} ] });
- 使用路由
var myvue = new Vue({ el:'#app', // 引入到vue 实例中,并在模板中使用<router-view> router:myRouter, template:` <div> 头部 <router-view></router-view> 尾部 </div> ` })
路由跳转
路由的跳转有两种方式:
1.使用标签
<router-link to='/login'></router-link>
3.编程式路由,使用js
this.$router.push({path:'/login'}); this.$router.replace({path:'/login'});
说明:
- this.$router.push(); 会向history中添加记录
- this.$router.replace();不会向history中添加记录。
- this.$router.go(-1)常用来做返回上一个地址。
路由中的对象:
- this.$route 路由信息对象,只读。
- this.$router 路由操作对象,只写。
路由的传参和取值
- 查询参
配置。查询参可以和path属性匹配,也可以和name属性匹配。
<router-link :to="{path:'/login',query:{id:queryid}}"></router-link>
或者
<router-link :to="{name:'login',query:{id:queryid}}"></router-link>
或者
this.$router.push({path:'/login',query:{id:queryid}});
取参
- 路由参
配置路由规则
var router = new VueRouter({ routers:[ // 需要在配置路由规则时,使用冒号指定参数 {name:'login',path:'/login/:id',component:LoginVue} ] });
配置。意:在这里path和params两个参数不能同时使用
<router-link :to="{name:'login',params:{id:paramId}}"></router-link>
或者
this.$router.push({name:'login',params:{id:this.paramId}});
取参
this.$route.params.id;
注意:相同路由,但参数不同。造成页面不刷新的问题。
<router-view :key="$route.fullPath"></router-view>
嵌套路由
- 路由间有层级关系。他们在模板中也有嵌套关系。
- 可以一次性配置多个路由。
var Nav = { template:` <div> <router-link :to="{name:'nav.index'}">首页</router-link> <router-link :to="{name:'nav.personal'}">个人中心</router-link> <router-link :to="{name:'nav.message'}">消息</router-link> <router-view></router-view> </div> ` }; var Index = { template:` <div> 首页 </div> ` } var Personal = { template:` <div> 个人中心 </div> ` } var Message = { template:` <div> 消息 </div> ` }
var router = new VueRouter({ routes:[ { path:'/nav', name:'nav', component:Nav, children:[ {path:'',redirect:'/nav/index'}, {path:'index',name:'nav.index',component:Index}, {path:'personal',name:'nav.personal',component:Personal}, {path:'message',name:'nav.message',component:Message} ] }, { path:'', redirect:'/nav' } ] });
var app01 = new Vue({ el:'#app', template:` <div> <router-view></router-view> </div> `, router });
路由守卫
- 可以做验证判断
- 使用路由的钩子函数beforeEach实现
let app = new Vue({ el: '#app01', router:myRouter, mounted() { this.$router.beforeEach((to,from,next)=>{ console.log(to); if(to.path=='/nav/index'){ // 跳转到目标路由 next(); }else{ setTimeout(function(){ next(); },2000); } }); } });
完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <router-view :key="$route.fullPath"></router-view> </div> </body> <script src="../js/vue2.7.js"></script> <script src="../js/vue-router.js"></script> <script> //安装路由,前提要导入路由js Vue.use(VueRouter) //导航子组件,以及路由 var nav = { template:` <div> <router-link :to="{name:'nav.index'}">首页</router-link> <router-link :to="{name:'nav.personal'}">个人中心</router-link> <router-link :to="{name:'nav.message'}">消息</router-link> <router-view></router-view> </div> ` }; var Index = { template:` <div> 首页 </div> ` } var Personal = { template:` <div> 个人中心 </div> ` } var Message = { template:` <div> 消息 </div> ` } var router=new VueRouter({ routes:[ { path:'/nav', name:'nav', component:nav, children:[ {path:'',redirect:'/nav/index'}, {path:'index',name:'nav.index',component:Index}, {path:'personal',name:'nav.personal',component:Personal}, {path:'message',name:'nav.message',component:Message} ] }, { path:'', redirect:'/nav' } ] }); var app=new Vue({ el:"#app", router, mounted() { this.$router.beforeEach((to,from,next)=>{ console.log(to); if(to.path=='/nav/index'){//判断跳转的是否是首页,否延时2秒后跳转 // 跳转到目标路由 next(); }else{ setTimeout(function(){ next(); },2000); } }); } }); </script> </html>