先看效果
一个import都没有!
本文将介绍下面几个vite插件(可自由搭配,推荐node版本14+) [demo仓库地址] (
github.com/qc-z/vue-te…
)
1 unplugin-vue-components
1.1 自动导入ui库,该插件内置了大多数流行库解析器
这里拿几个流行ui库做栗子 Element Plus Ant Design Vue Element UI Headless UI
npm install unplugin-vue-components -D
然后将下面的代码添加到 Vite
或 webpack
的配置文件。
Vite配置
// vite.config.js
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
import {
ElementPlusResolver,
AntDesignVueResolver,
VantResolver,
HeadlessUiResolver,
ElementUiResolver
} from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
Components({
// ui库解析器,也可以自定义
resolvers: [
ElementPlusResolver(),
AntDesignVueResolver(),
VantResolver(),
HeadlessUiResolver(),
ElementUiResolver()
Webpack配置
// webpack.config.js
const components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver,AntDesignVueResolver,VantResolver,HeadlessUiResolver,ElementUiResolver } = require('unplugin-vue-components/resolvers')
module.exports =
plugins: [
Components({
resolvers: [
AntDesignVueResolver(),
ElementPlusResolver(),
VantResolver(),
HeadlessUiResolver(),
ElementUiResolver()
插件会生成一个ui库组件以及指令路径components.d.ts文件,详情看这个vue3的issue
types(defineComponent): support for expose component types
// components.d.ts
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/vue-next/pull/3399
declare module 'vue' {
export interface GlobalComponents {
ElAside: typeof import('element-plus/es')['ElAside']
ElButton: typeof import('element-plus/es')['ElButton']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElResult: typeof import('element-plus/es')['ElResult']
export { }
想了解其他的打包工具(Rollup, Vue CLI),请参考 unplugin-vue-components。
1.2 自动导入自己的组件
直接写组件名即可,插件会帮你引入进来 注意别重名
// vite.config.js
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
Components({
// 指定组件位置,默认是src/components
dirs: ['src/components'],
// ui库解析器
// resolvers: [ElementPlusResolver()],
extensions: ['vue'],
// 配置文件生成位置
dts: 'src/components.d.ts'
插件会生成一个自己组件路径的components.d.ts文件,详情看这个vue3的issue
types(defineComponent): support for expose component types
// components.d.ts
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/vue-next/pull/3399
declare module 'vue' {
export interface GlobalComponents {
BaseFilter: typeof import('./components/Common/BaseFilter.vue')['default']
BaseHeader: typeof import('./components/Common/BaseHeader.vue')['default']
BasePagination: typeof import('./components/Common/BasePagination.vue')['default']
BaseSidebar: typeof import('./components/Common/BaseSidebar.vue')['default']
BaseTags: typeof import('./components/Common/BaseTags.vue')['default']
BaseTitle: typeof import('./components/Common/BaseTitle.vue')['default']
export { }
// 插件的所有默认配置
Components({
// relative paths to the directory to search for components.
// 要搜索组件的目录的相对路径
dirs: ['src/components'],
// valid file extensions for components.
// 组件的有效文件扩展名。
extensions: ['vue'],
// search for subdirectories
// 搜索子目录
deep: true,
// resolvers for custom components
// 自定义组件的解析器
resolvers: [],
// generate `components.d.ts` global declarations,
// also accepts a path for custom filename
// 生成 `components.d.ts` 全局声明,
// 也接受自定义文件名的路径
dts: false,
// Allow subdirectories as namespace prefix for components.
// 允许子目录作为组件的命名空间前缀。
directoryAsNamespace: false,
// 忽略命名空间前缀的子目录路径
// 当`directoryAsNamespace: true` 时有效
// Subdirectory paths for ignoring namespace prefixes
// works when `directoryAsNamespace: true`
globalNamespaces: [],
// auto import for directives
// default: `true` for Vue 3, `false` for Vue 2
// Babel is needed to do the transformation for Vue 2, it's disabled by default for performance concerns.
// To install Babel, run: `npm install -D @babel/parser @babel/traverse`
// 自动导入指令
// 默认值:Vue 3 的`true`,Vue 2 的`false`
// 需要 Babel 来为 Vue 2 进行转换,出于性能考虑,它默认处于禁用状态。
directives: true,
// filters for transforming targets
include: [/.vue$/, /.vue?vue/],
exclude: [/[\/]node_modules[\/]/, /[\/].git[\/]/, /[\/].nuxt[\/]/],
2 unplugin-auto-import/vite
自动导入vue3的hooks,借助unplugin-auto-import/vite这个插件
支持vue
, vue-router
, vue-i18n
, @vueuse/head
, @vueuse/core
等自动引入
先看效果图
// 引入前
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
//引入后
const count = ref(0)
const doubled = computed(() => count.value * 2)
// 引入前
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return <div>{ count }</div>
//引入后
export function Counter() {
const [count, setCount] = useState(0)
return <div>{ count }</div>
npm i -D unplugin-auto-import
Vite配置
// vite.config.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
AutoImport({
imports: ['vue', 'vue-router', 'vue-i18n', '@vueuse/head', '@vueuse/core'],
// 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
// dts: 'src/auto-import.d.ts'
原理:
安装的时候会自动生成auto-imports.d文件(默认是在根目录)
// Generated by 'unplugin-auto-import'
// We suggest you to commit this file into source control
declare global {
const ref: typeof import('vue')['ref']
const reactive: typeof import('vue')['reactive']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const watch: typeof import('vue')['watch']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
export {}
可以选择auto-import.d.ts生成的位置,使用ts建议设置为src/auto-import.d.ts
其他插件 vue-router
, vue-i18n
, @vueuse/head
, @vueuse/core
等自动引入的自动引入请查看文档
// 插件的所有默认配置
AutoImport({
// targets to transform
include: [
/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
/\.vue$/, /\.vue\?vue/, // .vue
/\.md$/, // .md
// global imports to register
imports: [
// presets
'vue',
'vue-router',
// custom
'@vueuse/core': [
// named imports
'useMouse', // import { useMouse } from '@vueuse/core',
// alias
['useFetch', 'useMyFetch'] // import { useFetch as useMyFetch } from '@vueuse/core',
'axios': [
// default imports
['default', 'axios'] // import { default as axios } from 'axios',
'[package-name]': [
'[import-names]',
// alias
['[from]', '[alias]']
// custom resolvers
// 可以在这自定义自己的东西,比如接口api的引入,工具函数等等
// see https://github.com/antfu/unplugin-auto-import/pull/23/
resolvers: [
/* ... */
3vue-global-api 解决eslint报错(2022/03/01已不推荐,推荐使用unplugin-auto-import的eslintrc选项)
在页面没有引入的情况下,使用unplugin-auto-import/vite来自动引入hooks,在项目中肯定会报错的,这时候需要在eslintrc.js中的extends引入vue-global-api,这个插件是vue3hooks的,其他自己找找,找不到的话可以手动配置一下globals
npm install vue-global-api -D
// .eslintrc.js
module.exports = {
extends: [
'vue-global-api'
它还为细粒度控制提供了相同的集合和单个 API 选项。
// .eslintrc.js
module.exports = {
extends: [
// collections
'vue-global-api/reactivity',
'vue-global-api/lifecycle',
'vue-global-api/component',
// single apis
'vue-global-api/ref',
'vue-global-api/toRef',
4 vite-plugin-style-import
当你使用unplugin-vue-components来引入ui库的时候
message, notification 等引入样式不生效
安装vite-plugin-style-import即可
这里以一些流行库为例
// vite.config.js
import { defineConfig } from 'vite'
import styleImport, {
AndDesignVueResolve,
VantResolve,
ElementPlusResolve,
NutuiResolve,
AntdResolve
} from 'vite-plugin-style-import'
export default defineConfig({
plugins: [
styleImport({
resolves: [
AndDesignVueResolve(),
VantResolve(),
ElementPlusResolve(),
NutuiResolve(),
AntdResolve()
// 自定义规则
libs: [
libraryName: 'ant-design-vue',
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/index`
// 引用使用less的库要配置一下
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true
5 注意点
1. element-plus默认是英文
方案: 在app.vue加上ElConfigProvider
<template>
<div id="app">
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
</div>
</template>
<script setup>
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
const locale = zhCn
</script>
日期相关组件设置中文:
<script setup>
// 日历等与dayjs相关的组件,不想显示中文可以不加
// 第一种方法 使用中国时区weekStart默认为1
import 'dayjs/locale/zh-cn'
// 第二种方法 使用 weekStart可配置(只能是0或者1)
import dayjs from 'dayjs'
// 引入英文即为英文
import cn from 'dayjs/locale/zh-cn'
dayjs.locale({
...cn,
weekStart: 1
const locale = zhCn
</script>
2. 按需加载不支持指令方式导入,需要手动导入(仅作记录)
这个是我在作者下面提的issue
(2021/11/02记录现在已支持指令)
方案: 新建文件 element-plus-directive.js
import { ElLoading, ElMessage } from 'element-plus'
* 按需导入 Element Plus 组件
* Vite 插件 https://github.com/antfu/unplugin-vue-components
* @param app {App}
export default function styleImport(app) {
const components = [ElLoading, ElMessage]
components.forEach((v) => {
app.use(v)
return app
在main.js使用
import elemetPlusDirectives from './utils/element-plus-directive.js'
const app = createApp(App)
elemetPlusDirectives(app).mount('#app')