unplugin-vue-components
Vue 的按需组件自动导入。
特性
- 💚 开箱即用,支持 Vue 2 和 Vue 3。
- ✨ 支持组件和指令。
- ⚡️ 支持 Vite、Webpack、Rspack、Vue CLI、Rollup、esbuild 等,基于 unplugin。
- 🏝 树摇,仅注册你使用的组件。
- 🪐 文件夹名称作为命名空间。
- 🦾 完全支持 TypeScript。
- 🌈 内置解析器 支持流行的 UI 库。
- 😃 与 unplugin-icons 完美兼容。
安装
npm i unplugin-vue-components -D
vite-plugin-components
已更名为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').default({ /* options */ }),
],
}
Rspack
// rspack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-components/rspack').default({ /* options */ }),
],
}
Nuxt
你可能不需要这个插件用于 Nuxt。请使用 @nuxt/components
替代。
Vue CLI
// vue.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-components/webpack').default({ /* options */ }),
],
}
你也可以将 Vue 配置文件重命名为 vue.config.mjs
并使用静态导入语法(应使用最新的 @vue/cli-service ^5.0.8
):
// vue.config.mjs
import Components from 'unplugin-vue-components/webpack'
export default {
configureWebpack: {
plugins: [
Components({ /* options */ }),
],
},
}
esbuild
// esbuild.config.js
import { build } from 'esbuild'
import Components from 'unplugin-vue-components/esbuild'
build({
/* ... */
plugins: [
Components({
/* options */
}),
],
})
使用
像平常一样在模板中使用组件,它会按需导入组件,不再需要 import
和 组件注册
!如果你异步注册父组件(或懒加载路由),自动导入的组件将与其父组件一起进行代码分割。
它将自动将以下内容转换为:
<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
选项来进行自定义。
TypeScript
要获得自动导入组件的 TypeScript 支持,有一个 PR 被提出给 Vue 3 来扩展全局组件的接口。当前,Volar 已经支持这种用法。如果你在使用 Volar,你可以按照以下方式更改配置以获得支持。
Components({
dts: true, // 如果安装了 `typescript`,默认启用
})
设置完成后,将生成 components.d.ts
并会自动更新类型定义。随意选择是否提交到 Git。
确保还将
components.d.ts
添加到tsconfig.json
的include
中。
从 UI 库导入
我们针对流行的 UI 库如 Vuetify、Ant Design Vue 和 Element Plus 提供了几个内置解析器,你可以通过以下方式启用它们:
支持的解析器:
- Ant Design Vue
- Arco Design Vue
- BootstrapVue
- Element Plus
- Element UI
- Headless UI
- IDux
- Inkline
- Ionic
- Naive UI
- Prime Vue
- Quasar
- TDesign
- Vant
@vant/auto-import-resolver
- Vant 的自动导入解析器
- Varlet UI
@varlet/import-resolver
- Varlet 的自动导入解析器
- VEUI
- View UI
- Vuetify — 在可能的情况下优先使用第一方插件:v3 + vite,v3 + webpack,v2 + webpack
- VueUse Components
- VueUse Directives
- Dev UI
import {
AntDesignVueResolver,
ElementPlusResolver,
VantResolver,
} from 'unplugin-vue-components/resolvers'
// vite.config.js
import Components from 'unplugin-vue-components/vite'
// 安装插件
Components({
resolvers: [
AntDesignVueResolver(),
ElementPlusResolver(),
VantResolver(),
],
})
你也可以快速编写自己的解析器:
Components({
resolvers: [
// 导入 Vant 的示例
(componentName) => {
// 其中 `componentName` 始终是大写字母开头
if (componentName.startsWith('Van'))
return { name: componentName.slice(3), from: 'vant' }
},
],
})
全局注册组件的类型
一些库可能会为你注册一些全局组件,以便你可以随时使用(例如 Vue Router 提供 <RouterLink>
和 <RouterView>
)。由于它们是全局可用的,因此该插件不需要导入它们。然而,这些组件通常不友好于 TypeScript,你可能需要手动注册它们的类型。
因此,unplugin-vue-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` 已重命名为 `resolver`
- 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'],
// 匹配文件名的全局模式,以被识别为组件
// 当指定时,`dirs`、`extensions` 和 `directoryAsNamespace` 选项将被忽略
// 如果你想排除组件的注册,请使用带有前导 `!` 的否定全局模式
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`
// Babel 被禁用,以提高性能。如果需要安装 Babel,请运行:`npm install -D @babel/parser`
directives: true,
// 解析前转换路径
importPathTransform: v => v,
// 允许组件覆盖同名的其他组件
allowOverrides: false,
// 转换目标的过滤器(要插入自动导入的组件)
// 注意这些不是关于包括/排除注册的组件 - 用 `globs` 或 `excludeNames` 来处理
include: [/\.vue$/, /\.vue\?vue/],
exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
// 不会被导入的组件名称的过滤器
// 用于全局导入的异步组件或插件无法检测的其他冲突
excludeNames: [/^Async.+/],
// 项目的 Vue 版本。如果未指定,将自动检测。
// 可接受的值:2 | 2.7 | 3
version: 2.7,
// 仅提供库中组件的类型(全局注册)
types: []
})
示例
Vitesse 启动模板。
感谢
感谢 @brattonross,这个项目受到了 vite-plugin-voie 的启发。
许可证
MIT 许可证 © 2020-PRESENT Anthony Fu