本文已参与「新人创作礼」活动,一起开启掘金创作之路。
推荐阅读
vite.config.ts 之 Plugins 篇 (二)
unplugin-vue-components - 自动导入、按需导入组件
自动导入组件,以往使用组件时必须要
import
导入后在使用。通过unplugin-auto-import
实现自动导入,配合Element Plus
组件库也可以实现按需加载(其他主流组件库也支持)
- 安装
# 选择一个你喜欢的包管理器
# NPM
npm install unplugin-vue-components -D
# Yarn
yarn add unplugin-vue-components -D
# PNPM
pnpm install unplugin-vue-components -D
- 配置
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import legacy from '@vitejs/plugin-legacy'
import compressPlugin from 'vite-plugin-compression'
import viteImagemin from 'vite-plugin-imagemin'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
...省略插件配置,
Components({
dirs: ['src/components'],
resolvers: [ElementPlusResolver()],
// 组件的有效文件扩展名。
extensions: ['vue'],
// 允许子目录作为组件的命名空间前缀。
directoryAsNamespace: false,
deep: true,
}),
],
})
去掉
import HelloWorld from './components/HelloWorld.vue'
代码也可以正常使用HelloWorld
组件
- 使用
// App.vue
<script setup lang="ts" name="App">
</script>
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
运行或打包会自动生成
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 {
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
}
}
export { }
element-plusVue 3 的桌面端组件库
Element Plus
目前还处于快速开发迭代中。目前使用2.0.1
版可以结合vite-plugin-style-import
插件按需加载样式。unplugin-vue-components
按需自动导入组件 使用Element Plus
组件时可以直接使用
- 安装
# 选择一个你喜欢的包管理器
# NPM
npm install element-plus --save
# Yarn
yarn add element-plus
# pnpm
pnpm install element-plus
vite-plugin-style-import - 按需引入组件库样式
vite-plugin-style-import
新最新版本(新版本需安装consola
才能正常运行)
- 安装
# 选择一个你喜欢的包管理器
# NPM
npm install vite-plugin-style-import consola -D
# Yarn
yarn add vite-plugin-style-import consola -D
# PNPM
pnpm install vite-plugin-style-import consola -D
- 配置
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import legacy from '@vitejs/plugin-legacy'
import compressPlugin from 'vite-plugin-compression'
import viteImagemin from 'vite-plugin-imagemin'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
...省略插件配置,
Components({
// 指明组件存放目录
dirs: ['src/components'],
resolvers: [ElementPlusResolver()],
// 组件的有效文件扩展名。
extensions: ['vue'],
// 允许子目录作为组件的命名空间前缀。
directoryAsNamespace: false,
deep: true,
}),
createStyleImportPlugin({ resolves: [ElementPlusResolve()] }),
],
})
使用
Element Plus
UI库自动导入样式,unplugin-vue-components
按需自动导入组件
- 使用
// HelloWorld.vue
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{ msg: string }>()
const count = ref(0)
</script>
<template>
<h1>{{ msg }}</h1>
<p>
Recommended IDE setup:
<el-link type="danger" href="https://code.visualstudio.com/" target="_blank">VSCode</el-link>
+
<el-link type="primary" href="https://github.com/johnsoncodehk/volar/" target="_blank">Volar</el-link>
</p>
<p>See <code>README.md</code> for more information.</p>
<p>
<el-link type="success" href="https://vitejs.dev/guide/features.html" target="_blank">
Vite Docs
</el-link>
|
<el-link type="success" href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</el-link>
</p>
<el-button type="primary" @click="count++">count is: {{ count }}</el-button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>
<style scoped>
a {
color: #42b983;
}
label {
margin: 0 0.5em;
font-weight: bold;
}
code {
background-color: #eee;
padding: 2px 4px;
border-radius: 4px;
color: #304455;
}
</style>
unplugin-auto-import - API自动导入
setup
语法让我们不用再一个一个的把变量和方法都return
出去就能在模板上使用,大大的解放了我们的双手。然而对于一些常用的Vue
API,比如ref
、computed
、watch
等,还是每次都需要我们在页面上手动进行import { ref } from 'vue'
。
可以通过unplugin-auto-import
实现自动导入,无需import
即可在文件里使用Vue
的API。
- 安装
# 选择一个你喜欢的包管理器
# NPM
npm install unplugin-auto-import -D
# Yarn
yarn add unplugin-auto-import -D
# PNPM
pnpm install unplugin-auto-import -D
- 配置
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import legacy from '@vitejs/plugin-legacy'
import compressPlugin from 'vite-plugin-compression'
import viteImagemin from 'vite-plugin-imagemin'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
...省略插件配置,
Components({
dirs: ['src/components'],
resolvers: [ElementPlusResolver()],
// 组件的有效文件扩展名。
extensions: ['vue'],
// 允许子目录作为组件的命名空间前缀。
directoryAsNamespace: false,
deep: true,
}),
createStyleImportPlugin({ resolves: [ElementPlusResolve()] }),
AutoImport({
imports: ['vue'],
resolvers: [ElementPlusResolver({ importStyle: false })],
}),
],
})
HelloWorld.vue
组件去掉,import { ref } from 'vue'
可以正常使用
- 使用
// HelloWorld.vue
<script setup lang="ts">
defineProps<{ msg: string }>()
const count = ref(0)
</script>
<template>
<h1>{{ msg }}</h1>
<p>
Recommended IDE setup:
<el-link type="danger" href="https://code.visualstudio.com/" target="_blank">VSCode</el-link>+
<el-link type="primary" href="https://github.com/johnsoncodehk/volar/" target="_blank">Volar</el-link>
</p>
<p>
See
<code>README.md</code> for more information.
</p>
<p>
<el-link type="success" href="https://vitejs.dev/guide/features.html" target="_blank">Vite Docs</el-link>|
<el-link type="success" href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</el-link>
</p>
<el-button type="primary" @click="count++">count is: {{ count }}</el-button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>
<style scoped>
a {
color: #42b983;
}
label {
margin: 0 0.5em;
font-weight: bold;
}
code {
background-color: #eee;
padding: 2px 4px;
border-radius: 4px;
color: #304455;
}
</style>
运行或打包会自动生成
auto-imports.d.ts
文件内容如下:
// Generated by 'unplugin-auto-import'
// We suggest you to commit this file into source control
declare global {
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const EffectScope: typeof import('vue')['EffectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
}
export {}
vue-global-api
解决使用
unplugin-auto-import
开发时VSCode
出现错误提示、并且无法打包问题
- 安装
# 选择一个你喜欢的包管理器
# NPM
npm install vue-global-api -D
# Yarn
yarn add vue-global-api -D
# PNPM
pnpm install vue-global-api -D
- 配置
// main.ts
import 'vue-global-api'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
运行
npm run dev
打包
npm run build
生成目录
npm install --global treer
treer -e ./result.md -i "/node_modules|git|dist/"
本章最终目录如下:
├─index.html
├─package.json
├─pnpm-lock.yaml
├─README.md
├─tsconfig.json
├─tsconfig.node.json
├─vite.config.ts
├─src
| ├─App.vue
| ├─env.d.ts
| ├─main.ts
| ├─components
| | └HelloWorld.vue
| ├─assets
| | └logo.png
├─public
| └favicon.ico
├─.vscode
| ├─extensions.json
| └settings.json
{
"name": "admin-vite",
"private": true,
"version": "0.0.2",
"author": {
"name": "SunHongYu",
"email": "17600616235@163.com",
"url": "https://juejin.cn/"
},
"resolutions": {
"bin-wrapper": "npm:bin-wrapper-china"
},
"scripts": {
"bootstrap": "pnpm install",
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "npm run build && vite preview",
"preview:dist": "vite preview",
"clean": "rimraf node_modules",
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite"
},
"dependencies": {
"element-plus": "^2.0.2",
"vue": "^3.2.31"
},
"devDependencies": {
"@vitejs/plugin-legacy": "^1.7.1",
"@vitejs/plugin-vue": "^2.2.0",
"@vue/compiler-sfc": "^3.2.31",
"consola": "^2.15.3",
"typescript": "^4.5.5",
"unplugin-auto-import": "^0.6.1",
"unplugin-vue-components": "^0.17.21",
"vite": "^2.8.2",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-imagemin": "^0.6.1",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vue-global-api": "^0.4.1",
"vue-tsc": "^0.31.2"
}
}
继续学习
废话只说一句:码字不易求个👍,收藏 === 学会,快行动起来吧!🙇🙇🙇。