1. 安装
    cnpm install --save vue-router
  2. 引入
    // main.js
 import VueRouter from 'vue-router';
 Vue.use(VueRouter);
  1. 使用

       // 引入组件

       import comA from './components/comA';
       import comB from './components/comB';
       
       // 定义路由
       const routes = [
         {
           path: '/comA',
           component: comA
         },
         {
           path: '/comB',
           component: comB
         },
         {
           path: '*',
           redirect: '/comA'
           // 首次加载显示 comA (首页) 没有匹配到路径也显示首页
           // 重定向, 如果以上配置路由都没有匹配到, 就显示 * 中定义的路由  即 /comA
         }
       ];
       
       // 实例化
       const router = new VueRouter({
         routes: routes
       });
       
       // 挂载
       new Vue({
         el: '#app',
         // 将上一步的 router 放入这个根实例中
         router,
         store,
         components: { App },
         template: '<App/>'
       });
       
       // 切记: 在 App.vue 中 添加一行   <router-view></router-view>
       // router 是若干路由的管理者
       // route 是一个路由的映射

基本操作

HTML

    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      </p>
        
      <!-- 路由出口 -->
      <router-view></router-view>
    </div>
    
    <!--
        解释: <router-link to="/foo">Go to Foo</router-link>
        - router-link  => 将会被解析成 a 标签
        - to: ""         => 指定这个 a 会跳往何处
    
        ---------------------------------
        解释: <router-view></router-view>
        - 路由匹配到的组件将渲染在这里
            例如, 点击 Foo, <router-view> 里面就显示 Foo 的内容
    -->

JS

    // router.js
    import Vue from 'vue';
    import VueRouter from "vue-router";
    Vue.use(VueRouter);
    
    // 在此导入 组件
    import Foo from '../components/foo';
    import Bar from '../components/bar';
    
    // 配置路由信息
    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    ]
    
    // 将路由构造出来
    const router = new VueRouter({
      routes
    })
    
    // 导出
    // 在 main.js 中引入, 放入 App Vue 实例配置对象中
    export default router;
// main.js
import router from './router/index';

new Vue({
  el: '#app',
  router,   // 写入 Vue 根实例的配置项中
  components: { App },
  template: '<App/>',
  store
});

// 注意 ****
// 写入根实例的配置项之后, 我们可以在任何组件内通过 this.$router 访问路由器,
//                       也可以通过 this.$route 访问当前路由
完成以上两步HTML和JS的操作之后, 在页面中, 点击 Go to Foo会显示Foo的内容, 另外一个也一样, 同时只会显示一个.

动态路由

在路由跳转的时候, 需要传递值:
// 如果某个路由跳转需要传值, 修改路径配置
// <router-link to="/user/123">About</router-link>
const route = {
    path: '/user/:id',
    // ... 其他
}
/*
    解释:  '/user/:id'
    - : 冒号标记参数, 这个参数会被设置到 $route.params 中, 上例中为: {id: 123}
*/

 <li role="presentation" v-for="id in 5" :key="id">
     <router-link :to="{name: 'news', params:{id: id}, query:{user: 123}}">News{{id}}</router-link>
</li>
<!-- 
    这里循环了五个路由, 他们都是属于 news 下的子路由, 相当于在 news 组件中, 新闻列表, 每一条对应着一条新闻,当我们点击的时候, 需要向服务器发起请求, 指定是那一条新闻的数据请求回来渲染, 那么 params 中存放的就是这样的数据, id 就指明了是那一条新闻, 这个 id 我们可以将其拼接在新闻详情请求地址后面, 拿回数据.
    我们可以使用 watch 来监听这个 $route , 可以清楚的看见路由是如何切换的
    name: news 是在 VueRouter 中定义路由的时候, 给 news 路由给了一个名字, 在这里我们就直接使用这个名字就能找到这个路由
    query 则是查询参数
    http://localhost:8080/news/5?user=123    在 url 中, 也会拼接上我们传递的数据
-->

你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:

模式 匹配路径 $route.params
/user/:username /user/evan { username: 'evan' }
/user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' }

除了 route 对象还提供了其它有用的信息,例如,route.hash 等等。

监听路由变化

watch: {
    $route (to, from) {
        // to: 路由跳往何处
        // from: 从哪里跳过来的
    }
}

后面还可以使用 路由守卫.

嵌套路由

// 在用户界面下, 还有两个功能, 需要通过点击切换
// 这就需要用到嵌套路由

// 先引入需要跳转的组件
import User from './components/User';
  import UserAdd from './components/user/UserAdd';
  import UserList from './components/user/UserList';


// 在 user 下添加一个 children 数组, 里面存放子路由的路径和组件
{
    path: '/user',
    component: User,
    children: [
      {
        path: 'useradd',
        component: UserAdd
      },
      {
        path: 'userlist',
        component: UserList
      }
    ]
  }

// 其他的不用变

在 user 中:

<div class="user">
    <div class="left">
        <ul>
            // 跳转处添加好链接
            <li><router-link to="/user/useradd">添加用户</router-link></li>
            <li><router-link to="/user/userlist">用户列表</router-link></li>
        </ul>
    </div>
    <div class="right">
        在路由需要展示的地方加上 router-view
        <router-view></router-view>
    </div>
</div>

// 如果需要点击user默认显示第一条, 在 App.vue 中这样设置: 
<router-link to="/user/useradd">User ----</router-link>

不必担心在某一个router-view中显示不应该显示的组件, 因为在路由的配置中他就是有层级的, 不属于同一个层级的路由不会被匹配到而显示出来, 所以只要嵌套层级放对了, 就不会出问题.

命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

这跟代码调用 router.push() 是一回事:

router.push({ name: 'user', params: { userId: 123 }})

这两种方式都会把路由导航到 /user/123 路径。

命名视图

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

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components配置 (带上 s):

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})
// 指定组件显示的位置.
// router-view a 中显示 Bar
// router-view b 中显示 Baz

重定向和别名

重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

重定向的目标也可以是一个命名的路由:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

甚至是一个方法,动态返回重定向目标:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
        if(xx){
            return {
                path: '/'
                ....
            } 
        }
    }}
  ]
})

// 如果没有匹配到已经配置的路由, 就会进入重定向路由, 我们可以判断一下, 如果路径是 / 我们就去 首页
// 如果不是, 那说明路由路径有问题, 我们就重定向到 error 页面
// redirect: path | { 配置对象 } | funtion

命名视图

在某个路径下, 需要展示两个或以上的组件, 这时候就需要路由命名

// 配置项需要修改
routes: [
    {
        path: '/home',
        components: {
            left: about,
            default: home
        }
    },
    {
        path: 'about',
        components: {
            left: home
            default: about
        }
    }
]

// router-view 也需要
<router-view name="left"></router-view>
<router-view></router-view>
// 这时候, 当我们点击 home 的时候, 第一个(left)显示 user, 第二个(default)显示 home

get传值

// main.js 中, 正常配置, 无需添加任何东西
const routes = [
    {
        path: '/comC',
        component: comC
    },
];

// 跳转的地方如此配置: 
<router-link :to="'/comC?id=' + index" key={{index}}>{{ item }}</router-link>

// 在 C 组件中: 
this.$route.query.id 
// 可以获取到传递过来的值

编程式路由跳转


    this.$router.push({path: '/comB'})
    
    // 前提是 在 main.js 中, 有这个命名了的路由
    this.$router.push({name: 'comA'})
    
    // 传递参数
    this.$router.push({name: 'comA', params: { userId: 123 }})

    this.$router.replace('/all')
    // 区别
    // push: [a, b, c]   => [a, b, c, d]
    // replace: [a, b, c] => [a, b, d] 

hash路由

默认情况下就是 hash 路由: http://localhost:8080/comC?id=499#/comA

history模式: http://localhost:8080/comC?id=499

直接时候用默认的router-link名称添加active样式

当router-link被激活的时候, 会给标签添加上两个样式

router-link-active router-link-exact-active

其中exact为精确匹配,
没有exact的为模糊匹配, 即'/', '/a', '/abc', 当最后一个被激活的时候, 前面两个也会被激活.这个特性是有用的.
精确匹配也是有特定的使用场景的.
但是有时候我们会觉得这个class太长了:

// 在 router.js 中配置项设置
linkActiveClass: 'active',
linkExactActiveClass: 'exact-active',

通过这样的方式可以修改.