[Vue]常用工具配置
这篇文章中的各项配置都会写明环境和版本,以便于配置出现问题后追溯。此外这篇文章的目的是快速使用最佳实践构建项目,因此只会使用官方推荐的配置方法,小众的配置需求不会在这里出现。一些环境信息如下:
配置信息
系统Linux 6.11.6-arch1-1 | NodeJS23.1.0 | 编程语言TypeScript |
Vuevue@3.5.11 | Vitevite@5.4.8 |
AOS
aos 2.4.7nuxt-aos 1.2.5nuxt 3.13.2
Vue安装AOS
shell
npm install aos --save
ts
import { createApp } from 'vue';
import App from './App.vue';
import "aos/dist/aos.css";
import AOS from "aos";
AOS.init();
const app = createApp(App)
app.mount('#app')
ts
// /src/types/aos.d.ts
// 由于AOS完全使用JavaScript编写,因此在TS环境中使用时,可以自行为其添加类型声明文件
declare module "aos" {
interface AOSSettings {
offset?: number;
delay?: number;
easing?:
| "linear"
| "ease"
| "ease-in"
| "ease-out"
| "ease-in-out"
| "ease-in-back"
| "ease-out-back"
| "ease-in-out-back"
| "ease-in-sine"
| "ease-out-sine"
| "ease-in-out-sine"
| "ease-in-quad"
| "ease-out-quad"
| "ease-in-out-quad"
| "ease-in-cubic"
| "ease-out-cubic"
| "ease-in-out-cubic"
| "ease-in-quart"
| "ease-out-quart"
| "ease-in-out-quart" = "ease";
duration?: number;
disable?: boolean;
once?: boolean;
startEvent?: "DOMContentLoaded" | string;
throttleDelay?: number;
debounceDelay?: number;
disableMutationObserver?: boolean;
}
interface AOS {
init(options?: AOSSettings): void;
refresh(): void;
refreshHard(): void;
}
const aos: AOS;
export default aos;
}
Nuxt安装AOS
TIP
- 在部分教程中直接以自定义插件的方式引入
AOS
,并且defineNuxtPlugin
直接使用了默认配置。尽管AOS可能看起来正常工作,但我并不推荐这种方式,而是使用nuxt-aos
插件。 - 由于
AOS
的原理是通过MutationObserver
检测元素,并使用JS附加特定的类名添加动画。因此在Nuxt框架中使用时可能会触发**Hydration class mismatch (SSR)**的问题(尤其是在与Tailwind CSS共同使用时) - 而在
nuxt-aos
中,作者通过$nuxtApp.hook
,将AOS
的初始化时机放在page:finish
时,该时机在水合之后,以一种较为优雅的方式避免了上述问题。
shell
npx nuxi@latest module add aos
ts
// 如需全局覆盖默认配置,可以在该文件中进行配置
export default defineNuxtConfig({
aos: { // 写在这里
...
}
})
Element Plus
element-plus 2.8.7nuxt 3.13.2@element-plus/nuxt 1.0.10
Vue安装Element Plus
- 全量导入
全量导入使用起来方便,但打包后体积相对较大(尽管如此,Element Plus的体积也不算大)
shell
npm install element-plus --save
ts
import { createApp } from 'vue';
import App from './App.vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
- 按需导入 推荐
按需导入的优点很多,借助插件的话使用起来也很方便,比较推荐
shell
npm install element-plus --save
ts
import { defineConfig } from 'vite';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig({
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
Nuxt安装Element Plus
在Nuxt中安装Element Plus更加简单且统一:
shell
npm install -D @element-plus/nuxt
ts
export default defineNuxtConfig({
modules: ['@element-plus/nuxt'],
})
- 就这些,完事了
使用图标包
自定义主题
- Vue项目的配置方式
scss
// /src/assets/element-theme.scss
/**
* 新建一个样式文件,这里仅仅是将主题色改为红色
* 详见:<https://element-plus.org/zh-CN/guide/theming.html#如何覆盖它>
*/
@forward "element-plus/theme-chalk/src/common/var" with (
$colors: (
'primary': (
'base': #FF3E2C,
)
)
);
ts
// vite.config.ts
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
export default defineConfig({
plugins: [ // 这部分和官网的配置一样
AutoImport({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
Components({
resolvers: [ElementPlusResolver({ importStyle: "sass" })],
}),
],
// 由于修改了主题色,需要让vite重新编译scss,以生成新的主题色对应的一系列Element Plus内置变量
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/assets/element-theme.scss";`,
},
},
},
});
- Nuxt项目的配置方式
其实和Vue项目的配置几乎一样,只是将原本写在
vite.config.ts
的配置写到nuxt.config.ts
中的vite
字段中
scss
// /assets/element-theme.scss
/**
* 新建一个样式文件,这里仅仅是将主题色改为红色
* 详见:<https://element-plus.org/zh-CN/guide/theming.html#如何覆盖它>
*/
@forward "element-plus/theme-chalk/src/common/var" with (
$colors: (
'primary': (
'base': #FF3E2C,
)
)
);
ts
// nuxt.config.ts
export default defineNuxtConfig({
modules: ["@element-plus/nuxt"],
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/assets/element-theme.scss" as element;`,
},
},
},
},
elementPlus: {
importStyle: "scss",
}
});
shadcn-vue
- 谈及
shadcn/ui
和shadcn/vue
,就不得不提到HeadlessUI
。简而言之,这是一种新的组件库设计理念,有兴趣了解的可以看看这个:在 2023 年屌爆了一整年的 shadcn/ui 用的 Headless UI 到底是何方神圣? - 掘金。按照我的理解,它将组件视为“样式+逻辑”,并且将这二者解耦,组件库中干脆就没有样式,因此可以让开发者自由地按照设计实现样式(多是利用Tailwind CSS)。这种设计理念的优点在于,可以以一种较低的成本实现自定义样式,也就是便于二次开发。shadcn/ui
和shadcn/vue
就是基于这种设计理念的组件库。- 举个例子,如果需要你搭建一个风格类似于ChatGPT的页面,并且规模比较大——这意味着组件复用会很频繁,这种情况下花些时间二次封装一些Headless UI的组件,会比一点点覆盖现有组件库(如Element Plus)的样式要方便得多。
- 但目前,这种方式还有很多弊端:比如它只适合规模比较大、且对界面风格有较高需求的项目;另外,
HeadlessUI
的组件太少也是个大问题(虽然shadcn/ui
以及类似的HeadlessUI
库已经很大程度上弥补了这一问题);最后,这种方式的学习成本较高,因为你需要自己实现样式、响应式以及学习Tailwind CSS。- 但不管它会不会成为未来的设计范式,至少现在接触一下总没坏处,而且同时需要学的Tailwind CSS也是个快速开发的好工具。