vue-router路由


1 路由概述

        vue-router是vue的一个插件,用来提供路由功能。通过路由的改变可以动态加载组件,达到开发单页面程序的目的。

2 基本使用

    1) 声明组件
       let com1 = {template:`<div>this is com1</div>`}
       let com2 = {template:`<div>this is com2</div>`}
       let com3 = {template:`<div>this is com3</div>`}
    2) 声明路由器
      router是路由器对象,routes是路由列表
      let router = new VueRouter({
        routes: [
          { 
            path: '/a',     // 路由地址
            component: com1,// 对应组件
            name: 'comA',   // 给路由设置名字,方便使用name进行跳转
            redirect: '/c', // 重定向
            alias: '/coma', // 别名
          },
          { path: '/b', component: com2 },
          { path: '/c', component: com3 },
        ]
      })
    3)路由注册
      在vue的根实例中,注册路由
      let vm = new Vue({
        el: '#app',
        router  //等价于router:router
      })
    4)路由使用
      <router-link to="/a">A组件</router-link>
      <router-link to="/b">B组件</router-link>
      <router-link to="/c">C组件</router-link>
      // 路由视口,用来加载路由对应的组件
      <router-view></router-view>

3 动态路由

3.1 声明

  let router = new VueRouter({
        routes: [
             // 动态路由参数以冒号开头 
             { path: '/user/:username/:id', component:com1 }
        ]
  })
  <router-link to="/user/zhangsan/1001"></router-link>

3.2 路由参数

	  对于获取路由携带参数(参数值会被设置到 this.$route.params中)
      /user/zhangsan/1001/user/lisi/1002都将映射同一个组件,
      在一个组件内部发生动态路由变化时,vue组件实例会被复用,而不会重新销毁再创建;
      组件内部发生动态路由变化,想要监听路由参数变化时,可以使用watch监听$route,
      或者使用组件内部的导航守卫。
      let com1 = {
        data() {
          return {
            id: null,
            username: null
          }
        },
        template: ``,
        created() {
          // 在created钩子函数中,只能一次性获取携带的参数,不能够持续获取
          this.id = this.$route.params.id;
          this.username = this.$route.params.username;
        },
        watch() {
          // 使用watch监听器,可以持续监听路由器对象中,携带参数的变化
          $route(to, from) {
            this.id = to.params.id;
            this.username = to.params.username;
          }
        }
      }

4 路由守卫

4.1 介绍

  正如其名,vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
  每个守卫方法接收三个参数:
    to: Route 即将要进入的目标 路由对象
    from: Route 当前导航正要离开的路由
    next: Function 一定要调用该方法来 resolve 这个钩子,让路由跳转继续进行
      next(): 进行管道中的下一个钩子(继续完成导航跳转)
      next(false): 中断当前的导航。
      next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。
  守卫是异步解析执行,导航在所有守卫 resolve 完之前一直处于等待中。

4.2 全局守卫

    let router = new VueRouter({
        routes: [
             {...}
        ]
     })
 1)全局前置守卫
     router.beforeEach((to, from, next) => {
          .......拦截操作
          next();
     })
 2) 全局后置守卫
     router.afterEach((to, from) => {
         .......之后操作
     })
 3) 路由独享守卫
     let router = new VueRouter({
         routes: [
             { 
		        path: '/a', 
		        component: com1,
		        beforeEnter(to, from, next) {
		          .......拦截操作
		          next();
        	    }
             }
         ]
     })
  4) 组件内守卫
     let com1 = {
         data(){
            return {}
         },
         template: ``,
         // 进入当前组件之前拦截
         beforeRouteEnter(to, from, next) {
              .......拦截操作
              next();
         },
         // 在当前组件中,路由发生改变时触发
    	 beforeRouteUpdate(to, from, next) {
      		  .......拦截操作
      		  next();
    	 },
    	// 离开当前组件之前,触发
    	beforeRouteLeave(to, from, next) {
      		.......拦截操作
      		next();
    	}
  	}

5 嵌套路由

	品字形布局:上面头部,左侧导航栏,右侧内容区域
	嵌套路由的定义(children属性中定义子路由)
	  let router = new VueRouter({
	    routes: [
	      {
	        path: '/student',
	        component: comStu,
	        children: [
	          { path: 'grade', component: comGrade },
	          { path: 'register', component: comRegister },
	        ]
	      }
	    ]
	  }) 
	使用
	  一级路由对应一个router-view
	  二级路由对应一个router-view

6 编程式导航

  1)this.$router.push()  // 在history历史栈中新增一条记录
    this.$router.push({ path: '/a' })
    this.$router.push({ name: 'comA' })
    路由跳转并携带参数
      · 路径path跳转和query搭配使用
        this.$router.push({ path: '/a', query: { username: 'zhangsan' } })
      · 名字name跳转和params搭配使用
        this.$router.push({ name: 'comA', params: { age: 12 } })
    参数获取
       在跳转的目标组件中,只要能够访问到$route就能拿到跳转携带的参数
       例如:在目标组件的created(){
         console.log(this.$route.params)
         console.log(this.$route.query)
       }
    query传参和params传参区别
        1.query传参参数保存在url地址栏中,以查询字符串的形式拼接上去
        2.安全性来讲,params比较安全,query会显示在地址栏中,容易造成数据泄露
        3.刷新页面时,query中的数据不受影响,而params中的数据直接消失
  2)this.$router.replace()  // 直接替换当前路由,不会产生新的历史记录
  3)this.$router.go()       // 内部接受正值或负值的整数作为参数,正数就是前进,负数就是后退(在历史记录中)

具体案例:

<head>
    <title>编程式导航</title>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
    <style>
        header{
            height: 50px;
            background-color: blue;
        }
        main{
            display: flex;
        }
        .left{
            width: 150px;
            border: 3px solid orange;
            height: 650px;
            margin: 10px 10px 0 0;
        }
        .right{
            flex: 1;  /* width: calc(100%-150px);相当于flex:1 */
            border: 3px solid red;
            height: 650px;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <div id="app">
        <header>我是网站头部</header>
        <main>
            <div class="left">
                <!-- 4.路由的使用 -->
                <router-link to="/user">用户管理</router-link><br/>
                <router-link to="/student">学生管理</router-link><br/>
                <router-link to="/class">班级管理</router-link><br/>
            </div>
            <div class="right">
            <!-- 实现了组件之间的动态加载 -->
            <router-view></router-view>
            </div>
        </main>
    </div>
    <script>
    // 1.注册组件
    let com1={
        data(){
            return{}
        },
        template:`
        <div>
            用户管理
        </div>
         `
    }
    let com2={
        data(){
            return{}
        },
        template:`
        <div>
            学生管理<br/>
            <div>
                <button @click="clickHandler">成绩管理</button>
                <button @click="clickHandler">学籍管理</button> 
                <button @click="$router.go(1)">返回</button>
            </div>
            <router-view></router-view>  
        </div>
        `,
        methods:{
            clickHandler(e){
                if(e.target.innerText == '成绩管理'){
                    // 使用this.$router.push  完成编程式导航
                    // this.$router.push({path:'/student/grade'})
                    // 判断当前自己是自己就不用跳转了
                    if(this.$route.fullPath !== '/student/grade'){
                        // this.$router.push({
                        //     name:'grade',
                        //     params:{
                        //         id:1001,
                        //         name:'zhansgan'
                        //     }
                        // })
                        
                        // 路由替换
                        this.$router.replace('/student/grade')
                        // go方法  后可以跟一个整数                        
                    }
                }else{
                    // this.$router.push({path:'/student/register'})
                    if(this.$route.fullPath !== '/student/register'){
                        // 使用path跳转
                        this.$router.push({
                            name:'register',
                            query:{
                                id:1002,
                                name:'lisi'
                            }
                        })
                    }
                }
            }
        }
    }
    let com3={
        data(){
            return{}
        },
        template:`
        <div>
            班级管理
        </div>
        `
    }
    // 2.定义路由
    let comGrade={
        data(){
            return{}
        },
        template:`
        <div>
            成绩管理
        </div>
        `,
        created(){
            console.log('params',this.$route.params);
        }
    }
    let comRegister={
        data(){
            return{}
        },
        template:`
        <div>
            学籍管理
        </div>
        `,
        created(){
            console.log('query',this.$route.query);
        }
    }
    // 2.定义路由
    let router = new VueRouter({
        // 修改路由模式  默认模式是hash
        mode:'history',
        routes:[
            { path:'/user',component:com1 },
            { 
                path:'/student',
                component:com2,
                children:[
                    {path:'grade',component:comGrade,name:'grade'},
                    {path:'register',component:comRegister,name:'register'},
                ]
             },            
            { path:'/class',component:com3 }            
        ]
    })
    let vm = new Vue({
        el:"#app",
        data:{},
        methods:{},
        // 3.路由注册
        router
    })
    </script>
</body>
</html>

7 路由模式

7.1 修改路由模式

       vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。不过要想使用这种模式,还需要后台配置支持。

   let router = new VueRouter({
        // mode: 'hash',
        mode: 'history',  // mode属性修改路由模式,默认为hash模式
        routes: []
   })

7.2 hash路由和history路由的区别:

1.hash路由在地址栏URL上有#,而history路由没有#,并且更精简;
2.进行回车刷新操作,hash路由会加载到地址栏对应的页面,而history路由一般就404报错了;(刷新是网络请求,history路由需要后端支持)。
3.hash路由支持低版本的浏览器,而history路由是HTML5新增的API。
4.hash的特点在于它虽然出现在了URL中,但是不包括在http请求中,所以对于后端是没有一点影响的,所以改变hash不会重新加载页面,所以这也是单页面应用的必备。
5.history运用了浏览器的历史记录栈,之前有back,forward,go方法,之后在HTML5中新增了pushState()和replaceState()方法(需要特定浏览器的支持),它们提供了对历史记录进行修改的功能,不过在进行修改时,虽然改变了当前的URL,但是浏览器不会马上向后端发送请求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值