使用 unplugin-vue-components 按需引入组件(内附实现原理)

简介: 使用 unplugin-vue-components 按需引入组件(内附实现原理)

我们开发 Vue 项目时,一般会使用组件库进行开发,组件库有两种加载方式:全局引入按需引入

全局引入组件库,使用起来就非常方便,但是坏处就是产物体积大,对性能要求较高的项目不友好。

按需引入,可以减少体积大小,但需要通过以下方式加载组件:


import Button from 'ant-design-vue/lib/button';
import 'ant-design-vue/lib/button/style';
// 或者 ant-design-vue/lib/button/style/css 加载 css 文件

引入组件还需要引入样式,非常麻烦,因此有了 babel-plugin-import 来进行按需加载,加入这个插件后,可以省去 style 的引入。


import { Button } from 'ant-design-vue';

但这种仍然需要手动引入组件,而且还必须使用 babel

而  unplugin-vue-components 可以不需要手动引入组件,能够让开发者就像全局组件那样进行开发,但实际上又是按需引入,且不限制打包工具,不需要使用 babel


使用效果


Antd Vuevite 为例:


import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
export default {
  plugins: [
    Components({
      resolvers: [
          AntDesignVueResolver()
      ],
    }),
  ],
};

这样就能自动引入 Antd Vue 的组件,不需要手动 import 组件以及组件样式,使用起来就像全局组件一样,但这是按需自动引入,可以减少产物大小。


<template>
  <a-button>按钮</a-button>
</template>

这样直接使用即可

解析器


unplugin-vue-components 为主流的 UI 组件库提供了内置的支持,通过使用对应 UI 组件库的解析器(resolvers),就能自动引入对应的组件库组件及样式

解析器可以是一个函数或者是对象

以对象为例:


{
    type: 'component',
    resolve: (name: string) => {
        const map = {
            'Abutton': 'Button'
        }
        const path = `ant-design-vue/es`
        const name = map[name]
        return {
          // Button
          name,   
          // ant-design-vue/es
          from: path, 
          // ant-design-vue/es/button/style/css
          sideEffects: `ant-design-vue/es/${name.toLowerCase()}/style/css`, 
        }
      }
    },
  }
}

resolve 是一个函数,当遇到 a-button 时,就会调用该函数,入参是 AButton

函数需要返回一个对象,例如:


{
  name: 'Button',   
  from: 'ant-design-vue/es',  
  sideEffects: 'ant-design-vue/es/button/style/css',  
}

这样 unplugin-vue-components  就会加入以下代码:


import { Button } from 'ant-design-vue/es'
import 'ant-design-vue/es/button/style/css'

ant-design-vue/es/button/style/css 中,引入了 Button 组件相关的样式:


import '../../style/default.css';
import './index.css';

一般情况按需引入组件,需要把组件的样式也引入进来,这就是 sideEffects 的作用。


实现原理


可能大家会想到,将 Vue 处理成以下内容即可:


<template>
  <a-button>按钮</a-button>
</template>
<script setup>
import { Button as AButton } from 'ant-design-vue/es'
import 'ant-design-vue/es/button/style/css'
</script>

看起来可行,但其实不行,因为你 script 有普通的写法和 setup 写法,如果要做,得兼容两种情况,比较复杂。

其实 unplugin-vue-components 的实现非常简单。我们直接来看看 Vue 编译后的代码

1686404724870.png

可以看到,全局组件编译后会用 resolveComponent 包裹,该函数在 Vue 官网有说明,就是按名称找到已注册的全局组件。

unplugin-vue-components 只需要正则匹配 _resolveComponent,拿到入参 a-button,然后根据将名称标准化为 AButton,然后交给解析器,解析器会返回如下对象:


{
  name: 'Button',   
  from: 'ant-design-vue/es',  
  sideEffects: 'ant-design-vue/es/button/style/css',  
}

然后修改 Vue 编译后的代码(unplugin-vue-components 会在 Vue 插件之后执行

1686404700366.png

引入以下代码:


import { Button as __unplugin_components_0 } from 'ant-design-vue/es';
import 'ant-design-vue/es/button/style/css';
const _sfc_main = {}

并且_resolveComponent 替换成 __unplugin_components_0

这就将 a-button 组件的全局使用,转换成了按需引入的方式


局限性


unplugin-auto-import 看起来非常厉害,但它也有些局限性:

  • 不能作用于 JSX,因为插件只处理 template 模板的代码。不过JSX 则需要配合 unplugin-auto-import(用于自动引入变量)
  • 在 Vite 中 CSS 无法 tree shaking,不过这个是 Vite 的问题。但 JS 仍然是可以 tree shaking,相对于全局注册组件,对构建产物体积的优化还是非常可观的

总结


使用 unplugin-vue-components 可以非常方便地实现按需引入组件的功能,从而减小项目体积、加快项目加载速度,提升用户体验。

它通过正则匹配 Vue 的全局组件(编译后使用 _resolveComponent 包裹),然后引入组件并替换 _resolveComponent,因此这种方式,只适用于 template 模板编译后的代码,JSX 的自动引入,则需要配合 unplugin-auto-import(用于自动引入变量)

实际上, unplugin-vue-components 还能自动引入项目 components 目录下的组件,同时也支持自定义指定的自动按需引入,更多内容请查看  unplugin-vue-components文档

如果这篇文章对您有所帮助,可以点赞加收藏👍,您的鼓励是我创作路上的最大的动力。也可以关注我的公众号订阅后续的文章:Candy 的修仙秘籍(点击可跳转)

另外,想要米哈游/腾讯内推的,也可以关注公众号找我内推

目录
打赏
0
0
0
0
3
分享
相关文章
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
162 0
|
3月前
|
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
350 4
Vue 表情包输入组件的实现代码:支持自定义表情库、快捷键发送和输入框联动的聊天表情解决方案
本文详细介绍了在 Vue 项目中实现一个功能完善、交互友好的表情包输入组件的方法,并提供了具体的应用实例。组件设计包含表情分类展示、响应式布局、与输入框的交互及样式定制等功能。通过核心技术实现,如将表情插入输入框光标位置和点击外部关闭选择器,确保用户体验流畅。同时探讨了性能优化策略,如懒加载和虚拟滚动,以及扩展性方案,如自定义主题和国际化支持。最终,展示了如何在聊天界面中集成该组件,为用户提供丰富的表情输入体验。
111 8
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
74 1
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
44 0
基于 ant-design-vue 和 Vue 3 封装的功能强大的表格组件
VTable 是一个基于 ant-design-vue 和 Vue 3 的多功能表格组件,支持列自定义、排序、本地化存储、行选择等功能。它继承了 Ant-Design-Vue Table 的所有特性并加以扩展,提供开箱即用的高性能体验。示例包括基础表格、可选择表格和自定义列渲染等。
186 6
vue2和vue3的响应式原理有何不同?
大家好,我是V哥。本文详细对比了Vue 2与Vue 3的响应式原理:Vue 2基于`Object.defineProperty()`,适合小型项目但存在性能瓶颈;Vue 3采用`Proxy`,大幅优化初始化、更新性能及内存占用,更高效稳定。此外,我建议前端开发者关注鸿蒙趋势,2025年将是国产化替代关键期,推荐《鸿蒙 HarmonyOS 开发之路》卷1助你入行。老项目用Vue 2?不妨升级到Vue 3,提升用户体验!关注V哥爱编程,全栈开发轻松上手。
231 2
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等