存在如下 3 个比较不简洁的问题:
1.每个 vue 文件要手动导入 vue 相关函数:ref、reactive、computed 等等,比较麻烦。
2.在 src/components 里的组件,一般是全局按需应用,一个个导入也比较麻烦。
3.使用 UI 组件库时,一般是按需导入,每个 vue 文件手动按需导入也挺麻烦。
4.为了解决这个问题,官方提供了 自动按需导入 的插件,这篇文章来介绍一下。
官方提供了两个插件:unplugin-auto-import、unplugin-vue-components
可以自动按需导入 Vite、Webpack、Rollup 和 esbuild 的 api、指定目录的组件,且支持 typescript。
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
export default defineConfig({
plugins: [
vue(),
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue'],
}),
Components({
// 指定自动导入的组件位置,默认是 src/components
// dirs: ['src/components'],
}),
],
});
这样 vue 文件里就不用再手动导入相关 vue api、src/components 里的组件了。
但会出现一个问题,不导入 vue,vscode 就找不到相关 api
这是一个 ts 错误,解决方法:在 tsconfig.json include 加上自动导入所生成的配置文件 auto-imports.d.ts
{
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"./auto-imports.d.ts"
],
}
这样 vscode 就可以找到对应 api 了
自动导入 vue api 后,在 vue 文件使用中,会报一个 eslint 报错问题:
解决方法:配置 eslintrc.enabled 为 true,重启项目生成 .eslintrc-auto-import.json 文件(浏览器需要访问所有应用到 vue/element api 的页面才会生成所有自动导入 api 的文件 json),生成后改为 false。最后在 .eslintrc.js 引入生成的 json
export default defineConfig({
base: './',
plugins: [
vue(),
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue'],
// eslint 报错解决:'ref' is not defined
eslintrc: {
// 默认 false, true 启用生成。生成一次就可以,避免每次工程启动都生成,一旦生成配置文件之后,最好把 enable 关掉,即改成 false。
// 否则这个文件每次会在重新加载的时候重新生成,这会导致 eslint 有时会找不到这个文件。当需要更新配置文件的时候,再重新打开
enabled: false,
// filepath: './.eslintrc-auto-import.json', // 默认就是 ./.eslintrc-auto-import.json
// globalsPropValue: true, // 默认 true
},
}),
],
});
// .eslintrc.js
extends: [
...
'./.eslintrc-auto-import.json'
],
推荐安装的 vscode 插件:Volar、TypeScript Vue Plugin (Volar),并把 Vetur 卸载
以 element-plus UI 组件库为例,官方文档描述的也很清楚:快速开始
Vite 配置如下
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [
// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox...
ElementPlusResolver(),
],
}),
Components({
resolvers: [
// 自动导入 Element Plus 组件
ElementPlusResolver(),
],
}),
],
});
element-plus 图标是用 svg 渲染的,需要额外的导入方法。
官方也有提供自动按需导入,需要额外安装 unplugin-icons 插件,Vite 配置如下:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [
// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox...
ElementPlusResolver(),
// 自动导入图标组件
IconsResolver({
prefix: 'Icon',
}),
],
}),
Components({
resolvers: [
// 自动导入 Element Plus 组件
ElementPlusResolver(),
// 自动注册图标组件
IconsResolver({
enabledCollections: ['ep'], // element-plus 图标库
}),
],
}),
Icons({
autoInstall: true,
}),
],
});
如上面配置代码已经自动导入,@iconify-json/ep 是 Element Plus 的图标库,所以 IconsResolver 配置了 enabledCollections: [‘ep’]
重点需要注意的是,使用图标要加上前缀。
从 element-plus 文档复制 icon 的代码是这样的
实际上使用的时候,要加上 i-ep- 前缀,并推荐改成短横线命名
配置了自动按需导入,在应用时,会自动生成 auto-imports.d.ts、components.d.ts 配置文件,分别描述自动导入的 API、component。
可以自定义配置文件的路径
AutoImport({
// ...
// 配置文件生成位置,默认是根目录 /auto-imports.d.ts
// dts: 'src/auto-imports.d.ts',
}),
Components({
// ...
// 配置文件生成位置,默认是根目录 /components.d.ts
// dts: 'src/components.d.ts',
}),
vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'path';
import vue from '@vitejs/plugin-vue';
import AutoImport from 'unplugin-auto-import/vite';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue'],
resolvers: [
// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox...
ElementPlusResolver(),
// 自动导入图标组件
IconsResolver({
prefix: 'Icon',
}),
],
// 配置文件生成位置,默认是根目录 /auto-imports.d.ts
// dts: 'src/auto-imports.d.ts',
}),
Components({
// 指定自动导入的组件位置,默认是 src/components
// dirs: ['src/components'],
resolvers: [
// 自动导入 Element Plus 组件
ElementPlusResolver(),
// 自动注册图标组件
IconsResolver({
enabledCollections: ['ep'],
}),
],
// 配置文件生成位置,默认是根目录 /components.d.ts
// dts: 'src/components.d.ts',
}),
Icons({
autoInstall: true,
}),
],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
// 加载 assets 图片资源,这个别名必须用 / 开头
'/images': resolve(__dirname, 'src/assets/img'),
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "src/assets/css/theme.scss";', // 添加公共样式
},
},
},
server: {
open: true,
},
});