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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

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