vue-路由

路由

用 Vue.js + Vue Router 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们

起步

<!DOCTYPE html>
<html lang="en">
<head>
        <script src="../vue.js"></script>
    <script src="../vue-router.js"></script>
    <style>
        .router-link-exact-active{
            color: red;
        }
    </style>
</head>

<body>
    <div id="app">
       <ul>
           <router-link to="/position">职位</router-link>
           <router-link to="/search">搜索</router-link>
       </ul>
       <router-view></router-view>
    </div>
    
<script>
    const position = {
        template:`<div>position</div>`
    }

    const search = {
        template:`<div>search</div>`
    }

    var router = new VueRouter({
        mode:'hash',
        routes:[
            {
                path:"/",
                redirect: '/position'
            },
            {
                path:'/position',
                component:position
            },
            {
                path:'/search',
                component:search
            }
        ]
    })
   
   
    var vm = new Vue({
        router,
        el:"#app",
    })
</script>
</body>
</html>

动态路由

<!DOCTYPE html>
<html lang="en">
<head>
<script src="../vue.js"></script>
<script src="../vue-router.js"></script>
<style>
  .router-link-exact-active {
      color: red;
  }
</style>
</head>

<body>
<div id="app">
  <router-link tag="div" to="/position/35">职位</router-link>
  <router-link tag="div" to="/search">搜索</router-link>

  <router-view></router-view>
</div>

<script>
  const search = {
      template: `<div>search</div>`
  }

  var router = new VueRouter({
      mode: 'hash',
      routes: [{
              path: '/position/:id',  //动态路由
              component: {
                  template: `<div>{{$route.params}} </div>` //$route.params等于{ "id": "35" }
              }
          },
          {
              path: '/search',
              component: search
          },

      ]
  })


  var vm = new Vue({
      router,
      el: "#app",
  })
</script>
</body>

</html>

嵌套路由

<!DOCTYPE html>
<html lang="en">
<head>
<script src="../vue.js"></script>
<script src="../vue-router.js"></script>
<style>
  .router-link-active{
      color: red;
  }
</style>
</head>

<body>
<div id="app">
 <ul>
     <router-link to="/position">职位</router-link>
     <router-link to="/search">搜索</router-link>
 </ul>
 <router-view></router-view>
</div>

<script>

const position ={template:`<div>
      <router-link to="/position/fe">前端</router-link>
      <router-link to="/position/be">后端</router-link>

      <router-view></router-view>
  </div>`
}
const search = {
  template:`<div>search</div>`
}

var router = new VueRouter({
  mode:'hash',
  routes:[
      {
          path:'/position',
          component:position,
          children:[   //嵌套路由
              {
                  path:'fe',
                  component:{
                      template:`<div>position fe</div>`
                  }
              },
              {
                  path:'be',
                  component:{
                      template:`<div>position be</div>`
                  }
              }
          ]
      },
      {
          path:'/search',
          component:search
      }
  ]
})


var vm = new Vue({
  router,
  el:"#app",
})
</script>
</body>
</html>

编程式导航

<!DOCTYPE html>
<html lang="en">
<head>
<script src="../vue.js"></script>
<script src="../vue-router.js"></script>
<style>
  .router-link-active{
      color: red;
  }
</style>
</head>

<body>
<div id="app">
 <ul>
     <router-link to="/position">职位</router-link>
     <router-link to="/search">搜索</router-link>
 </ul>
 <router-view></router-view>

           <button @click="go">编程式导航</button>
</div>

<script>
const position ={
  template:`<div>position</div>`
}
const search = {
  template:`<div>search</div>`
}

var router = new VueRouter({
  mode:'hash',
  routes:[
      {
          path:'/position',
          component:position,
      },
      {
          path:'/search',
          component:search
      }
  ]
})


var vm = new Vue({
  router,
  el:"#app",
  methods:{
      go(){
          // this.$router.push('/position')  //这这两种写法都行, 编程式导航
          this.$router.push({
              path:'/position'
          })
      }
  }
})
</script>
</body>
</html>

命名路由

意思是用name标示路由

<!DOCTYPE html>
<html lang="en">
<head>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active{
           color: red;
       }
   </style>
</head>

<body>
   <div id="app">
      <ul>
          <router-link :to="{name:'ps'}">职位</router-link>  //使用名字访问路由
          <router-link to="/search">搜索</router-link>
      </ul>
      <router-view></router-view>

   </div>
   
<script>
   const position ={
       template:`<div>position</div>`
   }
   const search = {
       template:`<div>search</div>`
   }

   var router = new VueRouter({
       mode:'hash',
       routes:[
           {
               path:'/position',
               name:'ps',        //命名路由
               component:position,
           },
           {
               path:'/search',
               component:search
           }
       ]
   })
  
  
   var vm = new Vue({
       router,
       el:"#app",
   })
</script>
</body>
</html>

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default

<!DOCTYPE html>
<html lang="en">
<head>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active{
           color: red;
       }
   </style>
</head>

<body>
   <div id="app">
      <ul>
          <router-link to="/position">职位</router-link>
          <router-link to="/search">搜索</router-link>
      </ul>
     
      <router-view name="header"></router-view>  //命名视图  @key
      <router-view ></router-view>
      <router-view name="footer"></router-view>
     
   </div>
   
<script>
   const position ={
       template:`<div>position</div>`
   }
   const search = {
       template:`<div>search</div>`
   }

   var router = new VueRouter({
       mode:'hash',
       routes:[
           {
               path:'/position',
               components:{
                   default:{template:'<div>main content</div>'},  //模版和命名视图名字对上  @key
                   header:{template:'<div>header content</div>'},
                   footer:{template:'<div>footer content</div>'}
               }
           },
           {
               path:'/search',
               component:search
           }
       ]
   })
  
  
   var vm = new Vue({
       router,
       el:"#app",
   })
</script>
</body>
</html>

路由组件传参

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。

使用 props 将组件和路由解耦

布尔模式

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>
<body>
   <div id="app">

       <router-link to="/position/35">职位</router-link>
       
       <router-view></router-view>

   </div>
   <script>
       const position = {
           props: ['id'],
           template: `<div>position {{id}}</div>`   // 这块输出: position 35
       }
      
       var router = new VueRouter({
           mode: 'hash',
           routes: [{
                   path: '/position/:id',
                   component: position,
                   props: true,  //@key
               }
               
           ]
       })


       var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</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>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>
<body>
   <div id="app">

       <router-link to="/position">职位</router-link>

       <router-view></router-view>
   </div>

   <script>
       const position = {
           props: ['uname','age'],     //@Key
           template: `<div>{{uname}}-{{age}}</div>`  //这块输出:hanye-20
       }
       const search = {
           template: `<div>search</div>`
       }

       var router = new VueRouter({
           mode: 'hash',
           routes: [{
                   path: '/position',
                   component: position,
                   props:{uname:'hanye',age:20},  //@key
               },
               {
                   path: '/search',
                   component: search
               }
           ]
       })


       var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</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>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>
<body>
   <div id="app">

       <router-link to="/search?keyword=前端">搜索</router-link>

       <router-view></router-view>
   </div>

   
   <script>
       const search = {
           props: ['query'], //@Key
           template: `<div>参数:{{query}}</div>`  //参数:前端
       }

       var router = new VueRouter({
           mode: 'hash',
           routes: [ 
               {
                   path: '/search',
                   component: search,
                   props:(route)=>{ return {query:route.query.keyword}} //@key
               }
           ]
       })


       var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</html>

导航守卫

导航守卫其实也是路由守卫,也可以是路由拦截,我们可以通过路由拦截,来判断用户是否登录,该页面用户是否有权限浏览,就是拦截器,类似钩子之类的。。。

全局路由守卫有2个

  • <span style="color:red">全局前置守卫</span> 应用场景:例如判断用户是否登录之类的
  • <span style="color:red">全局后置守卫</span>

每个守卫方法接收三个参数:

  • to: Route: 到哪个页面去
  • from: Route: 从哪个页面来
  • next: Function:
  • next(): 进行管道中的下一个钩子
  • next(false): 中断当前的导航
  • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto proprouter.push 中的选项。
  • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>

<body>
   <div id="app">
       <router-link to="/position?islogin=1">职位</router-link>
       <router-link to="/login">登录</router-link>

       <router-view></router-view>
   </div>

   <script>
       const position = {
           template: `<div>职位页面</div>`
       }
       const search = {
           template: `<div>登录页面</div>`
       }

       var router = new VueRouter({
           mode: 'hash',
           routes: [{
                   path: '/position',
                   component: position,
               },
               {
                   path: '/login',
                   component: search
               }
           ]
       })

       //@key 全局前置守卫
       router.beforeEach((to, from, next) => {
           if(to.path == "/login") {  //除了`/login`路由不需要判断,其余路由都需要判断
               next()
           } else {
               if (to.query.islogin !=0) {  //1 代表登录, 0 代表没有登录
                   next()
               } else {
                   next('/login')
               }
           }
       })
     
      //@key 全局后置守卫
       router.afterEach((to,from)=>{
           console.log("afterEach")
           alert(1)
       })

       var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</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>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>
<body>
   <div id="app">

       <router-link to="/position?islogin=1">职位</router-link>
       <router-link to="/login">登录</router-link>

       <router-view></router-view>

   </div>

   <script>
       const position = {
           template: `<div>职位页面</div>`
       }
       const search = {
           template: `<div>登录页面</div>`
       }

       var router = new VueRouter({
           mode: 'hash',
           routes: [{
                   path: '/position',
                   component: position,
                   beforeEnter:(to,from,next)=>{  //@key 路由守卫
                       console.log('路由守卫');
                       next()
                   }
               },
               {
                   path: '/login',
                   component: search
               }
           ]
       })
       

          var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</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>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>
<body>
   <div id="app">

       <router-link to="/position?islogin=1">职位</router-link>
       <router-link to="/login">登录</router-link>

       <router-view></router-view>

   </div>

   <script>
       const position = {
           template: `<div>职位页面</div>`,
           beforeRouteEnter(to, from, next) {
               // 在渲染该组件的对应路由被 confirm 前调用
               // 不!能!获取组件实例 `this`
               // 因为当守卫执行前,组件实例还没被创建

               next()
           },
           beforeRouteUpdate(to, from, next) {
               // 在当前路由改变,但是该组件被复用时调用
               // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
               // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
               // 可以访问组件实例 `this`
           },
           beforeRouteLeave(to, from, next) {
               //这个离开守卫通常用来禁止用户在还未保存修改前突然离开,
               //该导航可以通过 next(false) 来取消。
             
               // 导航离开该组件的对应路由时调用
               // 可以访问组件实例 `this`
               let rs = confirm("确认要离开么?")
               if (rs) {
                   next()
               }
           }
       }
       const search = {
           template: `<div>登录页面</div>`
       }

       var router = new VueRouter({
           mode: 'hash',
           routes: [{
                   path: '/position',
                   component: position,
               },
               {
                   path: '/login',
                   component: search
               }
           ]
       })



       var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</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>
   <script src="../vue.js"></script>
   <script src="../vue-router.js"></script>
   <style>
       .router-link-active {
           color: red;
       }
   </style>
</head>

<body>
   <div id="app">

       <router-link to="/position?islogin=1">职位</router-link>
       <router-link to="/login">登录</router-link>

       <router-view></router-view>

   </div>

   <script>
       const position = {
           template: `<div>职位页面</div>`
       }
       const search = {
           template: `<div>登录页面</div>`
       }

       var router = new VueRouter({
           mode: 'hash',
           routes: [{
                   path: '/position',
                   component: position,
                   meta:{   //@key 通过meta字段进行配置
                       auth:true
                   }
               },
               {
                   path: '/login',
                   component: search
               }
           ]
       })

       router.beforeEach((to, from, next) => {
           if(to.meta.auth == true){   //@Key
               console.log('请您先登录');
           }
           next()
       })
       
       var vm = new Vue({
           router,
           el: "#app",
       })
   </script>
</body>
</html
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文转载于前端工匠。如有侵权联系本人立刻删除 一、首先带着问题 要学习vue-ro...
    qiaoguoxing阅读 474评论 0 1
  • HTML部分 Hello App! <!-- 通过传入 `to` 属性指定链接. --> <!-- <rout...
    另一个童话阅读 321评论 0 0
  • 这里说的Vue中的路由是指前端路由,与后端路由有所区别。我们可以使用url来获取服务器的资源,而这种url与资源的...
    一颗脑袋阅读 613评论 0 0
  • 路由 路由起步 监听地址栏的改变.根据改变渲染不同的组件 基本使用下载安装路由 npm install vue-r...
    jie_han阅读 262评论 0 0
  • vue是当前最流行的框架之一,路由也是不可或缺的,怎么样快速搭建路由?在搭建路由路由之前我们需要两个插件(vue....
    夭桃_dd0a阅读 1,200评论 1 8