【Vue2】vue-router基础知识点梳理

651 阅读2分钟

介绍

Vue Router 是 Vue.js 官方的路由管理器。

所谓路由,是指解析地址并获取资源的过程。

基础

安装

npm i -S vue-router

使用

// main.js
// 导入vue和vue-router
import Vue from 'vue';
import VueRouter from 'vue-router';
// 安装vue-router,实则调用其install方法
Vue.use(VueRouter);
// 导入组件
import Foo from '@/components/foo';
import Bar from '@/components/bar';
import Logs from '@/components/logs';
import NotFound from '@/components/not-found';
// 创建路由匹配表
const routes = [
  // 匹配到'/foo'时,切换为组件Foo
  { path: '/foo', nama: 'Foo', component: Foo },
  // 匹配到'/bar'时,切换为组件Bar
  { path: '/bar', nama: 'Bar', component: Bar },
  // 匹配到`/logs/aaa/bbb`时,切换为组件Logs,
  // 其中,参数user等于'aaa',参数date等于'bbb'
  { path: '/logs/:user/:date', name: 'Logs', component: Logs },
  // 匹配到'/redirect'时,URL改变并导航至'/foo'
  { path: '/redirect', redirect: '/foo' },
  // 匹配到'/alias'时,URL不变但导航至'/foo'
  { path: '/alias', alias: '/foo' },
  // 匹配所有路径,因为越后面的路由优先级越低,所以常用于监听404
  { path: '*', nama: 'NotFound', component: NotFound },
];
// 创建路由实例
const router = new VueRouter({ routes });
// 创建vue实例, 并将router绑定到该实例上
const app = new Vue({
  router,
}).$mount('#app');
<template>
  <div id="app">
    <router-link to="/foo">Route to Foo</router-link>
    <router-link to="/bar">Route to Bar</router-link>
    <a @click="routeToLogs('xiaoming', '2020-08-15')">Route to Logs</a>
    <router-view />
  </div>
</template>
<script>
export default {
  watch: {
    // 监测路由变化
    $route(to, from) {
      console.log(to.params); // 路由参数
      console.log(to.query); // 查询参数
    },
  },
  methods: {
    // 路由跳转
    routeToLogs(user, date) {
      this.$router.push({
        name: 'Logs',
        params: {
          user,
          date,
        },
        query: {},
      });
    },
  },
};
</script>

进阶

编程式导航

const router = this.$router;
// push:导航至指定路径,并添加导航记录
router.push('/user');
router.push({
  name: 'User',
  params: { userId: '123' },
  query: { plan: 'private' },
  onComplete() {},
  onAbort() {},
});
// replace:导航至指定路径,并替换当前导航记录
router.replace({});
// go:前进相应步数,为负数则后退
router.go(2);
router.go(-1);

导航守卫

导航守卫方法通常接受三个参数:

  • to:当前匹配到的路由。
  • from:原路由。
  • next:调用该方法,才会“通过”守卫,成功跳转。
// router.js
new VueRouter({
  routes: [
    {
      // 路由独享守卫
      beforeEnter(to, from, next) {},
    },
  ],
  // 全局守卫
  beforeEach(to, from, next) {},
  beforeResolve(to, from, next) {},
  afterEach(to, from, next) {},
});

// component.vue
export default {
  name: 'Component',
  // 组件内守卫
  beforeRouteEnter(to, from, next) {},
  beforeRouteUpdate(to, from, next) {},
  beforeRouteLeave(to, from, next) {},
};

注意,路由参数和查询参数的改变,不会触发导航守卫。

命名视图

// ComponentDefault、ComponentA和componentB,
// 分别被渲染到对应name的<router-view>中
const routes = [
  {
    path: '/',
    components: {
      default: ComponentDefault,
      viewA: ComponentA,
      viewB: ComponentB,
    },
  },
];
<div id="app">
  <!--name默认为default-->
  <router-view />
  <router-view name="viewA" />
  <router-view name="viewB" />
</div>

动态路由匹配

获取路由参数:

this.$router.params;

路由组件传参:

const routes = [
  // 布尔模式:将路由参数传递给User的props
  { path: '/user/:id', component: User, props: true },
  // 对象模式:将props传递给User的props
  { path: '/user/:id', component: User, props: {} },
  // 函数模式:将props的返回值传递给User的props
  { path: '/user/:id', component: User, props(route) {} },
];

嵌套路由匹配

// 匹配到'/user/:id/profile'时,
// 组件User会被渲染到组件App的<router-view>中,
// 组件UserProfile会被选绕到组件User的<router-view>中
const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        path: 'profile',
        component: UserProfile,
      },
      {
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
];
<!--App.vue-->
<div id="app">
  <router-view />
</div>

<!--User.vue-->
<div id="user">
  <h2>UserID: {{ $route.params.id }}</h2>
  <router-view />
</div>

路由命名

const route = {
  name: 'foo',
};
this.$router.push({
  name: 'foo',
});

路由元信息

const route = {
  meta: {
    requireAuth: true,
    requireLog: true,
  },
};

路由滚动行为

// savedPosition是滚动条位置(仅前进/后退时可用)
new VueRouter({
  scrollBehavior(to, from, savedPosition) {
    // 返回滚动位置
    return {
      x: 0,
      y: 32,
    };
  },
});

路由过渡动效

详见此文

<!--App.vue-->
<transition>
  <router-view></router-view>
</transition>

路由懒加载

方法一,使用 Vue 异步组件:

const route = {
  path: '/',
  component: () =>
    Promise.resolve({
      // 组件定义对象
    }),
};

方法二,使用import语法:

const route = {
  path: '/',
  component: () => import('@/components/component-name'),
};

API

router

// 配置项
const router = new VueRouter({
  mode,
  base,
  routes,
  linkActiveClass,
  linkExactActiveClass,
  parseQuery,
  stringifyQuery, //自定义解析/反解析函数
  scrollBehavior,
});

// 实例属性和方法
router.app; // 挂载的Vue根实例
router.mode;
router.currentRoute; // 当前对应的路由信息对象
router.beforeEach();
router.beforeResolve();
router.afterEach();
router.push();
router.replace();
router.forward();
router.back();
router.getMatchedComponents(); // 返回当前路由匹配的组件数组
router.addRoutes(routes); // 添加路由规则
router.onReady(callback);
router.onError(callback);

// 在组件中,通过this.$router访问router
this.$router;

route

// 配置项
const route = {
  path,
  name,
  meta,
  redirect,
  alias,
  children,
  component,
  components,
  props,
  beforeEnter,
  caseSensitive, // 是否大小写敏感
};

// 实例属性
route.path; // 路由路径
route.fullPath; // 完整路径
route.hash; // 路由hash值
route.params;
route.query;
route.name; // 路由名
route.redirectedFrom; // 重定向的来源路由

// 在组件中,通过this.$route访问当前匹配到的route
this.$route;

// props
to, replace, append // 传入path或route
tag // 渲染成的标签种类
active-class, exact-active-class // 激活样式
exact // 是否精确匹配,默认为包含匹配(/a/b也会匹配到/a)
event // 触发导航的事件,默认为click

name; // 视图名

参考