Vue-router,在静态切换的世界中翱翔

      发布在:Notes, 前端技术      评论:0 条评论

什么是router

首先知道,Vue是适合在SPA(单页应用)开发中使用的,router能够做到类似html5和jQuery中的pjax(局部刷新,无刷新切换路由)的效果,也是Web应用的路由管理系统。

router快速上手

    import Vue from 'vue'    //引入Vue
    import Router from 'vue-router'    //引入Vue-router
    import HelloWorld from '@/components/HelloWorld'   //引入Components里的HelloWorld.vue 

    Vue.use(Router)    //全局使用路由

    export default new Router({
      routes: [    //路由配置数组
        {
          path: '/',    //路径
          name: 'HelloWorld',    //路由名称
          component: HelloWorld    //模板组件
        }
      ]
    })

尝试在components下新建一个vue模板,然后在index.js里写入

    {
      path:'/Hi',
      name:'Hi',
      component:Hi
    }

在router里根据上面的格式写入路由数组就可以添加路由,并且还要在头部import引入一下import Hi from '@/components/Hi'
然后看到src源码目录下的App.vue,这里是VueRouter的全局页面

<template>
  <div id="app">
<img src="./assets/logo.png" alt="Vue-router,在静态切换的世界中翱翔">
<router-view/>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

我们打开本地阅览,尝试在host后面加上Hi,发现可以跳到刚刚配置的Hi.vue页面,但是只有局部,上面Vue默认的图片还是存在,这就是router的奇妙之处,在刚刚打开的App.vue里,可以看到一句<router-view/>这里就是Vue作为引导,把其他路由页面加入到这个页面的组件。设想我们需要做一个SaaS,就可以在这个页面写导航栏,而剩下的部分则依靠<router-view/>引入切换
- 说到导航栏,其实Vue给我们提供了一个新标签(也可以说是新组件),来制作导航栏
我们在App.vue全局页面里写入

<template>
      <div id="app">
        <img src="./assets/logo.png" alt="Vue-router,在静态切换的世界中翱翔">
        <div>
          <router-link to="/">首页</router-link>
          <router-link to="/Hi">Hi</router-link>
        </div>
        <router-view/>
      </div>
</template>

然后在浏览器中看到,已经有了两个导航按钮
Vue-router,在静态切换的世界中翱翔
我们注意到地址栏,然后点击Hi,发现已经能够无需刷新网页,就可以切换页面和路由,这就是router的强大之处

子路由

在实际构建网站中,我们会遇到二级栏目的情况,例如我们鼠标hover到关于上,会显示出关于我们和联系我们,这两个栏目都隶属于关于,所以就有了子路由的配置
假设我们把导航变成

<div>
  <router-link to="/">首页</router-link>|
  <router-link to="/Hi">Hi页面</router-link>|
  <router-link to="/Hi1">Hi1页面</router-link>|
  <router-link to="/Hi2">Hi2页面</router-link>
</div>

Hi1和Hi2是Hi的子页面,然后我们希望这两个子页在H页面的底部,这种情况的话,我们需要在之前components下的Hi.vue写入

<template>
  <div>
    <h2>{{ msg }}</h2>
    <router-view/>
  </div>
</template>

新建Hi1.vue和Hi2.vue,改改msg做区别,然后在index.js写入路由配置

{
  path:'/Hi',
  name:'Hi',
  component:Hi,
  children:[
    {path:'/Hi1',component:Hi1},
    {path:'/Hi2',component:Hi2},
  ]
}

这样就可以让Hi1和Hi2继承Hi

参数传递

在OA和SaaS开发中,我们经常遇到需要在路由中传递参数的情况,而使用router时<router-link to="/">首页</router-link>|并不能传递参数,那就可以使用之前index.js在配置路由时一直没用过的name

{
  path: '/',
  name: 'youNeed',
  component: HelloWorld
}

假设我们需要在跳转到HelloWorld的时候接收到youNeed
首先在App.vue全局页面写一个假装是面包屑的标签
<p>{{ $route.name }}</p>
保存好,然后就在HelloWorld页面看到我们定义的youNeed
Vue-router,在静态切换的世界中翱翔
然后尝试给有子路由增加name参数

    {
      path:'/Hi',
      name:'Hi',
      component:Hi,
      children:[
        {path:'/hi1',name:'here hi1',component:Hi1},
        {path:'/hi2',name:'here hi2',component:Hi2},
      ]
    }

也能在浏览器中看到效果了。
但是这种方法并不常用,实际开发中,我们的传参是动态的,那就需要改造一下<router-link to="/Hi1">Hi1页面</router-link>
改造成

<router-link :to="{ name:'here hi1',params:{username:'Hansuku',id:'666' }}">Hi1页面</router-link>

这里的name要和index.js路由配置中的name一致,params接数组对象,然后在Hi1模板写入

<h2>{{ msg }}-{{ $route.params.username }}-{{ $route.params.id }}</h2>

这样就能接收到参数了。我们可以通过动态传参的方法去更改username和id的value.

单页面多路由操作

什么是单页面多路由操作,假设一个页面里我们有几个区域,需要引入几个模块,则需要在这个页面

    <router-view/>
    <router-view name="left"/>
    <router-view name="right"/>

然后我们新建一个hello1.vue和hello2.vue写好相应的区分,在index.js中写入路由配置:

    {
      path: '/',
      name: 'youNeed',
      components: {
        defaule:HelloWorld,
        left:Hello1,
        right:Hello2
      }
    }

deafult是默认配置,left和right则对应了刚才的<router-view name="left"/>,刷新就能看到效果了

通过url传递参数

上面提到的传递参数的方法,都是不会在url中体现的,而有的时候我们会喜欢用url来辨识文章或者一些操作,那就需要用url传参
新建一个params.vue的模板

    <template>
      <h2>{{msg}}</h2>
    </template>
    <script>
      export default{
        data(){
          return{
            msg:'parmas pages'
          }
        }
      }
    </script>

index.js引入import Params from '@/components/params
添加路由

    {
      path:'/params/:newsID/:newsTit',
      component:Params
    }

这里的格式是路径+冒号+属性
然后在App.vue导航栏加个<router-link to="/params/200/hansuku you">params</router-link>
params后面跟着的其实就是url参数了,点击试试就能看到路由中已经带了参数。接收方式有很多种,vue的方法是

    <p>newsID:{{ $route.params.newsID }}</p>

配置路由时还能做一些验证,比如newsID必须是数字

    path:'/params/:newsID(\\d+)/:newsTit',

直接括号里面写正则即可

router重定向

重定向即两个不同的路由打开的页面是一样的,类似返回首页的效果。
添加路由规则配置

{
  path:'/goIndex',
  redirect:'/'
}

在App.vue里添加一个导航<router-link to="/goIndex">返回首页</router-link>即可
重定向传参
类似上面的路由传参,添加路由配置

    {
      path:'/goParams/:newsID(\\d+)/:newsTit',
      redirect:'/params/:newsID(\\d+)/:newsTit'
    }

添加导航:<router-link to="/goParams/199/thisIsParams2">params2</router-link>
一样可以传递参数并且跳转。主要,如果是重定向的path里写入了参数传递,而跳转的时候没有带参数,跳转后在页面内会什么都不显示

alias别名

alias别名的方式也可以实现类似重定向的效果,区别在于上面的redirect跳转后url内的地址就是重定向的地址,不会有区别,而alias别名是一个新的url地址,但是页面是一样的

    {
      path:'/Hi1',
      name:'Hi1',
      component:Hi1,
      alias:'/Hansuku'
    }

这个时候,导航<router-link to="/Hi1">Hi1</router-link><router-link to="/Hansuku">Hansuku</router-link>跳转的页面内容是一样的,但是地址是http://localhost:8080/#/Hi1http://localhost:8080/#/Hansuku

路由过渡动画

在路由切换的时候,由于用户体验不到刷新感,我们需要增添一些过渡动画来提升用户体验
在router-view标签即页面会切换内容的地方包裹一层transition

    <transition name="fade" mode="out-in">
      <router-view/>
    </transition>

name代表渐入渐出式,mode是出入循序

    out-in 代表先出后入
    in-out 代表先入后出

然后增加css

    .fade-enter {
      opacity:0;
    }
    .fade-leave{
      opacity:1;
    }
    .fade-enter-active{
      transition:opacity .5s;
    }
    .fade-leave-active{
      opacity:0;
      transition:opacity .5s;
    }

这样就有了一个比较基础的切换效果

路由模式

    export default new Router({
      mode:'history',
      routes: [
        {
          path: '/',    //路径
          name: 'HelloWorld',    //路由名称
          component: HelloWorld    //模板组件
        }
      ]
    })

这里的mode代表路由模式,加上mode:'history'后,本身我们路由里面会带一个#号,现在就消失了,mode还有一个模式mode:'hash'这个模式会带上#号,选择上个人喜好就好。

404处理

VUE如果不配置,发生了404的情况下用户会比较懵逼的,不知道网页出了什么错,就是不显示
添加配置

    {
      path:'*',
      component:Error
    }

*就是对所有没有的路由展示Error页面
引入import Error from '@/components/Error'
然后自由配置一个404模板即可

路由中的钩子函数

钩子函数能够监听两个状态,一个是进路由之前,一个是离开路由之前,配置钩子函数可以在index中写,也可以在模板中写
index.js中的钩子函数

    {
      path:'/params/:newsID(\\d+)/:newsTit',
      component:Params,
      beforeEnter:(to,from,next)=>{
        console.log(to),
        console.log(from),
        next(true)
      }
    }

next(true)是相当于一个开关的角色,如果换成了false就不会进行跳转,如果不写也会导致不跳转
模板中的钩子函数

    export default{
        data(){
          return{
            msg:'parmas pages'
          }
        },
        beforeRouteEnter:(to,from,next)=>{
            console.log("进入");
            next()
        },
        beforeRouteLeave:(to,from,next)=>{
            console.log("离开");
            next()
        }
      }

编程式导航

假设需要一个后退和前进的按钮(类似chrome左上角的按钮)
html

    <button @click="goBack">后退</button>
    <button @click="goDo">前进</button>

script

    export default {
      name: 'app',
      methods:{
        goBack(){
          this.$router.go(-1);
        },
        goDo(){
          this.$router.go(1);
        }
      }
    }

需要注意的是,在没有历史记录的情况下$router.go是不起作用的
- 编程式跳转

    <button @click="goHome">返回首页</button>
goHome(){
      this.$router.push('/');
    }

方法跟$router.go大同小异,可以push任意页面

Responses