Nuxt3项目初始化
项目初始化
安装
tex
npx nuxi@latest init <project-name>
构建
-
创建
src
目录。 -
nuxt.config.ts
中配置srcDir
。nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", })
-
src
目录下创建相关目录。texassets:资源目录(资源文件会被构建工具处理) components:组件目录 layouts:布局目录 middleware:中间件目录 pages:页面目录 plugins:插件目录 public:静态资源目录(资源文件不会被构建工具处理) store:状态树目录 app.vue:Nuxt应用程序入口文件
-
创建默认布局。
src/layouts/default.vue
vue<template> <div> <header>Header</header> <slot></slot> <footer>Footer</footer> </div> </template> <script setup lang="ts"></script> <style scoped></style>
-
创建
index
页面。src/pages/index.vue
vue<template> <div> Nuxt App </div> </template> <script setup lang="ts"> </script> <style scoped> </style>
-
修改
app.vue
。vue<template> <div> <!-- 布局组件 --> <NuxtLayout> <!-- 页面组件 --> <NuxtPage></NuxtPage> </NuxtLayout> </div> </template>
-
启动项目。
texnpm run dev
Tailwind CSS
安装
tex
npm install -D tailwindcss postcss autoprefixer
构建
-
创建
tailwind css
配置文件。texnpx tailwindcss init --ts
-
将
tailwind css
添加到postcss
中。nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, })
-
添加需要使用
tailwind css
的文件路径。tailwind.config.ts
typescriptimport type { Config } from "tailwindcss"; export default { content: ["./src/**/*.{js,vue,ts}", "./src/app.vue", "./src/error.vue"], theme: { extend: {}, }, plugins: [], } satisfies Config;
-
使用
tailwind css
默认样式。src/assets/css/main.css
css@tailwind base; @tailwind components; @tailwind utilities;
-
引入默认样式文件。
nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", css: ["~/assets/css/main.css"], postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, })
-
使用
tailwind css
。src/pages/index.vue
vue<template> <div class="text-xl">Nuxt App</div> </template> <script setup lang="ts"></script> <style scoped></style>
-
启动项目。
texnpm run dev
VueUse
安装
tex
npm i @vueuse/nuxt @vueuse/core
构建
-
添加
@vueuse/nuxt
模块。nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", css: ["~/assets/css/main.css"], postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, modules: ["@vueuse/nuxt"], })
-
使用
vueuse
。src/pages/index.vue
vue<template> <div> <h1>Nuxt App</h1> <p>X坐标:{{ x }}</p> <p>Y坐标:{{ y }}</p> </div> </template> <script setup lang="ts"> import { useMouse } from "@vueuse/core"; const { x, y } = useMouse(); </script> <style scoped></style>
-
启动项目。
texnpm run dev
Pinia
安装
tex
// pinia依赖
npm i pinia @pinia/nuxt
// pinia数据持久化依赖
npm i -D @pinia-plugin-persistedstate/nuxt
构建
-
添加
@pinia/nuxt
&@pinia-plugin-persistedstate/nuxt
模块。nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", css: ["~/assets/css/main.css"], postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, modules: ["@vueuse/nuxt", "@pinia/nuxt", "@pinia-plugin-persistedstate/nuxt"], })
-
创建状态树。
src/store/count.ts
typescriptimport { defineStore } from "pinia"; export const useCount = defineStore( "count", () => { const number = ref(0); const double = computed(() => number.value * 2); const increase = () => { number.value++; }; return { number, double, increase }; }, { // pinia数据持久化默认存储为cookie persist: true, } );
-
使用状态树。
src/pages/index.vue
vue<template> <div> <h1>Nuxt App</h1> <p>number: {{ store.number }}</p> <p>double: {{ store.double }}</p> <button @click="store.increase()">increase</button> </div> </template> <script setup lang="ts"> import { useCount } from "~/store/count"; const store = useCount(); </script> <style scoped></style>
-
启动项目。
texnpm run dev
状态持久化
Option Store
typescript
export const useCount = defineStore('count', {
state: () => ({
number: 0,
}),
getters: {
double() {
return this.number * 2;
}
},
actions: {
increase() {
this.number++;
}
},
// 数据持久化
persist: true
})
Setup Store
typescript
import { defineStore } from "pinia";
export const useCount = defineStore(
"count",
() => {
const number = ref(0);
const double = computed(() => number.value * 2);
const increase = () => {
number.value++;
};
return { number, double, increase };
},
{
// 数据持久化
persist: true,
}
);
默认配置
- 数据存储于
cookie
key
为store.$id
- 使用
JSON.stringify()
与JSON.parse()
进行序列化 / 反序列化- 整个
store
都会被保存
选项配置
key
:设置数据保存的key
值storage
:设置存储方式,使用persistedState
配置(cookie
、localStorage
、sessionStorage
)paths
:用于指定需要保存的数据serializer
:指定序列化方式debug
:用于设置是否打印错误
Icon
安装
tex
// 下载依赖同时将模块添加到nuxt.config.ts
npx nuxi module add icon
构建
-
设置
icon
前缀以及路径。nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", css: ["~/assets/css/main.css"], postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, modules: ["@vueuse/nuxt", "@pinia/nuxt", "@pinia-plugin-persistedstate/nuxt", "@nuxt/icon"], icon: { customCollections: [ // 通用icon { prefix: "common", dir: "./src/assets/icons/common", }, // 黑暗模式icon { prefix: "dark", dir: "./src/assets/icons/dark", }, // 明亮模式icon { prefix: "light", dir: "./src/assets/icons/light", }, ], }, })
ps:
由于需要切换明亮 & 黑暗模式,icon会改变。
但没有找到一个好的解决方案,替换icon颜色时填充部分也会添加上颜色。
所以选择使用明亮 & 暗黑两套icon。
如果阅读该文章的你有更好的解决方案,可以评论交流下,前端萌新来的。
-
使用
icon
图标。src/pages.index.vue
vue<template> <div> <h1>Nuxt App</h1> <div class="flex"> <!-- name: 前缀:icon文件名 --> <Icon name="light:search" /> <Icon name="light:cart" /> <Icon name="light:profile" /> </div> </div> </template> <script setup lang="ts"></script> <style scoped></style>
-
启动项目。
texnpm run dev
Color Mode
安装
tex
npm install --save-dev @nuxtjs/color-mode
构建
-
添加
@nuxtjs/color-mode
模块并配置colorMode
。nuxt.config.ts
typescriptexport default defineNuxtConfig({ devtools: { enabled: true }, srcDir: "./src", css: ["~/assets/css/main.css"], postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, }, }, modules: [ "@vueuse/nuxt", "@pinia/nuxt", "@pinia-plugin-persistedstate/nuxt", "@nuxt/icon", "@nuxtjs/color-mode" ], icon: { customCollections: [ // 通用icon { prefix: "common", dir: "./src/assets/icons/common", }, // 黑暗模式icon { prefix: "dark", dir: "./src/assets/icons/dark", }, // 明亮模式icon { prefix: "light", dir: "./src/assets/icons/light", }, ], }, colorMode: { preference: "light", // 初始值 fallback: "light", // 未找到系统默认值返回该值 classSuffix: "", // 设置class前缀 } })
-
切换模式。
src/pages/index.vue
vue<template> <div> <h1>Nuxt App</h1> <p>当前主题模式:{{ mode.value }}</p> <button @click="changeMode()">切换主题模式</button> </div> </template> <script setup lang="ts"> const mode = useColorMode(); const changeMode = () => { mode.preference = mode.value === "light" ? "dark" : "light"; }; </script> <style scoped></style>
-
启动项目。
texnpm run dev
主题切换
Tailwind CSS
&Color Mode
实现主题切换。
-
设置主题
css
变量。src/assets/css/main.css
css@tailwind base; @tailwind components; @tailwind utilities; @layer base { /* light模式 */ html { --primary-cover: #ffffff; --primary-title: #000000; --primary-content: #1a202c; --primary-subhead: rgba(26, 32, 44, 0.24); } /* dark模式 */ html[class="dark"] { --primary-cover: #1e1e27; --primary-title: #ffffff; --primary-content: #f7fafc; --primary-subhead: rgba(247, 250, 252, 0.24); } }
-
tailwind.config.ts
中扩展colors
。typescriptimport type { Config } from "tailwindcss"; export default { content: ["./src/**/*.{js,vue,ts}", "./src/app.vue", "./src/error.vue"], theme: { extend: { colors: { title: "var(--primary-title)", content: "var(--primary-content)", subhead: "var(--primary-subhead)", cover: "var(--primary-cover)", }, }, }, plugins: [], darkMode: "class", // 以class进行模式切换 } satisfies Config;
-
页面中使用主题颜色。
src/pages/index.vue
vue<template> <div class="bg-cover"> <h1 class="text-title">Nuxt App</h1> <p class="text-content">Content</p> <p class="text-subhead">Subhead</p> <div class="flex"> <!-- 仅在客户端渲染 --> <ClientOnly> <Icon :name="`${mode.value}:search`" /> <Icon :name="`${mode.value}:cart`" /> <Icon :name="`${mode.value}:profile`" /> </ClientOnly> </div> <p class="text-content">当前主题模式:{{ mode.value }}</p> <button class="text-content" @click="changeMode()">切换主题模式</button> </div> </template> <script setup lang="ts"> const mode = useColorMode(); const changeMode = () => { mode.preference = mode.value === "light" ? "dark" : "light"; }; </script> <style scoped></style>
-
启动项目。
texnpm run dev
明亮模式:
暗黑模式:
结语
至此
Nuxt3
+Tailwind CSS
项目初始化完成,其中集成Pinia
、VueUse
、Icon
以及Color Mode
。略有瑕疵但也希望能够帮助初学
Nuxt3
的各位。
ICON
不能使用样式或SVG
相关属性修改还是引发的一系列的问题。导致处于主题切换的
ICON
只能在客户端渲染,刷新时还是会有ICON
短暂闪烁。希望有大佬评论留下解决方案,哈哈。
前端萌新太难了~