VueRouter 基础教程系列 ?
路由组件的懒加载
VueRouter 的 component
和 components
配置可以接受一个返回 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)组件)。
扩展的手段有哪些?
- 使用
<router-link>
的v-slot API
获取要跳转路由的解析信息。 - 在 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