小举人 手册

↑↓ 选择 Enter 打开 Esc 关闭

Vite相关插件

日常用到的 Vite 插件:auto-import、components、pages、layouts 等。

约 3 分钟读完
本页目录

记录下日常使用 Vite 的一些相关插件。

#unplugin-auto-import

自动导入 vue3 相关方法,支持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

完整配置

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'],
      dts: 'src/auto-import.d.ts',
      // 可以选择auto-import.d.ts生成的位置(默认根目录),建议设置为'src/auto-import.d.ts'
    }),
  ],
})

原理: 自动生成 auto-imports.d.ts 文件用于代码提示,如下

// 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 {}

caution 注意,由于没有局部导入,在代码跳转查看时,就会跳转到 auto-imports.d.ts 文件,然后再跳转到原定义位置。

#响应式语法糖

Reactivity Transform | Vue.js (vuejs.org)

使用$ref 在使用时,无需.value。演示如下

import { $ref, $$ } from 'vue/macros' // $ref是vue/macros包下的

// bind ref as a variable
let count = $ref(0)

// assignments are reactive
count++

// get the actual ref
console.log($$(count)) // { value: 1 }
  • 可以用$()来解构响应式对象,这样就不用写.value
  • 可以用$$()来获取原有的响应式对象

在 vite.config.ts 文件里,加上reactivityTransform: true

plugins: [
  vue({
    reactivityTransform: true,
  }),
]

可以使用 unplugin-auto-import 中的导入vue/macros无需 import 导入。

AutoImport({
  imports: ['vue/macros'],
  dts: true,
})

#unplugin-vue-components

自动导入 UI 库,按需导入。很多组件库都推荐这种方式导入例如 Element Plus 、Ant Design Vue

安装

npm install unplugin-vue-components -D
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()
      ]
    })
  ]

插件会生成一个 ui 库组件以及指令路径 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']
    ElHeader: typeof import('element-plus/es')['ElHeader']
    ElIcon: typeof import('element-plus/es')['ElIcon']
    ElMain: typeof import('element-plus/es')['ElMain']
  }
}

export {}

只要你用过的组件都会自动导入,同时也可以导入自己的组件。

import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({
      // 指定组件位置,默认是src/components
      dirs: ['src/components'],
      extensions: ['vue'],
      // 配置文件生成位置
      dts: 'src/components.d.ts',
    }),
  ],
})

#unplugin-vue-define-options/vite

script setup 语法糖通过 defineOptions 定义组件 name、inheritAttrs、props、emits

安装

npm i unplugin-vue-define-options
import { defineConfig } from 'vite'
import DefineOptions from 'unplugin-vue-define-options/vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue(), DefineOptions()],
})

在tsconfig.json设置 types,如下所示:

{
  "compilerOptions": {
    "types": ["unplugin-vue-define-options"]
  }
}

不然在 ts 项目中会提示 找不到名称“defineOptions”,具体使用如下

<script setup lang="ts">
import { useSlots } from 'vue'
defineOptions({
  name: 'Foo',
  inheritAttrs: false,
  props: {
    msg: { type: String, default: 'bar' },
  },
  emits: ['change', 'update'],
})
const slots = useSlots()
</script>

输出

<script lang="ts">
export default {
  name: 'Foo',
  inheritAttrs: false,
  props: {
    msg: { type: String, default: 'bar' },
  },
  emits: ['change', 'update'],
}
</script>

<script setup>
const slots = useSlots()
</script>

如果只是想单纯的设置组件名的话,这个插件 vite-plugin-vue-setup-extend 可能更适合,只需要在 script 中添加一个 name 属性即可。

<template>
  <div>hello world {{ a }}</div>
</template>

<script lang="ts" setup name="App">
const a = 1
</script>

#vite-plugin-mock

提供本地和生产模拟服务。

安装

npm i mockjs vite-plugin-mock
import { UserConfigExport, ConfigEnv } from 'vite'

import { viteMockServe } from 'vite-plugin-mock'
import vue from '@vitejs/plugin-vue'

export default ({ command }: ConfigEnv): UserConfigExport => {
  return {
    plugins: [
      vue(),
      viteMockServe({
        // default
        mockPath: 'mock',
        localEnabled: command === 'serve',
      }),
    ],
  }
}

#vite-plugin-pages

基于文件系统的动态路由。

安装

npm install -D vite-plugin-pages
npm install vue-router
import Pages from 'vite-plugin-pages'

export default {
  plugins: [
    Pages({
      dirs: 'src/views',
    }),
  ],
}

传统的 routes 写法

// 1. 定义路由组件.
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }

// 2. 定义一些路由
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3. 创建路由实例并传递 `routes` 配置
const router = VueRouter.createRouter({
  routes,
})

而该插件则是导入整个 pages(views)下的 vue 文件作为路由,也有一套自定义的路由规则,类似 nuxt.js

import { createRouter } from 'vue-router'
import routes from '~pages'

const router = createRouter({
  // ...
  routes,
})

#vite-plugin-vue-layouts

配合vite-plugin-pages使用,可以在生成页面路由的基础上实现动态布局功能.

安装

npm install -D vite-plugin-vue-layouts
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import Layouts from 'vite-plugin-vue-layouts'

export default {
  plugins: [Vue(), Pages(), Layouts()],
}

在对应的页面单文件中添加布局配置,在路由时即可按配置切换布局,将页面嵌入对应的布局文件之中.

<route lang="yaml">
meta:
  layout: users
</route>

#vite-plugin-purge-icons

方便的使用 Iconify 图标。

安装

 pnpm add @iconify/iconify
 pnpm add vite-plugin-purge-icons @iconify/json -D
import PurgeIcons from 'vite-plugin-purge-icons'

export default {
  plugins: [
    PurgeIcons({
      /* PurgeIcons Options */
    }),
  ],
}

在 main.js 中导入 @purge-icons/generated

import { createApp } from 'vue'
import App from './App.vue'

import '@iconify/iconify'
import '@purge-icons/generated'

createApp(App).mount('#app')

使用

在 html 文件中指明 class 为 iconify,data-icon 为 iconify 对应的图标(直接复制官网的图标)

<span class="iconify" data-icon="system-uicons:browser-alt" data-inline="false" />

当然,也可以自行封装一个 Icon 组件,像下面这样使用。

<Icon icon="ion:settings-outline" :size="30" />

或者使用 vue3 版的 Iconify for Vue 。

#vite-plugin-windicss

安装

npm i -D vite-plugin-windicss windicss
import WindiCSS from 'vite-plugin-windicss'

export default {
  plugins: [WindiCSS()],
}

之所以使用 Windi CSS,主要是属性化模式太香了(预计会成为一个趋势),属性化默认情况下是可选的,可以在你的 windi 配置中开启。

import { defineConfig } from 'windicss/helpers'

export default defineConfig({
  attributify: true,
})

并根据需要这样使用它们:

<button bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600" text="sm white" font="mono light" p="y-2 x-4" border="2 rounded blue-200">Button</button>

语法

(variant[:-]{1})*key? = "((variant:)*value)*"

#vite-plugin-node

允许您使用 vite 作为节点开发服务器。‎

暂时没有实际测试过,只是觉得有点意思。

#总结

体验过一段时间的 Vite 开发,开发体验还是很满意的,这其中肯定与上面的插件有着密切联系。这次去翻看了一些项目,了解其中插件的使用。这里只是汇总了些常用的,还有更多相关插件可以去awesome-vite上查看。

参考文章:

尤大推荐的神器 unplugin-vue-components,解放双手!以后再也不用呆呆的手动引入(组件,ui(Element-ui)库,vue hooks 等) - 掘金 (juejin.cn)

vite2 常用插件篇(三)- 进阶插件 - 掘金 (juejin.cn)

Vite 之高效插件推荐 🍉 - 掘金 (juejin.cn)

vitejs/awesome-vite: ⚡️ A curated list of awesome things related to Vite.js (github.com)