初始化
Node 版本 V18
使用 NPM:
$ npm init vite@latest 项目名
使用 Yarn:
$ yarn create vite@latest 项目名
激活PNPM
corepack prepare pnpm --activate
使用 PNPM:
$ pnpm create vite
选择框架 Vue,其他步骤如下:
Customize with create-vue 自定义
Add TypeScript? ye
Add JSX Support? jsx yes
Add Vue Router for Single Page Application development? router yes
Add Pinia for state management? pinia ~ yes
Add Vitest for Unit Testing? 测试用例 ~ yes
Add an End-to-End Testing Solution? 端到端测试解决方案 ~ Cypress
Add ESLint for code quality? eslint ~ yes
Add Prettier for code formatting? 格式化 ~ yes
依赖
pnpm install
或者直接指定项目名称和你想要使用的模板: github.com/vitejs/vite…
npm create vite@latest my-vue-app --template vue
yarn create vite my-vue-app --template vue
pnpm create vite my-vue-app --template vue
样式相关
Sass
vite 不需要安装 sass-loader
pnpm i -D sass
reset-css
reset 重置浏览器所有的默认样式,normalize 保留有用的默认CSS样式尽可能减少不同浏览器差异
pnpm install reset-css
main.ts
import 'reset-css'
tailwindcss
该依赖包含 reset-css
pnpm install -D tailwindcss@3.4.17 postcss autoprefixer
执行命令创建:tailwind.config.js 和 postcss.config.js
npx tailwindcss init -p
tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./index.html', // 入口文件
'./src/**/*.{vue,js,ts,jsx,tsx}' // 解析文件
],
theme: {
extend: {}
},
plugins: []
}
.vscode / settings.json
{
"css.lint.unknownAtRules": "ignore" // 忽略未知的css规则
}
文件 assets/main.css 导入模块
@tailwind base;
@tailwind components;
@tailwind utilities;
入口文件 main.ts 导入
import './assets/main.css'
unocss
pnpm add unocss@0.63.4 @unocss/reset@0.63.4 -D
vite.config.ts
import UnoCss from 'unocss/vite'
export default defineConfig({
plugins: [
UnoCss()
],
})
测试
<template>
<h1 class="text-3xl font-bold underline">tailwind</h1>
</template>
根目录创建 uno.config.ts
import { defineConfig } from 'unocss'
export default defineConfig({})
main.ts
import 'virtual:uno.css'
// import '@unocss/reset/tailwind.css' // tailwind reset
import '@unocss/reset/normalize.css' // 二选一
unocss 和 tailwind 一起使用
pnpm add @unocss/preset-wind@0.63.4 -D
更改配置 uno.config.ts
import { defineConfig } from 'unocss'
import presetWind from '@unocss/preset-wind'
export default defineConfig({
presets: [presetWind()]
})
测试
<template>
<h1 class="p-4">unocss</h1>
</template>
TS
如果版本是 V4 建议升级 5.0 版本
pnpm add @vue/tsconfig @types/node -D
不同版本配置 tsconfig.app.json
"extends": "@vue/tsconfig/tsconfig.dom.json", // Vue 官方提供的 TypeScript 5 基础配置文件
// "extends": "@vue/tsconfig/tsconfig.web.json", // ts 4
tsconfig.node.json
"extends": [
"@tsconfig/node22/tsconfig.json",
"@vue/tsconfig/tsconfig.json"
// Node 20 TS5
// "@tsconfig/node20/tsconfig.json"
// Node 18 TS5
// "@tsconfig/node18/tsconfig.json",
// "@vue/tsconfig/tsconfig.json"
// Node 18 TS4
// "@vue/tsconfig/tsconfig.node.json"
],
自动化路由
vite-plugin-pages
只支持 vite
pnpm install -D vite-plugin-pages
vite.config.ts
import Pages from 'vite-plugin-pages'
export default defineConfig({
plugins: [
Pages({
dirs:['src/views'] // 默认为 pages 、将 view 文件夹设置成自动路由的路径
})
]
})
router > index.ts
import { createRouter, createWebHistory } from 'vue-router'
import routes from '~pages'
const router = createRouter({
// history 底层是 history api pushState replaceState popstate
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
env.d.ts
/// <reference types="vite-plugin-pages/client" />
views 文件名即路由名,views 下创建 index.vue( 默认/ )直接访问
<template>
<div>hello</div>
</template>
<script setup lang="ts"></script>
404页:[...all].vue
<template>
<div>404 Not Found</div>
</template>
<script setup lang="ts"></script>
重定向方案
拦截器重定向 router / index.ts
router.beforeEach((to, from, next) => {
if (to.path === '/home') {
next('/')
}
next()
})
编程式:home.vue
<script setup lang="ts">
import { useRouter } from 'vue-router'
const router = useRouter()
router.push('/')
</script>
vite.config.ts
export default defineConfig({
plugins: [
Pages({
extendRoute(route) {
if (route.path === '/home') {
return { ...route, redirect: '/' }
}
return route
}
})
],
})
官方推荐:home.vue
<route lang="yaml">
name: home
redirect: /
</route>
<route lang="yaml">
{ name: 'home', redirect: '/' }
</route>
unplugin-vue-router
vite / webpack 均支持
pnpm add -D unplugin-vue-router@0.6.4
vite.config.ts
import VueRouter from 'unplugin-vue-router/vite'
export default defineConfig({
plugins: [
VueRouter({}), // 在 vue() 之前
vue(),
]
})
router > index.ts
import { createRouter, createWebHistory } from 'vue-router/auto'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL)
})
设置自动导入文件时需要排除的模式,希望手动导入 vue-router,而不是通过自动导入来处理它。
.vscode > settings.json
{
"typescript.preferences.autoImportFileExcludePatterns": ["vue-router"]
}
tsconfig.app.json
{
"include": [
// ...
"typed-router.d.ts" // 启动项目自动生成声明配置
],
"compilerOptions": {
// 解决路由自动引入TS错误,按照 commonJs 解析模块
// bundler 会交由打包工具作为解析(如webpack rollup vite)
"moduleResolution": "node"
}
}
创建 pages 文件夹
创建 index.vue,默认路由 /
<template>
<div class="home">index</div>
</template>
创建 404 模板, [...all].vue
<template>
<div class="error-page">Not Found</div>
</template>
<script setup lang="ts"></script>
<style scoped></style>
自动导入
导入依赖
自动导入 JavaScript 包中的模块,并将其添加到项目中的代码中。
pnpm i -D unplugin-auto-import@0.16.6
vite.config
import AutoImport from 'unplugin-auto-import/vite' // 自动导入依赖
import { VueRouterAutoImports } from 'unplugin-vue-router' // 帮助简化 Vue Router 的使用
export default defineConfig({
plugins: [
AutoImport({
include: [
/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
/\.vue$/,
/\.vue\?vue/, // .vue
/\.md$/ // .md
],
imports: [
'vue',
// 'vue-router', // 如果不使用自动化路由
VueRouterAutoImports // 如已配置自动路由、代替 vue-router
]
})
],
})
tsconfig.app.json
"include": [
"auto-imports.d.ts" // unplugin-auto-import 自动导入
],
示范
<template>
<h2>{{ msg }}</h2>
</template>
<script setup lang="ts">
const msg = ref('hello')
</script>
导入组件
pnpm add unplugin-vue-components@0.27.4 -D
pnpm i element-plus
vite.config
import Components from 'unplugin-vue-components/vite' // 自动组件导入
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' // 自动导入 element-plus
export default defineConfig({
plugins: [
// 自动导入组件
Components({
// 如 User 文件下的 user.vue 直接使用 <Useruser></Useruser>
directoryAsNamespace: true, // 以文件名开头作为前缀,因为一些组件会重名
// 如 User 文件下的 user.vue 直接使用 <User></User>
collapseSamePrefixes: true, // 如果文件名和组件前缀一致,则省略
resolvers: [
ElementPlusResolver() // 集成 element-plus
]
})
]
})
测试
<template>
<div class="container">
<HelloWorld msg="Hello" />
<el-button type="primary">Default</el-button>
</div>
</template>
<script setup lang="ts"></script>
Hooks
@vueuse/core 是一个集合了许多实用工具函数的库,旨在简化日常开发中的常见需求,这些工具函数涵盖了状态管理、事件监听、浏览器交互等多个方面
pnpm i @vueuse/core@10.2.1
vite.config.ts
AutoImport({
include: [
/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
/\.vue$/,
/\.vue\?vue/, // .vue
/\.md$/, // .md
],
imports: [
'vue',
// 'vue-router', // 如果不使用自动化路由
VueRouterAutoImports, // 自动路由专用 - 代替 vue-router
'@vueuse/core', // 提供一些常用的 hooks,vue 3.3 以后不需要
],
}),
组件中使用:
<template>
<div ref="target">
x:{{ x }} ,y:{{ y }} ,isOutside:{{ isOutside }}
</div>
</template>
<script setup lang="ts">
// import {useMouseInElement} from '@vueuse/core' // 如果没有配置自动导入
const target = ref(null)
const { x, y, isOutside } = useMouseInElement(target)
</script>
图标集
如果使用 tailwind 类似没有提供图标集的CSS框架,即可使用此工具; 简化项目中的图标管理,允许应用中轻松引入并使用各种流行的图标库(如 Material Design Icons, Font Awesome 等);
pnpm i -D unplugin-icons@0.22.0
配置自动导入,按需加载。vite.config.ts
import Components from 'unplugin-vue-components/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
export default defineConfig({
plugins: [
// 自动导入组件
Components({
// ...
resolvers: [
// 集成图标集
IconsResolver({
prefix: 'icon' // 私有前缀
})
]
}),
Icons({
autoInstall: true // 自动安装所需图标集
})
]
})
测试
<template>
<div>
<icon-mdi-account style="color: red" />
</div>
</template>
@iconify/json
pnpm i -D @iconify/json@2.2.260
uno.config.ts
import { defineConfig } from 'unocss'
import { presetWind, presetIcons } from 'unocss' // tailwind unocss 一起使用
export default defineConfig({
presets: [
presetWind(), // 样式一起使用
// 图标一起使用
presetIcons({
prefix: 'i-', // 图标前缀
extraProperties: {
display: 'inline-block', // 图标样式
},
}),
],
})
例
<template>
<div class="i-logos-vue"></div>
</template>
其他图标集推荐: react-icons lucide heroicons pikaicons
自动布局 layouts
pnpm i -D vite-plugin-vue-layouts
vite.config.ts
import Layouts from 'vite-plugin-vue-layouts'
export default defineConfig({
plugins: [
Layouts({
layoutsDirs: 'src/layouts', // 指定布局文件(Layout)的目录路径
defaultLayout: 'default' // 指定默认布局文件的名称
})
]
})
env.d.ts
/// <reference types="vite-plugin-vue-layouts/client" />
或 tsconfig.json
"types": ["vite-plugin-vue-layouts/client"]
router > main.ts
import { createRouter, createWebHistory } from 'vue-router/auto'
import { setupLayouts } from 'virtual:generated-layouts'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), // 路由的历史模式
// 扩展路由配置。它接受一个路由配置数组作为参数,并返回包含布局配置的新路由配置。
extendRoutes: (routes) => setupLayouts(routes)
})
创建 layouts 文件夹 > layouts 组件,如 default.vue
<template>
<div>
im defult layouts
<router-view></router-view>
</div>
</template>
pages 文件夹 > index.vue
<template>
<div>
<RouterLink to="/">home</RouterLink> |
<RouterLink to="/about">about</RouterLink>
</div>
</template>
<script setup lang="ts"></script>
<route lang="yaml">
meta:
layout: default
</route>
宏
版本 > 3.3 不需要
pnpm add -D unplugin-vue-macros @vue-macros/volar
vite.config.ts
plugins: [
// vue(),
// vueJsx(),
// 代替以上
VueMacros({
plugins: {
vue: vue(),
vueJsx: vueJsx()
}
})
]
示范
<template>
<button @click="handleClick">Click me</button>
</template>
<script setup lang="ts">
const num = ref(0)
// macros
const emits = defineEmits<{
(e: 'clickCount', num: number): void
}>()
// 官方:
// const emits2 = defineEmits<
// SE<{
// clickCount(num: number): void
// }>
// >()
const handleClick = () => {
console.log('click')
emits('clickCount', ++num.value)
}
</script>
mock
pnpm add mockjs vite-plugin-mock -D
vite.config.ts
import { viteMockServe } from 'vite-plugin-mock'
export default defineConfig({
plugins: [
viteMockServe({
mockPath: 'mock', // 模拟接口数据的文件存放在项目根目录下的 ‘mock’ 文件夹中。
enable: true // 是否启用模拟接口数据
})
]
})
根目录创建 mock 文件夹 >text.ts
import type { MockMethod } from 'vite-plugin-mock'
import fs from 'fs'
import path from 'path'
// 模拟数据
export default [
{
url: '/api/get', // 访问 http://localhost:5173/api/get
method: 'get',
response: () => {
return {
code: 0,
data: {
name: 'zs'
}
}
}
}
] as MockMethod[]
Pwa
pnpm add -D vite-plugin-pwa
vite.config.ts
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
VitePWA({
registerType: 'autoUpdate' // 自动更新
}),
]
})
env.d.ts
/// <reference types="vite-plugin-pwa/client" />
演示
import { registerSW } from 'virtual:pwa-register'
onMounted(() => {
registerSW({
immediate: true, // 立即注册
// pwa 注册完成 回调
onRegisteredSW(url, reg) {},
// 提示文件需要更新
onNeedRefresh() {
console.log('need refresh')
}
})
})
vite 5
pnpm i -D workbox-window
打包目录:
registerSW.js:注册 serviceWorker 文件
sw.js:文件核心信息记录