2×6 VueRouter – 进阶 – 路由懒加载 与 RouterLink 扩展

VueRouter 基础教程系列 ?

路由组件的懒加载

VueRouter 的 componentcomponents 配置可以接受一个返回 promise 组件的函数,再结合构建工具 (webpack) 的 “代码分割”与“动态导入” 特性,便可以实现路由组件的懒加载

懒加载路由组件可以优化打包应用时每个独立包的大小,通过多次异步请求来来减少一次请求资源的大小、提高首次加载速度。

// UserDetails 是返回带 Promise 组件的函数
const UserDetails = () => import('./views/UserDetails')

const router = createRouter({
  // ...
  routes: [{ path: '/users/:id', component: UserDetails }],
})
复制代码

粒度过低的代码分割也并不总是合理,综合考量打包的体积以及加载速度间的关系,有时将多个组件按“组”进行代码分割会显得更加有效。

例如,我们可以将一个嵌套路由作为一个,统一打包在一起,然后这个组本身采用懒加载进行动态导入。

实现多个组件的按组分块需要使用构建工具的 “命名 chunk” 功能,Webpack 会将多个异步组件按照相同的 “块名称” 进行合并。

const UserDetails = () =>
  import(/* webpackChunkName: "group-user" */ './UserDetails.vue')
const UserDashboard = () =>
  import(/* webpackChunkName: "group-user" */ './UserDashboard.vue')
const UserProfileEdit = () =>
  import(/* webpackChunkName: "group-user" */ './UserProfileEdit.vue')
复制代码

俗称 Webpack 的注释魔法 (magic)

扩展 <router-link>

意义?

满足更多的使用场景,例如:跳转外部链接、不同的打开方式、用于扩展其它组件(例如菜单组件、导航(nav)组件)。

扩展的手段有哪些?

  1. 使用 <router-link>v-slot API 获取要跳转路由的解析信息。
  2. 在 Composition API 中使用 useLink(props) 方法来获取 router-link 组件内部的行为与信息。

扩展的结构设计

···text
RouterLink | a
–> AppLink.vue (处理内部链接、外部链接、打开方式)
-> NavLink.vue | Menu.vue (作为不同导航组件的组成部分,用于相关的定制需求)
···

一个简单的示例

<template>
  <a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">
    <slot />
  </a>
  <router-link
    v-else
    v-bind="$props"
    custom
    v-slot="{ isActive, href, navigate }"
  >
    <a
      v-bind="$attrs"
      :href="href"
      @click="navigate"
      :class="isActive ? activeClass : inactiveClass"
    >
      <slot />
    </a>
  </router-link>
</template>

<script>
import { RouterLink } from 'vue-router'

export default {
  name: 'AppLink',

  props: {
    // 如果使用 TypeScript,请添加 @ts-ignore
    ...RouterLink.props,
    inactiveClass: String,
  },

  computed: {
    isExternalLink() {
      return typeof this.to === 'string' && this.to.startsWith('http')
    },
  },
}
</script>
复制代码

如果是 Composition API

import { RouterLink, useLink } from 'vue-router'

export default {
  name: 'AppLink',

  props: {
    // 如果使用 TypeScript,请添加 @ts-ignore
    ...RouterLink.props,
    inactiveClass: String,
  },

  setup(props) {
    // toRef 允许我们提取一个 prop 并保持它的响应
    // https://v3.vuejs.org/api/refs-api.html#toref
    const { navigate, href, route, isActive, isExactActive } = useLink(
      toRef(props, 'to')
    )

    // profit!

    return { isExternalLink }
  },
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享