Vue-router 基础用法

2023-05-17 16:04:09 浏览数 (2)

# 基础

路由规划配置,router/index.js

代码语言:javascript复制
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/admin',
    name: 'admin',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "admin" */ '../views/Admin.vue'),
  },
];

路由出口导航,App.vue

代码语言:javascript复制
<div id="app">
  <nav>
    <router-link to="/">home</router-link>
    <router-link to="/admin">admin</router-link>
  </nav>
  <router-view></router-view>
</div>

# 动态路由

路由配置

代码语言:javascript复制
// router/index.js
{
  path: '/course/:name',
  component: () => import(/* webpackChunkName: "course" */ '../views/Detail.vue'),
}

路由跳转

代码语言:javascript复制
<router-link :to="`/course/${c.name}`">
  {{ c.name }} - {{ c.price | currency('¥') }}
</router-link>

参数读取

代码语言:javascript复制
<p>{{$route.params.name}}</p>

# 通配符

代码语言:javascript复制
// router/index.js
{
  path: '*',
  component: () => import('../views/404.vue'),
}

# 嵌套路由

代码语言:javascript复制
// router/index.js
{
  path: '/admin',
  name: 'admin',
  // route level code-splitting
  // this generates a separate chunk (about.[hash].js) for this route
  // which is lazy-loaded when the route is visited.
  component: () => import(/* webpackChunkName: "admin" */ '../views/Admin.vue'),
  children: [
    {
      path: '/admin/course/:name',
      name: 'course',
      component: () => import(/* webpackChunkName: "course" */ '../views/Detail.vue'),
    },
  ],
}

使用

代码语言:javascript复制
<div class="admin">
  <img alt="Vue logo" src="../assets/logo.png">
  <a href="">test</a>
  <course-list :courses="courses"></course-list>
  <router-view></router-view>
</div>

# 组件复用注意事项

组件复用时嵌套,局部组件更新时,容器create不动,可以通过监听$route变化实现

代码语言:javascript复制
export default {
  watch: {
    $route: {
      handler: () => {
        console.log('$route change');
      },
      immediate: true,
    }
  },
};

# 编程导航

代码语言:javascript复制
// router.push(location, onComplete?, onAbort?);
// 字符串
router.push('home');
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' } })
// 带参数查询 => /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })

# 路由守卫

全局守卫

代码语言:javascript复制
// router/index.js
// 全局守卫
router.beforeEach((to, from, next) => {
  // ...
  // to: Route 即将要进入的目标 路由对象
  // from: Route 当前导航正要离开的路由
  // next: Function 一定要调用该方法来 resolve 该钩子
});

示例

代码语言:javascript复制
// 全局守卫
const routes = [
  {
    path: '/admin',
    name: 'admin',
    meta: {
      auth: true,
    }
  }
]
router.beforeEach((to, from, next) => {
  if (to.meta.auth) {
    if (window.isLogin) {
      next();
    } else {
      next(`/login?redirect=${to.fullPath}`);
    }
  } else {
    next();
  }
});

路由独享守卫

代码语言:javascript复制
{
  path: '/admin',
  name: 'admin',
  // 全局守卫
  beforeEnter(to, from, next) => {
    if (window.isLogin) {
      next();
    } else {
      next(`/login?redirect=${to.fullPath}`);
    }
  }
}

组件内守卫 可以在路由组件内直接定义一下路由导航守卫

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
代码语言:javascript复制
// Admin.vue
beforeRouteEnter(to, from, next) {
  if (window.isLogin) {
    next();
  } else {
    next(`/login?redirect=${to.fullPath}`);
  }
}

# 数据获取时机

路由导航前

代码语言:javascript复制
// 组件未渲染,通过next传递回调访问组件实例
beforeRouteEnter(to, from, next) {
  getPost(to.params.id, post => {
    next(vm => vm.setData(post));
  });
}
// 组件已渲染,可以访问this直接赋值
beforeRouteUpdate(to, from, next) {
  this.post = null;
  getPost(to.params.id, post => {
    this.setData(post);
    next();
  })
}

路由导航后

代码语言:javascript复制
created() {
  this.fetchData();
},
watch: {
  '$route': 'fetchData',
}

# addRoutes动态路由

代码语言:javascript复制
// 动态添加路由
this.$router.addRoutes([
  {
    path: '/admin',
    name: 'admin',
    // ...
  }]);

# 组件缓存

利用keep-alive做组件缓存,保留组件状态,提高执行效率

代码语言:javascript复制
<keep-alive :include="['admin']" max="10">
  <router-view></router-view>
</keep-alive>

使用include 或 exclude时使用的是组件的name

有两个可利用的钩子:activated、deactivated

# 路由懒加载

路由组件的懒加载能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件

代码语言:javascript复制
() => import(/* webpackChunkName: "group-about" */ "../views/About.vue")

0 人点赞