4,293378 unplugin-vue-components Vue 组件按需自动导入
💚 开箱即用,原生支持 Vue 3。
✨ 同时支持组件和指令。
⚡️ 基于 unplugin,支持 Vite、Webpack、Rspack、Rollup、Rolldown、esbuild 等多种构建工具。
🏝 支持 Tree-shaking,仅注册你实际使用的组件。
🪐 使用文件夹名作为命名空间。
🦾 全面支持 TypeScript。
🌈 内置主流 UI 库的解析器。
😃 与 unplugin-icons 完美配合。
安装
bash
npm i unplugin-vue-components -D
vite-plugin-components 已更名为 unplugin-vue-components,迁移指南见这里。
Vite
ts
// vite.config.ts
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
Components({ /* options */ }),
],
})
Rollup
ts
// rollup.config.js
import Components from 'unplugin-vue-components/rollup'
export default {
plugins: [
Components({ /* options */ }),
],
}
Rolldown
ts
// rolldown.config.js
import Components from 'unplugin-vue-components/rolldown'
export default {
plugins: [
Components({ /* options */ }),
],
}
Webpack
ts
// webpack.config.js
// unplugin-vue-components 从 29.1.0 版本起不再支持 CommonJS
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-components/webpack')({ /* options */ }),
],
}
Rspack
ts
// rspack.config.js
// unplugin-vue-components 从 29.1.0 版本起不再支持 CommonJS
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-components/rspack')({ /* options */ }),
],
}
Nuxt
在 Nuxt 中可能不需要这个插件,可以直接用 @nuxt/components。
Quasar
ts
// vite.config.js [Vite]
import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
Components({ /* options */ })
]
})
ts
// quasar.config.js
export default defineConfig(() => {
return {
build: {
vitePlugins: [
['unplugin-vue-components/vite', { /* options */ }],
]
},
}
})
esbuild
ts
// esbuild.config.js
import { build } from 'esbuild'
import Components from 'unplugin-vue-components/esbuild'
build({
/* ... */
plugins: [
Components({
/* options */
}),
],
})
用法
在模板中照常使用组件即可,插件会自动按需引入,无需再手动 import 或注册组件。如果父组件是异步注册的(或懒加载路由),自动引入的组件也会跟随父组件一起做代码分割。
它会自动把这样的代码:
html
转换成:
html
默认情况下,该插件会导入 src/components 路径下的组件。你可以通过 dirs 选项自定义此路径。
TypeScript 支持
若想让 TypeScript 识别自动导入的组件,Vue 3 已有一个 PR 扩展了全局组件的接口定义。目前,Volar 已支持这一用法。如果你在使用 Volar,可以按以下示例修改配置以获取支持:
```ts
Components({
dts: true, // 如果安装了 `typescript` 包,此项默认为启用
})
```
配置完成后,系统会生成 components.d.ts 文件,并随类型定义的变更自动更新。你可以决定是否将其提交到 Git。
请务必将 components.d.ts 添加到 tsconfig.json 的 include 配置中。
从 UI 库导入组件
我们为 Vuetify、Ant Design Vue 和 Element Plus 等流行 UI 库提供了内置解析器。你可以通过以下方式启用它们:
支持的解析器:
* Ant Design Vue
* Arco Design Vue
* BootstrapVue
* Element Plus
* Headless UI
* IDux
* Inkline
* Ionic
* Naive UI
* Prime Vue
* Quasar
* TDesign
* @tdesign-vue-next/auto-import-resolver - TDesign 官方的自动导入解析器
* Vant
* @vant/auto-import-resolver - Vant 官方的自动导入解析器
* Varlet UI
* @varlet/import-resolver - Varlet 官方的导入解析器
* VEUI
* View UI
* Vuetify
* 优先使用官方插件:v3 + vite, v3 + webpack, v2 + webpack
* VueUse 组件
* VueUse 指令
* Dev UI
```ts
import {
AntDesignVueResolver,
ElementPlusResolver,
VantResolver,
} from 'unplugin-vue-components/resolvers'
// vite.config.js
import Components from 'unplugin-vue-components/vite'
// 插件安装配置
Components({
resolvers: [
AntDesignVueResolver(),
ElementPlusResolver(),
VantResolver(),
],
})
```
你也可以快速编写自定义解析器:
```ts
Components({
resolvers: [
// Vant 导入示例
(componentName) => {
// `componentName` 始终是大驼峰命名
if (componentName.startsWith('Van'))
return { name: componentName.slice(3), from: 'vant' }
},
],
})
```
我们不再接受新的解析器提交。
全局注册组件的类型
某些库可能会为你注册一些全局组件,以便在任何地方使用(例如 Vue Router 提供的 `
` 和 ``)。由于它们全局可用,因此无需本插件导入。然而,这些库通常对 TypeScript 支持不佳,你可能需要手动注册它们的类型。
因此,unplugin-vue-components 提供了一种仅注册全局组件类型的方式:
```ts
Components({
dts: true,
types: [{
from: 'vue-router',
names: ['RouterLink', 'RouterView'],
}],
})
```
这样,RouterLink 和 RouterView 就会出现在 components.d.ts 中。
默认情况下,当工作区中安装了相关库(如 vue-router)时,unplugin-vue-components 会自动检测并支持这些库。如果你想完全禁用此功能,可以传入一个空数组:
```ts
Components({
// 禁用仅类型注册
types: [],
})
```
从 vite-plugin-components 迁移
package.json
```diff
{
"devDependencies": {
- "vite-plugin-components": "*",
+ "unplugin-vue-components": "^0.14.0",
}
}
```
vite.config.js
```diff
- 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/, /\.vue\.[tj]sx?\?vue/, /\.md$/],
}),
],
}
```
配置项
以下展示了配置的默认值:
```ts
Components({
// 搜索组件的相对路径目录
dirs: ['src/components'],
// 组件的有效文件扩展名
extensions: ['vue'],
// 匹配被识别为组件文件名的 Glob 模式
// 你也可以指定多个,例如:`src/components/*.{vue,tsx}`
// 当指定此项时,`dirs`、`extensions` 和 `directoryAsNamespace` 选项将被忽略。
// 如果想排除某些组件不被注册,请使用带前缀 `!` 的负向 Glob 模式。
globs: ['src/components/*.vue'],
// 搜索子目录
deep: true,
// 自定义组件的解析器
resolvers: [],
// 生成 `components.d.ts` 全局声明
// 也接受自定义文件名的路径
// 如果安装了 typescript 包,默认为 `true`
dts: false,
// 生成带 TSX 支持的 dts
// 如果安装了 `@vitejs/plugin-vue-jsx`,默认为 `true`
dtsTsx: false,
// 允许使用子目录作为组件命名空间前缀
directoryAsNamespace: false,
// 折叠文件夹和组件相同的前缀(区分大小写)
// 以防止命名空间内的组件名重复
// 仅在 `directoryAsNamespace: true` 时生效
collapseSamePrefixes: false,
// 忽略命名空间前缀的子目录路径
// 仅在 `directoryAsNamespace: true` 时生效
globalNamespaces: [],
// 指令的自动导入
directives: true,
// 解析前转换路径
importPathTransform: v => v,
// 允许组件覆盖同名其他组件
allowOverrides: false,
// 转换目标的过滤器(插入自动导入的组件)
// 注意:这与包含/排除已注册组件无关,请使用 `globs` 或 `excludeNames`
include: [/\.vue$/, /\.vue\?vue/, /\.vue\.[tj]sx?\?vue/],
exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
// 不会被导入的组件名过滤器
// 用于全局导入的异步组件或插件无法检测到的其他冲突
excludeNames: [/^Async.+/],
// 项目的 Vue 版本。如果未指定,将自动检测。
// 可接受的值:2 | 2.7 | 3
version: 2.7,
// 仅提供库中组件的类型(全局注册)
// 参见 https://github.com/unplugin/unplugin-vue-components/blob/main/src/core/type-imports/index.ts
types: [
/* ... */
],
// 将组件信息保存到 JSON 文件,供其他工具使用
// 提供保存 JSON 文件的路径
// 如果设置为 `true`,将保存到 `./.components-info.json`
dumpComponentsInfo: false,
// 同步 components.d.ts 和 .components-info.json 文件模式
// 'append': 仅将新组件追加到现有文件
// 'overwrite': 用当前组件覆盖整个现有文件
// 'default': 使用开发服务器时采用 'append' 策略,构建时采用 'overwrite' 策略
syncMode: 'default',
})
```
示例
Vitesse 起始模板。
致谢
感谢 @brattonross,本项目深受 vite-plugin-voie 启发。
许可证
MIT License © 2020-PRESENT Anthony Fu