📝作用

Vue按需自动导入组件
特点:
💚 支持Vue 2和Vue 3,开箱即用。
✨ 支持组件和指令。
⚡️ 基于unplugin技术,支持Vite、Webpack、Vue CLI、Rollup、esbuild等构建工具。
🏝 只导入你使用的组件,实现按需加载。
🪐 使用文件夹名称作为命名空间。
🦾 完全支持TypeScript。
🌈 针对流行UI库提供内置解析器。
😃 与unplugin-icons完美协同工作。

📝下载

npm i -D unplugin-vue-components

🔖 vite

// vite.config.ts
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({ /* options */ }),
  ],
})

🔖 Rollup

// rollup.config.js
import Components from 'unplugin-vue-components/rollup'

export default {
  plugins: [
    Components({ /* options */ }),
  ],
}

🔖 webpack

// webpack.config.js
module.exports = {
  /* ... */
  plugins: [
    require('unplugin-vue-components/webpack')({ /* options */ }),
  ],
}

🔖 Nuxt

对于Nuxt,您可能不需要使用这个插件。可以使用@nuxt/components代替。
@nuxt/components是Nuxt.js的官方模块,它提供了类似按需导入组件的功能。通过@nuxt/components,您可以在需要时动态地导入和注册组件,而不需要使用额外的插件。这个模块与Nuxt.js紧密集成,提供了更简单和方便的方式来管理和使用组件。

🔖 Vue CLI

// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      require('unplugin-vue-components/webpack')({ /* options */ }),
    ],
  },
}

🔖 esbuild

// esbuild.config.js
import { build } from 'esbuild'

build({
  /* ... */
  plugins: [
    require('unplugin-vue-components/esbuild')({
      /* options */
    }),
  ],
})

📝 用法

在template中像平常一样使用组件,它将按需导入组件,不再需要导入和注册组件!如果您异步注册父组件(或懒加载路由),自动导入的组件将与其父组件一起进行代码拆分。

它将自动会把这段代码:

<template>
  <div>
    <HelloWorld msg="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

转换成:

<template>
  <div>
    <HelloWorld msg="Hello Vue 3.0 + Vite" />
  </div>
</template>

<script>
import HelloWorld from './src/components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

请注意,默认情况下,此插件将在 src/components 路径下导入组件。您可以使用 dirs 选项进行自定义。
这意味着 src/components 目录下的所有vue文件会自动注册为组件,可以直接使用,无需导入与注册。

📝 TypeScript

要为自动导入的组件获取TypeScript支持,Vue 3有一个扩展全局组件接口的Pull Request。目前,Volar已经支持了这种用法。如果您正在使用Volar,可以按照以下方式更改配置来获取支持。

Components({
  dts: true, // 默认情况下启用,如果安装了 `typescript`
})

一旦设置完成,将生成一个 components.d.ts 文件,并自动更新其中的类型定义。根据您的需求,您可以选择将其提交到git中或不提交。

请确保将 components.d.ts 添加到您的 tsconfig.json 的 include 中。

📝 从UI库导入

我们内置了对一些流行UI库的解析器,例如Vuetify、Ant Design Vue和Element Plus,您可以通过以下方式启用它们:

支持的解析器列表请查看官方文档:

https://github.com/antfu/unplugin-vue-components

// vite.config.js
import Components from 'unplugin-vue-components/vite'
import {
  AntDesignVueResolver,
  ElementPlusResolver,
  VantResolver,
} from 'unplugin-vue-components/resolvers'

// your plugin installation
Components({
  resolvers: [
    AntDesignVueResolver(),
    ElementPlusResolver(),
    VantResolver(),
  ],
})

您也可以快速编写自己的解析器:

Components({
  resolvers: [
    // 导入 Vant 组件的示例
    (componentName) => {
      // 这里的 `componentName` 始终是以大写驼峰命名法表示的
      if (componentName.startsWith('Van'))
        return { name: componentName.slice(3), from: 'vant' }
    },
  ],
})

🔖Ant Design Vue示例

Ant Design Vue按需导入样式目前支持css和less,然后直接在页面中使用组件库组件即可,会按需导入组件并加载样式

import { AntDesignVueResolver } from "unplugin-vue-components/resolvers"
export default defineConfig({
  plugins: [
    ...
    Components({
      resolvers: [
        AntDesignVueResolver({
          //  importStyle?: boolean | 'css' | 'less'
          importStyle: "less"
        })
      ]
    })
  ]
})

AntDesignVueResolver配置项

export interface AntDesignVueResolverOptions {
  /**
   * 排除不需要自动导入的组件
   *
   * @default []
   */
  exclude?: string[]
  /**
   * 是否同时导入样式
   *
   * @default 'css'
   */
  importStyle?: boolean | 'css' | 'less'
  /**
   * 解析 `ant-design-vue` 图标
   *
   * 需要安装 `@ant-design/icons-vue` 包
   *
   * @default false
   */
  resolveIcons?: boolean

  /**
   * @deprecated 请使用 `importStyle: 'css'` 替代
   */
  importCss?: boolean
  /**
   * @deprecated 请使用 `importStyle: 'less'` 替代
   */
  importLess?: boolean

  /**
   * 使用 CommonJS 构建,默认为 false
   */
  cjs?: boolean

  /**
   * 重命名包名称
   *
   * @default 'ant-design-vue'
   */
  packageName?: string
}

🔖element-plus示例

import { ElementPlusResolver } from "unplugin-vue-components/resolvers"
export default defineConfig({
  plugins: [
    ...
    Components({
      resolvers: [
        ElementPlusResolver({
          importStyle: "sass"
        })
      ]
    })
  ]
})

⚠️ 不再接受将新解析器添加到这个仓库的请求

来自官方文档:
感谢您对该项目的贡献兴趣!
由于新增解析器所带来的维护负担,⚠️ 我们不再接受将新解析器添加到这个仓库的请求。
相反,我们建议UI库维护并发布自己的解析器,因为解析器与其结构更加紧密相关。
我们建议将解析器放置在子模块下,或者作为一个独立的包发布。

import Components from 'unplugin-vue-components'
import MyLibResolver from 'my-lib/auto-import-resolver' // <--

export default defineConfig({
  plugins: [
    Components({
      resolvers: [
        MyLibResolver
      ]
    })
  ]
})

即使对于现有的解析器,我们也建议将它们移至独立的包中,以便拥有更快的发布周期。一旦您完成了这个步骤,我们将非常乐意接受用于废弃并将解析器转移到您的包中的PR。
非常感谢您的理解和支持。

📝 全局注册组件的类型

某些库可能会为您注册一些全局组件,供您在任何地方使用(例如,Vue Router 提供了 <RouterLink><RouterView>)。由于它们是全局可用的,所以此插件无需导入它们。然而,这些组件通常不太友好于 TypeScript,并且您可能需要手动注册它们的类型。
因此,unplugin-vue-components 提供了一种只为全局组件注册类型的方法。
vite-plugin-components

Components({
  dts: true,
  types: [{
    from: 'vue-router',
    names: ['RouterLink', 'RouterView'],
  }],
})

这样,RouterLink 和 RouterView 将出现在 components.d.ts 中。
默认情况下,unplugin-vue-components 会在工作区中安装了支持的库(例如 vue-router)时自动检测它们。如果您完全禁用此功能,可以将一个空数组传递给它:

Components({
  // 禁用仅注册类型
  types: [],
})

📝从vite-plugin-components迁移

package.json:

{
  "devDependencies": {
-   "vite-plugin-components": "*",
+   "unplugin-vue-components": "^0.14.0",
  }
}

vite.config.js

- import Components, { ElementPlusResolver } from 'vite-plugin-components'
+ import Components from 'unplugin-vue-components/vite'
+ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    /* ... */
    Components({
      /* ... */

      // `customComponentsResolvers` 已更名为 `resolvers`
-     customComponentsResolvers: [
+     resolvers: [
        ElementPlusResolver(),
      ],

      // `globalComponentsDeclaration` 已更名为 `dts`
-     globalComponentsDeclaration: true,
+     dts: true,

      // `customLoaderMatcher` 已弃用,使用 `include` 替代
-     customLoaderMatcher: id => id.endsWith('.md'),
+     include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
    }),
  ],
}

📝 配置

以下是配置的默认值

Components({
  // 相对路径,用于搜索组件的目录。
  dirs: ['src/components'],

  // 组件的有效文件扩展名。
  extensions: ['vue'],

  // 匹配文件名作为组件的Glob模式。
  // 当指定时,`dirs` 和 `extensions` 选项将被忽略。
  globs: ['src/components/*.{vue}'],

  // 是否搜索子目录。
  deep: true,

  // 自定义组件的解析器。
  resolvers: [],

  // 生成 `components.d.ts` 全局声明文件,
  // 也可以指定自定义文件名的路径。
  // 默认值:如果安装了 `typescript` 包,则为 `true`。
  dts: false,

  // 允许子目录作为组件的命名空间前缀。
  directoryAsNamespace: false,

  // 折叠相同前缀(对大小写敏感)的文件夹和组件,
  // 以防止在命名空间组件名称中出现重复。
  // 当 `directoryAsNamespace: true` 时有效。
  collapseSamePrefixes: false,

  // 忽略命名空间前缀的子目录路径。
  // 当 `directoryAsNamespace: true` 时有效。
  globalNamespaces: [],

  // 自动导入指令。
  // 默认值:对于Vue 3为 `true`,对于Vue 2为 `false`。
  // 针对Vue 2,为了性能考虑,默认情况下禁用了Babel转换。
  // 若要安装Babel,请运行:`npm install -D @babel/parser`
  directives: true,

  // 解析前转换路径。
  importPathTransform: v => v,

  // 允许组件覆盖具有相同名称的其他组件。
  allowOverrides: false,

  // 用于转换目标的过滤器。
  include: [/\.vue$/, /\.vue\?vue/],
  exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],

  // 项目的Vue版本。如果未指定,将自动检测。
  // 可接受的值:2 | 2.7 | 3
  version: 2.7,

  // 仅提供库中组件(全局注册)的类型。
  types: []
})

⚠️ 问题解决:unplugin-vue-components 按需导入样式导致vite热更新卡顿

unplugin-vue-components插件,开发环境按需导入样式会导致 vite 热更新卡顿

https://github.com/antfu/unplugin-vue-components/issues/361 👈👈👈

解决方案:开发环境不按需导入样式,生产环境再按需导入样式

      Components({
        resolvers: [
          AntDesignVueResolver({
            importStyle: mode === 'development' ? false : 'less',
          }),
        ],
      }),
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐