Vue按需自动导入组件
特点:
支持Vue 2和Vue 3,开箱即用。
✨ 支持组件和指令。
⚡️ 基于unplugin技术,支持Vite、Webpack、Vue CLI、Rollup、esbuild等构建工具。
只导入你使用的组件,实现按需加载。
使用文件夹名称作为命名空间。
完全支持TypeScript。
针对流行UI库提供内置解析器。
与unplugin-icons完美协同工作。
npm i -D unplugin-vue-components
// vite.config.ts
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
Components({ /* options */ }),
],
})
// rollup.config.js
import Components from 'unplugin-vue-components/rollup'
export default {
plugins: [
Components({ /* options */ }),
],
}
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-components/webpack')({ /* options */ }),
],
}
对于Nuxt,您可能不需要使用这个插件。可以使用@nuxt/components代替。
@nuxt/components是Nuxt.js的官方模块,它提供了类似按需导入组件的功能。通过@nuxt/components,您可以在需要时动态地导入和注册组件,而不需要使用额外的插件。这个模块与Nuxt.js紧密集成,提供了更简单和方便的方式来管理和使用组件。
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
require('unplugin-vue-components/webpack')({ /* options */ }),
],
},
}
// 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支持,Vue 3有一个扩展全局组件接口的Pull Request。目前,Volar已经支持了这种用法。如果您正在使用Volar,可以按照以下方式更改配置来获取支持。
Components({
dts: true, // 默认情况下启用,如果安装了 `typescript`
})
一旦设置完成,将生成一个 components.d.ts 文件,并自动更新其中的类型定义。根据您的需求,您可以选择将其提交到git中或不提交。
请确保将 components.d.ts 添加到您的 tsconfig.json 的 include 中。
我们内置了对一些流行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按需导入样式目前支持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
}
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 提供了
和
)。由于它们是全局可用的,所以此插件无需导入它们。然而,这些组件通常不太友好于 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: [],
})
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 热更新卡顿
https://github.com/antfu/unplugin-vue-components/issues/361
解决方案:开发环境不按需导入样式,生产环境再按需导入样式
Components({
resolvers: [
AntDesignVueResolver({
importStyle: mode === 'development' ? false : 'less',
}),
],
}),