一、基础

1.编程式导航

  • router-link
  • this.$router.push
  • this.$router.replace
  • this.$router.go
  • params 和 query 的区别

    • params 相当于 post 方法,跳转后url不会拼接参数,但是刷新页面后id会消失
    • query 类似get,跳转后会拼接参数,类似?id=1,非重要性可以这样传,密码之类还是要用params,刷新页面后id还在

      2.路由组件传参

      通过props允许在任何地方使用该组件,使得该组件更容易重用和测试。
      1. const User = {
      2. // 请确保添加一个与路由参数完全相同的 prop 名
      3. props: ['id'],
      4. template: '<div>User {{ id }}</div>'
      5. }
      6. const routes = [{ path: '/user/:id', component: User, props: true }]

      3.不同的历史模式

  • hash模式

    • hash 模式是用createWebHashHistory()创建的,它在内部床底的实际URL之前使用了一个哈希字符#,该种做法对SEO有着不好的影响
  • html5模式

    • **createWebHistory**创建 HTML5 模式,当使用这种历史模式,URL看起来会很正常,例如[https://example.com/user/id](https://example.com/user/id)
    • 但是我们需要在服务器上添加一个简单的回退路由,如果URL不匹配任何静态资源,它应该提供与你的应用程序中的index.html相同的页面,否则会出现404错误。

      二、进阶

      1.导航守卫

  • 全局前置守卫 beforeEach

    1. router.beforeEach((to, from, next) => {
    2. if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
    3. else next()
    4. })
  • 全局解析守卫 beforeResolve

    • 在导航被确认之前,在所有组件内守卫和异步路由组件被解析后, beforeResolve 被正确调用
    • router.beforeResolve 是获取数据或执行任何其他操作的理想位置
  • 全局后置钩子

    • 这些钩子不会接受next函数也不会改变导航本身
    • 它们对分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用
      1. router.afterEach((to, from) => {
      2. sendToAnalytics(to.fullPath)
      3. })
  • 路由独享守卫 beforeEnter

    • 只在进入路由时触发,不会在paramsqueryhash改变时触发
  • 组件内的守卫

    • beforeRouteEnter
    • beforeRouteUpdate
    • beforeRouteLeave

      2. 数据获取

  • 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。

  • 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。

    3. 路由懒加载

    把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应组件,这样才更高效。我们可以用动态导入代替静态导入: ```javascript // 将 // import UserDetails from ‘./views/UserDetails’ // 替换成 const UserDetails = () => import(‘./views/UserDetails’)

const router = createRouter({ // … routes: [{ path: ‘/users/:id’, component: UserDetails }], })

  1. component (和 components) 配置接收一个返回 Promise 组件的函数,Vue Router **只会在第一次进入页面时才会获取这个函数**,然后使用缓存数据。
  2. ```javascript
  3. const UserDetails = () =>
  4. Promise.resolve({
  5. /* 组件定义 */
  6. })

4.动态路由

  • 添加路由 **router.addRoute()**

    • 只注册一个新的路由,当新增加的路由与当前位置相匹配,需要用router.push()router.replace()来手动导航
    • 当我们在导航守卫内部添加或删除路由,不应该调用router.replace(),而是通过返回新的位置来触发重定向
      1. router.beforeEach(to => {
      2. if (!hasNecessaryRoute(to)) {
      3. router.addRoute(generateRoute(to))
      4. // 触发重定向
      5. return to.fullPath
      6. }
      7. })
  • 删除路由

    • 通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由

      1. router.addRoute({ path: '/about', name: 'about', component: About })
      2. // 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
      3. router.addRoute({ path: '/other', name: 'about', component: Other })
    • 通过调用 router.addRoute() 返回的回调

      1. const removeRoute = router.addRoute(routeRecord)
      2. removeRoute() // 删除路由如果存在的话
    • 通过使用 router.removeRoute() 按名称删除路由

      1. router.addRoute({ path: '/about', name: 'about', component: About })
      2. // 删除路由
      3. router.removeRoute('about')
  • 查看现有路由

    • router.hasRoute():检查路由是否存在
    • router.getRoutes()获取一个包含所有路由记录的数组