Skip to content

unplugin-vue-components 插件的用法

unplugin-vue-components是Vue的按需组件自动导入插件。

仓库地址: https://github.com/unplugin/unplugin-vue-components

1. 特性

  • 💚 同时支持Vue 2Vue 3开箱即用。
  • ✨ 同时支持组件和指令。
  • ⚡️ 支持Vite, Webpack, Rspack, Vue CLI, Rollup, esbuild等,unplugin支持。
  • 🏝 可摇树,只注册你使用的组件。
  • 🪐 文件夹名称作为命名空间。
  • 🦾 完整的TypeScript支持。
  • 🌈 流行UI库的内置解析器。
  • 😃 与unplugin-icons图标完美配合。

2. 安装

bash
npm i unplugin-vue-components -D

3. 配置Vite

vite.config.js中添加如下配置:

ts
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    Components({ 
      dts: true,
      resolvers: [
        // 配置ElementPlus组件自动导入
        ElementPlusResolver()
      ]
    })
  ]
})

当项目启动时,插件自动在项目根目录下创建components.d.ts文件,用于声明组件的类型。

4. 使用

直接在vue文件中引入组件即可,无需手动导入。

vue
<template>
  <ElButton>按钮</ElButton>
</template>

<script setup lang="ts">
// nothing 
</script>

5. 个人扩展

以下是个人扩展的自动导入规则,可以根据自己的需求进行修改。

unplugin-vue-components-resolver.ts代码如下:

ts
const kebabCase2Line = (str) => {
  let s = str.replace(/[A-Z]/g, (item) => {
    return '-' + item.toLowerCase()
  })
  if (s.startsWith('-')) {
    s = s.slice(1)
  }
  return s
}

// 自定义unplugin-vue-component规则
const UnpluginVueComponentResolver = {
  /**
   * 自动导入src/icons/svg/**.vue, 使用: 在文件名前加MyIcon + 文件名改为驼峰命名
   *
   * @example
   * // 使用src/icons/svg/app-github.vue时,如下
   * <el-icon>
   *    <MyIconAppGithub />
   * </el-icon>
   *
   * @param componentName
   * @constructor
   */
  CustomSvgIcon: (componentName) => {
    // 自动导入自定义图标
    if (componentName.startsWith('MyIcon')) {
      const componentPath = `src/icons/svg/${kebabCase2Line(componentName.slice(6))}.vue`
      return fileURLToPath(new URL(componentPath, import.meta.url)).replaceAll('\\', '/')
    }
    // 自动导入自定义组件
    if (componentName === 'MyButton') {
      const componentPath = `src/components/button`
      return fileURLToPath(new URL(componentPath, import.meta.url)).replaceAll('\\', '/')
    }
  },

  ElementPlusIconsVue: (componentName) => {
    if (componentName.startsWith('Icon')) {
      return {
        name: componentName.slice(4),
        from: '@element-plus/icons-vue'
      }
    }
  }
}

export default UnpluginVueComponentResolver

vite.config.ts中引入自定义规则:

ts
import UnpluginVueComponentResolver from './unplugin-vue-components-resolver'

export default defineConfig({
  plugins: [
    Components({ 
      resolvers: [
        // 其他的规则
        ...
        // 配置自定义图标组件自动导入
        UnpluginVueComponentResolver.CustomSvgIcon,
        // 配置ElementPlus图标组件自动导入
        UnpluginVueComponentResolver.ElementPlusIconsVue
      ]
    })
  ]
})