diff --git a/app/app.vue b/app/app.vue
index 8bf81d9..2f90720 100644
--- a/app/app.vue
+++ b/app/app.vue
@@ -1,15 +1,17 @@
-
+
+ color="repeating-linear-gradient(to right,var(--c-primary) 0%,var(--c-primary-active) 100%)"/>
+ }"/>
@@ -76,7 +78,8 @@ provide('slideDirection', slideDirection)
.slide-right-leave-to {
transform: translateX(100%);
}
-:root{
+
+:root {
--safe-area-inset-bottom: env(safe-area-inset-bottom);
}
\ No newline at end of file
diff --git a/app/plugins/http.js b/app/plugins/http.ts
similarity index 100%
rename from app/plugins/http.js
rename to app/plugins/http.ts
diff --git a/app/plugins/i18n.js b/app/plugins/i18n.ts
similarity index 85%
rename from app/plugins/i18n.js
rename to app/plugins/i18n.ts
index 127eda7..ad5fb7c 100644
--- a/app/plugins/i18n.js
+++ b/app/plugins/i18n.ts
@@ -1,4 +1,4 @@
-
+import type { Locale as TypeLocale } from '#i18n'
import { Locale } from 'vant'
import enUS from 'vant/es/locale/lang/en-US'
import zhCN from 'vant/es/locale/lang/zh-CN'
@@ -6,7 +6,7 @@ import jaJP from 'vant/es/locale/lang/ja-JP'
import zhTW from 'vant/es/locale/lang/zh-TW'
export default defineNuxtPlugin(() => {
-
+ // 载入 vant 语言包
Locale.use('zh-CN', zhCN)
Locale.use('en-US', enUS)
Locale.use('ja-JP', jaJP)
@@ -15,9 +15,11 @@ export default defineNuxtPlugin(() => {
if (import.meta.client) {
const i18n = useNuxtApp().$i18n
const { setLocale } = i18n
+
const lang = localStorage.getItem('lang')
+
if (lang) {
- setLocale(lang)
+ setLocale(lang as TypeLocale)
Locale.use(lang)
}
else {
diff --git a/app/styles/default-theme.css b/app/styles/default-theme.css
new file mode 100644
index 0000000..67a6e9b
--- /dev/null
+++ b/app/styles/default-theme.css
@@ -0,0 +1,4 @@
+:root:root {
+ --van-primary-color: var(--c-primary);
+ --van-cell-group-inset-padding: 0;
+}
diff --git a/app/styles/global.css b/app/styles/global.css
new file mode 100644
index 0000000..386966d
--- /dev/null
+++ b/app/styles/global.css
@@ -0,0 +1,14 @@
+#__nuxt {
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ background: var(--van-gray-1);
+ color-scheme: light;
+}
+
+html.dark {
+ background: #222;
+ color-scheme: dark;
+}
diff --git a/app/styles/vars.css b/app/styles/vars.css
new file mode 100644
index 0000000..07f427f
--- /dev/null
+++ b/app/styles/vars.css
@@ -0,0 +1,4 @@
+:root {
+ --c-primary: #3554AF;
+ --c-primary-active: #3554AF;
+}
diff --git a/nuxt.config.js b/nuxt.config.js
index 1d3da5c..7645cea 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -1,18 +1,9 @@
-// 导入环境变量处理库
import dotenv from 'dotenv'
-// 导入 Node.js 进程模块
import process from 'node:process'
-// 导入预加载工具函数
import preload from './app/utils/preload'
-// 导入国际化语言配置
import { currentLocales } from './i18n/i18n'
-
-// 设置环境变量文件路径,默认使用 .env.test
const envFile = process.env.ENV_FILE || '.env.test'
-// 加载环境变量配置
dotenv.config({ path: `./env/${envFile}` })
-
-// 过滤出以 NUXT_PUBLIC_ 开头的环境变量作为公共配置
const publicConfig = Object.entries(process.env)
.filter(([key]) => key.startsWith('NUXT_PUBLIC_'))
.reduce((config, [key, value]) => {
@@ -21,38 +12,38 @@ const publicConfig = Object.entries(process.env)
}, {})
export default defineNuxtConfig({
- // 注册 Nuxt 模块
- modules: [
- '@nuxt/image', // 图片优化模块
- '@vant/nuxt', // Vant UI 组件库
- '@unocss/nuxt', // 原子化 CSS 框架
- '@nuxtjs/i18n', // 国际化模块
- ],
- // 运行时配置
+ modules: [
+ '@vant/nuxt',
+ '@unocss/nuxt',
+ '@nuxt/image',
+ '@nuxtjs/color-mode',
+ '@nuxtjs/i18n',
+ ],
runtimeConfig: {
- // 私有配置,只在服务端可用
+ // 私有配置,只有在服务端可用
apiSecret: process.env.NUXT_API_SECRET || 'default_secret',
// 公共配置,客户端和服务端都可用
public: publicConfig,
},
- // CSS 配置
css: [
- '@unocss/reset/tailwind.css', // 重置默认样式
+ '@unocss/reset/tailwind.css',
'@/static/styles/default-theme.css',
],
- // PostCSS 配置
+
postcss: {
plugins: {
- 'autoprefixer': {}, // 自动添加 CSS 前缀
- // 移动端适配插件配置
+ 'autoprefixer': {},
+
+ // https://github.com/wswmsword/postcss-mobile-forever
'postcss-mobile-forever': {
- appSelector: '#__nuxt', // 根选择器
- viewportWidth: 375, // 设计稿宽度
- maxDisplayWidth: 600, // 最大显示宽度
- exclude: /@nuxt/, // 排除的文件
- border: true, // 显示边框
+ appSelector: '#__nuxt',
+ viewportWidth: 375,
+ maxDisplayWidth: 600,
+ // devtools excluded
+ exclude: /@nuxt/,
+ border: true,
rootContainingBlockSelectorList: [
'van-tabbar',
'van-popup',
@@ -61,153 +52,89 @@ export default defineNuxtConfig({
},
},
- // 国际化配置
- i18n: {
- locales: currentLocales, // 支持的语言列表
- lazy: true, // 懒加载语言包
- strategy: 'no_prefix', // URL 策略:不添加语言前缀
- detectBrowserLanguage: {
- useCookie: true, // 使用 cookie 存储语言选择
- cookieKey: 'i18n_redirected', // cookie 键名
- redirectOn: 'root', // 仅在根路径重定向
- alwaysRedirect: true, // 总是重定向
- fallbackLocale: 'zh-CN' // 默认语言
- },
- langDir: 'locales', // 语言文件目录
- defaultLocale: 'zh-CN', // 默认语言
- vueI18n: './i18n/i18n.config.ts', // Vue I18n 配置文件
+ colorMode: {
+ classSuffix: '',
+ preference: 'system',
+ fallback: 'light',
+ storageKey: 'nuxt-color-mode',
+ },
+
+ i18n: {
+ locales: currentLocales,
+ lazy: true,
+ strategy: 'no_prefix',
+ detectBrowserLanguage: {
+ useCookie: true,
+ cookieKey: 'i18n_redirected',
+ redirectOn: 'root',
+ alwaysRedirect: true,
+ fallbackLocale: 'zh-CN'
+ },
+ langDir: 'locales',
+ defaultLocale: 'zh-CN',
+ vueI18n: './i18n/i18n.config.ts',
},
- // 应用配置
app: {
- // 布局过渡动画
layoutTransition: {
name: 'layout',
mode: 'out-in'
},
- // 头部配置
head: {
- // 视口配置
viewport: 'width=device-width,initial-scale=1,viewport-fit=cover',
- // 链接配置
link: [
- { rel: 'icon', href: '/favicon.ico', sizes: 'any' }, // 网站图标
- { rel: 'preload', as: 'style', href: '/critical.css' }, // 预加载关键 CSS
- { rel: 'preconnect', href: '你的API域名' }, // 预连接 API 域名
- { rel: 'dns-prefetch', href: '你的API域名' }, // DNS 预解析
+ { rel: 'icon', href: '/favicon.ico', sizes: 'any' },
],
- // Meta 标签配置
meta: [
- { name: 'apple-mobile-web-app-capable', content: 'yes' }, // iOS 应用模式
- { name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent' }, // iOS 状态栏样式
- { name: 'theme-color', media: '(prefers-color-scheme: light)', content: '#ffffff' }, // 浅色主题色
- { name: 'theme-color', media: '(prefers-color-scheme: dark)', content: '#222222' }, // 深色主题色
- { name: 'description', content: '你的网站描述' }, // SEO 描述
- { 'http-equiv': 'x-dns-prefetch-control', content: 'on' }, // DNS 预解析控制
+ { name: 'viewport', content: 'width=device-width, initial-scale=1, viewport-fit=cover,user-scalable=no' },
+ { name: 'apple-mobile-web-app-capable', content: 'yes' },
+ { name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent' },
+ { name: 'theme-color', media: '(prefers-color-scheme: light)', content: '#ffffff' },
+ { name: 'theme-color', media: '(prefers-color-scheme: dark)', content: '#222222' },
],
- // 脚本配置
script: [
- { innerHTML: preload(), type: 'text/javascript', tagPosition: 'head' }, // 预加载脚本
- // 性能监控脚本
- {
- innerHTML: `
- window.performance.mark('app-start');
- new PerformanceObserver((entryList) => {
- for (const entry of entryList.getEntries()) {
- console.log('FCP:', entry.startTime);
- }
- }).observe({entryTypes: ['paint']});
- `,
- type: 'text/javascript',
- tagPosition: 'head'
- }
+ { innerHTML: preload(), type: 'text/javascript', tagPosition: 'head' },
],
},
},
- // Vite 构建配置
vite: {
build: {
- target: 'esnext', // 构建目标
- // Rollup 配置
- rollupOptions: {
- output: {
- manualChunks: {
- 'vant': ['vant'], // Vant 单独打包
- 'vendor': ['vue', 'vue-router'] // 核心库单独打包
- }
- }
- },
- minify: 'terser', // 使用 terser 压缩
- terserOptions: {
- compress: {
- drop_console: true, // 移除 console
- drop_debugger: true // 移除 debugger
- }
- }
+ target: 'esnext',
},
- // 依赖优化配置
optimizeDeps: {
include: [
- '@intlify/core-base', // I18n 核心
- '@intlify/shared', // I18n 共享库
- 'is-https', // HTTPS 检测
- 'vant', // Vant UI
- '@vant/use', // Vant Hooks
- '@vueuse/core', // VueUse 工具集
+ '@intlify/core-base',
+ '@intlify/shared',
+ 'is-https',
],
},
},
- // 实验性功能
experimental: {
- typedPages: true, // 启用页面类型
+ typedPages: true,
},
- // 开发工具
devtools: {
- enabled: true, // 启用开发工具
+ enabled: true,
},
- // TypeScript 配置
typescript: {
- shim: false, // 禁用 shim
+ shim: false,
},
- // 功能特性配置
features: {
- inlineStyles: false, // 禁用内联样式
+ // For UnoCSS
+ inlineStyles: false,
},
- // 未来特性配置
future: {
- compatibilityVersion: 4, // 兼容性版本
+ compatibilityVersion: 4,
},
-
- // Nuxt 兼容性日期
- compatibilityDate: '2025-01-09', // 确保未来版本兼容性
-
- // 开发服务器配置
+ // 指定 Nuxt 应用程序的兼容性日期,确保应用程序在未来的 Nuxt 版本中保持稳定性
+ compatibilityDate: '2025-01-09',
devServer: {
- host: '0.0.0.0', // 主机地址
- port: 3000, // 端口号
+ host: '0.0.0.0', // Set the host to 'localhost'
+ port: 3000, // Set the port to 3000 or any other port you prefer
},
-
- // 图片优化配置
- image: {
- provider: 'ipx', // 图片处理提供者
- // 响应式断点
- screens: {
- xs: 320, // 超小屏幕
- sm: 640, // 小屏幕
- md: 768, // 中等屏幕
- lg: 1024, // 大屏幕
- xl: 1280, // 超大屏幕
- xxl: 1536, // 特大屏幕
- },
- quality: 80, // 图片质量
- format: ['webp', 'jpg'], // 支持的格式
- placeholder: true, // 启用占位图
- blur: 3 // 模糊加载效果
- }
})
\ No newline at end of file