refactor: 样式调整和代码优化
This commit is contained in:
@@ -145,7 +145,7 @@ page {
|
||||
```scss
|
||||
// ✅ 推荐:使用wot内置变量
|
||||
.my-component {
|
||||
background-color: var(--wot-card-bg);
|
||||
background-color: var(--wot-color-bg);
|
||||
color: var(--wot-color-text);
|
||||
}
|
||||
|
||||
|
||||
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -40,6 +40,7 @@ declare module 'vue' {
|
||||
WdProgress: typeof import('wot-design-uni/components/wd-progress/wd-progress.vue')['default']
|
||||
WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']
|
||||
WdRadioGroup: typeof import('wot-design-uni/components/wd-radio-group/wd-radio-group.vue')['default']
|
||||
WdSearch: typeof import('wot-design-uni/components/wd-search/wd-search.vue')['default']
|
||||
WdStatusTip: typeof import('wot-design-uni/components/wd-status-tip/wd-status-tip.vue')['default']
|
||||
WdSwiper: typeof import('wot-design-uni/components/wd-swiper/wd-swiper.vue')['default']
|
||||
WdSwitch: typeof import('wot-design-uni/components/wd-switch/wd-switch.vue')['default']
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
# 主题系统使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
本项目基于 Wot Design Uni 的 ConfigProvider 组件实现了完整的主题系统,支持:
|
||||
|
||||
- 🌙 暗黑/浅色模式切换
|
||||
- 🎨 12种预设主题色
|
||||
- 🎯 自定义主题色
|
||||
- 💾 主题设置持久化存储
|
||||
- 📱 多平台兼容(H5、小程序)
|
||||
|
||||
## 核心文件
|
||||
|
||||
### 1. useTheme Composable (`src/composables/useTheme.ts`)
|
||||
|
||||
主题管理的核心逻辑,提供:
|
||||
|
||||
```typescript
|
||||
const {
|
||||
theme, // 当前主题模式 'light' | 'dark'
|
||||
themeVars, // ConfigProviderThemeVars 主题变量
|
||||
toggleTheme, // 切换主题模式
|
||||
setThemeColor, // 设置主题色
|
||||
resetTheme, // 重置主题
|
||||
initTheme, // 初始化主题
|
||||
colorColumns, // 预设主题色列表
|
||||
} = useTheme();
|
||||
```
|
||||
|
||||
### 2. 布局文件
|
||||
|
||||
#### Tabbar 布局 (`src/layouts/tabbar.vue`)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<wd-config-provider
|
||||
:theme="theme"
|
||||
:theme-vars="themeVars"
|
||||
custom-style="min-height: 100vh"
|
||||
:class="{ 'wot-theme-dark': theme === 'dark' }"
|
||||
>
|
||||
<!-- 页面内容 -->
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### Default 布局 (`src/layouts/default.vue`)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<wd-config-provider
|
||||
:theme="theme"
|
||||
:theme-vars="themeVars"
|
||||
custom-style="background-color: #f5f5f5;min-height: 100vh"
|
||||
:class="{ 'wot-theme-dark': theme === 'dark' }"
|
||||
>
|
||||
<!-- 页面内容 -->
|
||||
</wd-config-provider>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 3. 主题设置页面 (`src/pages/mine/settings/theme/index.vue`)
|
||||
|
||||
提供用户界面来:
|
||||
|
||||
- 切换暗黑/浅色模式
|
||||
- 选择预设主题色
|
||||
- 输入自定义主题色
|
||||
- 预览主题效果
|
||||
- 重置主题设置
|
||||
|
||||
## 主题变量
|
||||
|
||||
### 支持的 ConfigProviderThemeVars
|
||||
|
||||
根据 Wot Design Uni 文档,主要使用:
|
||||
|
||||
```typescript
|
||||
interface ConfigProviderThemeVars {
|
||||
colorTheme?: string; // 主题色
|
||||
buttonPrimaryBgColor?: string; // 主按钮背景色
|
||||
buttonPrimaryColor?: string; // 主按钮文字色
|
||||
// ... 更多变量
|
||||
}
|
||||
```
|
||||
|
||||
### 预设主题色
|
||||
|
||||
```typescript
|
||||
const colorColumns = [
|
||||
{ value: "#165DFF", label: "蓝色" },
|
||||
{ value: "#0FC6C2", label: "青绿色" },
|
||||
{ value: "#722ED1", label: "紫色" },
|
||||
{ value: "#F5222D", label: "红色" },
|
||||
{ value: "#FA8C16", label: "橙色" },
|
||||
{ value: "#FADB14", label: "黄色" },
|
||||
{ value: "#52C41A", label: "绿色" },
|
||||
{ value: "#EB2F96", label: "粉色" },
|
||||
{ value: "#13C2C2", label: "青色" },
|
||||
{ value: "#1890FF", label: "天蓝色" },
|
||||
{ value: "#CD5C5C", label: "经典红" },
|
||||
{ value: "#228B22", label: "自然绿" },
|
||||
];
|
||||
```
|
||||
|
||||
## 暗黑模式实现
|
||||
|
||||
### 1. ConfigProvider 主题切换
|
||||
|
||||
```vue
|
||||
<wd-config-provider :theme="theme">
|
||||
<!-- theme 为 'dark' 时自动应用暗黑模式 -->
|
||||
</wd-config-provider>
|
||||
```
|
||||
|
||||
### 2. 全局样式适配
|
||||
|
||||
在 `src/uni.scss` 中定义:
|
||||
|
||||
```scss
|
||||
.wot-theme-dark {
|
||||
background-color: #1a1a1a !important;
|
||||
color: #f5f5f5 !important;
|
||||
|
||||
/* H5 环境 body 样式 */
|
||||
body {
|
||||
background-color: #1a1a1a !important;
|
||||
color: #f5f5f5 !important;
|
||||
}
|
||||
|
||||
/* 其他组件暗黑模式适配 */
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 动态 Body 样式
|
||||
|
||||
在 `useTheme` 中自动处理:
|
||||
|
||||
```typescript
|
||||
const applyDarkModeBodyStyle = (isDark: boolean) => {
|
||||
// #ifdef H5
|
||||
if (typeof document !== "undefined") {
|
||||
const body = document.body;
|
||||
if (isDark) {
|
||||
body.style.backgroundColor = "#1a1a1a";
|
||||
body.style.color = "#f5f5f5";
|
||||
body.classList.add("wot-theme-dark");
|
||||
} else {
|
||||
body.style.backgroundColor = "#f8f8f8";
|
||||
body.style.color = "#333";
|
||||
body.classList.remove("wot-theme-dark");
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
};
|
||||
```
|
||||
|
||||
## 持久化存储
|
||||
|
||||
主题设置自动保存到本地存储:
|
||||
|
||||
```typescript
|
||||
// 存储键名
|
||||
const THEME_STORAGE_KEY = "app_theme_mode";
|
||||
const THEME_COLOR_STORAGE_KEY = "app_theme_color";
|
||||
|
||||
// 自动监听变化并保存
|
||||
watch(
|
||||
theme,
|
||||
(newTheme) => {
|
||||
saveThemeToStorage(newTheme);
|
||||
applyDarkModeBodyStyle(newTheme === "dark");
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 在页面中使用主题
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<view>
|
||||
<wd-button type="primary">主题色按钮</wd-button>
|
||||
<text :style="{ color: themeVars.colorTheme }">主题色文本</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useTheme } from "@/composables/useTheme";
|
||||
|
||||
const { theme, themeVars, toggleTheme, setThemeColor } = useTheme();
|
||||
|
||||
// 切换主题模式
|
||||
const handleToggleTheme = () => {
|
||||
toggleTheme();
|
||||
};
|
||||
|
||||
// 设置主题色
|
||||
const handleSetColor = (color: string) => {
|
||||
setThemeColor(color);
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
### 在组件中响应主题变化
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<view :class="{ 'dark-mode': isDark }">
|
||||
<!-- 组件内容 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { useTheme } from "@/composables/useTheme";
|
||||
|
||||
const { theme } = useTheme();
|
||||
|
||||
const isDark = computed(() => theme.value === "dark");
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.dark-mode {
|
||||
background-color: #2a2a2a;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 组件开发
|
||||
|
||||
- 使用 Wot Design Uni 组件时,主题色会自动应用
|
||||
- 自定义组件需要手动适配暗黑模式
|
||||
- 使用 `:class="{ 'wot-theme-dark': theme === 'dark' }"` 来应用暗黑模式样式
|
||||
|
||||
### 2. 样式编写
|
||||
|
||||
```scss
|
||||
.my-component {
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
|
||||
// 暗黑模式适配
|
||||
.wot-theme-dark & {
|
||||
background-color: #2a2a2a;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 主题色使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 直接使用主题色 -->
|
||||
<view :style="{ borderColor: themeVars.colorTheme }">
|
||||
<!-- 内容 -->
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **ConfigProvider 包裹**:确保页面被 ConfigProvider 包裹才能应用主题
|
||||
2. **样式优先级**:暗黑模式样式需要足够的优先级,必要时使用 `!important`
|
||||
3. **平台兼容**:小程序和 H5 的样式处理略有不同,使用条件编译处理
|
||||
4. **性能考虑**:主题切换时避免频繁的 DOM 操作
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 添加新的主题色
|
||||
|
||||
在 `colorColumns` 中添加新的颜色:
|
||||
|
||||
```typescript
|
||||
export const colorColumns = [
|
||||
// ... 现有颜色
|
||||
{ value: "#FF6B6B", label: "珊瑚红" },
|
||||
{ value: "#4ECDC4", label: "薄荷绿" },
|
||||
];
|
||||
```
|
||||
|
||||
### 添加更多主题变量
|
||||
|
||||
```typescript
|
||||
const themeVars = ref<ConfigProviderThemeVars>({
|
||||
colorTheme: getStoredThemeColor(),
|
||||
buttonPrimaryBgColor: getStoredThemeColor(),
|
||||
// 添加更多变量
|
||||
});
|
||||
```
|
||||
|
||||
### 自定义暗黑模式样式
|
||||
|
||||
在 `uni.scss` 中添加更多组件的暗黑模式适配:
|
||||
|
||||
```scss
|
||||
.wot-theme-dark {
|
||||
// 新组件的暗黑模式样式
|
||||
.my-custom-component {
|
||||
background-color: #2a2a2a;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,426 +0,0 @@
|
||||
# uni-mini-router 在UniApp中的整合教程
|
||||
|
||||
## 一、uni-mini-router简介
|
||||
|
||||
uni-mini-router是一个轻量级的路由管理库,专为uni-app设计,解决了uni-app原生路由系统中没有路由拦截等关键功能的问题。它提供了类似Vue Router的API体验,使得在uni-app项目中实现更加灵活和强大的路由管理成为可能。
|
||||
|
||||
### 主要特点:
|
||||
|
||||
1. **Vue Router风格API**:提供与Vue Router相似的API,降低学习成本
|
||||
2. **路由拦截功能**:支持全局导航守卫,可以在路由跳转前后执行逻辑
|
||||
3. **优雅的参数传递**:支持params和query方式传参
|
||||
4. **命名路由**:支持通过路由名称进行导航
|
||||
5. **类型支持**:完整的TypeScript类型定义
|
||||
6. **轻量级**:体积小,性能高效
|
||||
|
||||
## 二、安装与基本配置
|
||||
|
||||
### 1. 安装uni-mini-router
|
||||
|
||||
使用npm或yarn安装uni-mini-router:
|
||||
|
||||
```bash
|
||||
pnpm add - uni-mini-router
|
||||
```
|
||||
|
||||
### 2. 初始化路由
|
||||
|
||||
在项目中创建router目录并初始化路由配置:
|
||||
|
||||
```typescript
|
||||
// src/router/index.ts
|
||||
import { createRouter } from 'uni-mini-router'
|
||||
import { pages, subPackages } from 'virtual:uni-pages'
|
||||
|
||||
// 生成路由配置
|
||||
function generateRoutes() {
|
||||
const routes = pages.map((page) => {
|
||||
const newPath = `/${page.path}`
|
||||
return { ...page, path: newPath }
|
||||
})
|
||||
|
||||
// 处理分包路由
|
||||
if (subPackages && subPackages.length > 0) {
|
||||
subPackages.forEach((subPackage) => {
|
||||
const subRoutes = subPackage.pages.map((page: any) => {
|
||||
const newPath = `/${subPackage.root}/${page.path}`
|
||||
return { ...page, path: newPath }
|
||||
})
|
||||
routes.push(...subRoutes)
|
||||
})
|
||||
}
|
||||
|
||||
return routes
|
||||
}
|
||||
|
||||
// 创建路由实例
|
||||
const router = createRouter({
|
||||
routes: generateRoutes(),
|
||||
})
|
||||
|
||||
export default router
|
||||
```
|
||||
|
||||
### 3. 在main.ts中挂载路由
|
||||
|
||||
```typescript
|
||||
// src/main.ts
|
||||
import { createSSRApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
|
||||
// 使用路由
|
||||
app.use(router)
|
||||
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 配置自动导入(可选,推荐)
|
||||
|
||||
使用unplugin-auto-import插件可以自动导入路由相关hooks,无需每次手动导入:
|
||||
|
||||
```typescript
|
||||
// vite.config.ts
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
AutoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
{
|
||||
from: 'uni-mini-router',
|
||||
imports: ['createRouter', 'useRouter', 'useRoute']
|
||||
}
|
||||
],
|
||||
dts: 'src/auto-imports.d.ts'
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
## 三、路由基本用法
|
||||
|
||||
### 1. 编程式导航
|
||||
|
||||
uni-mini-router提供了多种导航方法:
|
||||
|
||||
```typescript
|
||||
const router = useRouter()
|
||||
|
||||
// 字符串路径导航
|
||||
router.push('/pages/index/index')
|
||||
|
||||
// 对象导航(通过路径)
|
||||
router.push({ path: '/pages/index/index' })
|
||||
|
||||
// 对象导航(通过名称)
|
||||
router.push({ name: 'index' })
|
||||
|
||||
// 携带参数
|
||||
router.push({
|
||||
path: '/pages/detail/index',
|
||||
query: { id: 10 }
|
||||
})
|
||||
|
||||
// 通过名称 + 参数
|
||||
router.push({
|
||||
name: 'detail',
|
||||
params: { id: 10 }
|
||||
})
|
||||
|
||||
// Tab页面导航
|
||||
router.pushTab('/pages/home/index')
|
||||
|
||||
// 关闭当前页面并跳转
|
||||
router.replace('/pages/index/index')
|
||||
|
||||
// 关闭所有页面并跳转
|
||||
router.replaceAll('/pages/index/index')
|
||||
|
||||
// 返回上一级
|
||||
router.back()
|
||||
|
||||
// 返回多级
|
||||
router.back(2)
|
||||
```
|
||||
|
||||
### 2. 获取和使用路由信息
|
||||
|
||||
```typescript
|
||||
const route = useRoute()
|
||||
|
||||
// 访问当前路由信息
|
||||
console.log(route.path) // 当前路由路径
|
||||
console.log(route.name) // 当前路由名称
|
||||
console.log(route.query) // 查询参数
|
||||
console.log(route.params) // 路由参数
|
||||
```
|
||||
|
||||
### 3. 接收页面参数
|
||||
|
||||
在页面组件中接收传递的参数:
|
||||
|
||||
```typescript
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
// 方法1: 直接从route对象获取
|
||||
const id = route.query.id || route.params.id
|
||||
|
||||
// 方法2: 通过onLoad生命周期获取
|
||||
onLoad((option) => {
|
||||
console.log('页面参数:', option)
|
||||
// option中包含所有传递的参数
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
> ⚠️ **重要说明**:在uni-mini-router中,params和query参数都会转换为查询字符串放在URL中,两者在实际效果上没有区别。这种设计是为了与Vue Router保持API一致性。
|
||||
|
||||
## 四、导航守卫
|
||||
|
||||
uni-mini-router提供了全局导航守卫功能,可以在路由跳转前后执行自定义逻辑。
|
||||
|
||||
### 1. 全局前置守卫
|
||||
|
||||
```typescript
|
||||
// src/router/index.ts
|
||||
router.beforeEach((to, from, next) => {
|
||||
console.log('路由跳转:', from.path, '->', to.path)
|
||||
|
||||
// 检查是否需要登录
|
||||
if (to.meta && to.meta.requireAuth) {
|
||||
// 检查登录状态
|
||||
const isLoggedIn = uni.getStorageSync('token')
|
||||
|
||||
if (!isLoggedIn) {
|
||||
// 未登录,跳转到登录页
|
||||
uni.showToast({ title: '请先登录', icon: 'none' })
|
||||
next('/pages/login/index')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 继续导航
|
||||
next()
|
||||
})
|
||||
```
|
||||
|
||||
### 2. 全局后置守卫
|
||||
|
||||
```typescript
|
||||
// src/router/index.ts
|
||||
router.afterEach((to, from) => {
|
||||
console.log('路由跳转完成:', to.path)
|
||||
|
||||
// 可以在这里做一些统计或记录
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 路由元数据配置
|
||||
|
||||
可以在页面文件中使用`<route>`自定义块来定义路由元数据:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 页面内容 -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 页面逻辑
|
||||
</script>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"name": "protected-page",
|
||||
"meta": {
|
||||
"requireAuth": true,
|
||||
"title": "需要登录的页面"
|
||||
}
|
||||
}
|
||||
</route>
|
||||
```
|
||||
|
||||
## 五、实战示例:登录权限控制
|
||||
|
||||
### 1. 定义带有权限控制的路由
|
||||
|
||||
```typescript
|
||||
// src/router/index.ts
|
||||
import { createRouter } from 'uni-mini-router'
|
||||
|
||||
const router = createRouter({
|
||||
routes: generateRoutes()
|
||||
})
|
||||
|
||||
// 全局前置守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
// 检查页面是否需要登录
|
||||
if (to.meta && to.meta.requireAuth) {
|
||||
const token = uni.getStorageSync('token')
|
||||
|
||||
if (!token) {
|
||||
// 显示登录提示
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '该功能需要登录后使用',
|
||||
confirmText: '去登录',
|
||||
cancelText: '返回',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 记住原来要去的页面
|
||||
uni.setStorageSync('redirect', to.fullPath)
|
||||
next('/pages/login/index')
|
||||
} else {
|
||||
// 取消则返回首页
|
||||
next('/pages/index/index')
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 继续导航
|
||||
next()
|
||||
})
|
||||
|
||||
export default router
|
||||
```
|
||||
|
||||
### 2. 登录成功后跳转回原页面
|
||||
|
||||
```vue
|
||||
<!-- src/pages/login/index.vue -->
|
||||
<script setup>
|
||||
const router = useRouter()
|
||||
|
||||
function handleLogin() {
|
||||
// 模拟登录请求
|
||||
setTimeout(() => {
|
||||
// 登录成功,存储token
|
||||
uni.setStorageSync('token', 'user_token_example')
|
||||
|
||||
// 获取之前要去的页面
|
||||
const redirect = uni.getStorageSync('redirect') || '/pages/index/index'
|
||||
uni.removeStorageSync('redirect')
|
||||
|
||||
// 跳转回原来的页面
|
||||
router.replaceAll(redirect)
|
||||
}, 1000)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 六、最佳实践与性能优化
|
||||
|
||||
### 1. 合理使用跳转方式
|
||||
|
||||
- **router.push**:需要保留当前页面、可返回时使用
|
||||
- **router.replace**:不需要返回当前页面时使用
|
||||
- **router.replaceAll**:需要清除所有页面栈时使用(如登录后)
|
||||
- **router.pushTab**:跳转到tabBar页面时使用
|
||||
|
||||
### 2. 参数传递最佳实践
|
||||
|
||||
- 对于简单数据,直接使用参数传递
|
||||
- 对于复杂数据或对象,可使用以下方法:
|
||||
|
||||
```typescript
|
||||
// 传递复杂对象
|
||||
const complexData = { name: 'product', details: { id: 1, features: ['a', 'b'] } }
|
||||
|
||||
// 方法1: JSON序列化 + URL编码
|
||||
router.push({
|
||||
path: '/pages/detail/index',
|
||||
query: { data: encodeURIComponent(JSON.stringify(complexData)) }
|
||||
})
|
||||
|
||||
// 接收页面
|
||||
onLoad((option) => {
|
||||
if (option.data) {
|
||||
try {
|
||||
const data = JSON.parse(decodeURIComponent(option.data))
|
||||
console.log(data)
|
||||
} catch (e) {
|
||||
console.error('参数解析错误', e)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 方法2: 对于非常大的数据,考虑使用全局状态管理或本地存储
|
||||
```
|
||||
|
||||
### 3. 路由懒加载
|
||||
|
||||
uni-mini-router自动支持小程序的分包加载特性,可以在pages.json中配置分包:
|
||||
|
||||
```json
|
||||
{
|
||||
"pages": [
|
||||
// 主包页面
|
||||
],
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "pages/module",
|
||||
"pages": [
|
||||
{
|
||||
"path": "detail/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "详情页"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 七、路由调试与测试
|
||||
|
||||
### 1. 路由日志记录
|
||||
|
||||
```typescript
|
||||
// src/router/index.ts
|
||||
router.beforeEach((to, from, next) => {
|
||||
console.log(`[Router] ${from.path || '初始页面'} -> ${to.path}`, {
|
||||
params: to.params,
|
||||
query: to.query,
|
||||
})
|
||||
next()
|
||||
})
|
||||
```
|
||||
|
||||
### 2. 常见问题解决
|
||||
|
||||
1. **路由参数获取不到**:
|
||||
- 检查传参方式是否正确
|
||||
- 使用`console.log`打印完整的option对象
|
||||
- 尝试同时检查route.query和route.params
|
||||
|
||||
2. **页面未注册**:
|
||||
- 确保页面已在pages.json中正确注册
|
||||
- 检查路径大小写是否正确
|
||||
|
||||
3. **导航守卫不生效**:
|
||||
- 确保在路由配置后调用守卫
|
||||
- 检查是否正确调用next()函数
|
||||
|
||||
## 总结
|
||||
|
||||
uni-mini-router为uni-app提供了Vue Router风格的路由解决方案,特别是增加了路由拦截功能,解决了uni-app原生路由的限制。通过简单配置,就能在uni-app中实现更加灵活的路由管理,包括权限控制、参数传递和路由拦截等高级功能。
|
||||
|
||||
使用uni-mini-router可以让你的uni-app项目路由管理更加规范化和工程化,提升开发效率和代码质量。
|
||||
|
||||
参考资料:
|
||||
- [uni-mini-router GitHub仓库](https://github.com/Moonofweisheng/uni-mini-router)
|
||||
- [uni-mini-router官方文档](https://moonofweisheng.github.io/uni-mini-router/)
|
||||
- [uni-app官方路由文档](https://uniapp.dcloud.net.cn/tutorial/page.html)
|
||||
@@ -129,4 +129,4 @@
|
||||
]
|
||||
},
|
||||
"subPackages": []
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,26 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<!-- 自定义导航栏 -->
|
||||
<view class="custom-navbar">
|
||||
<!-- 状态栏占位 -->
|
||||
<view :style="{ height: statusBarHeight + 'px' }"></view>
|
||||
<!-- 导航栏内容 -->
|
||||
<view class="navbar-content">
|
||||
<wd-search
|
||||
v-model="searchValue"
|
||||
:custom-style="`width: ${searchWidth}`"
|
||||
placeholder="搜索"
|
||||
:placeholder-left="true"
|
||||
hide-cancel
|
||||
disabled
|
||||
@click="handleSearch"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 占位符,避免内容被固定导航栏遮挡 -->
|
||||
<view class="navbar-placeholder" :style="{ paddingTop: statusBarHeight + 'px' }"></view>
|
||||
|
||||
<!-- 轮播图 -->
|
||||
<wd-swiper
|
||||
v-model:current="current"
|
||||
:list="swiperList"
|
||||
@@ -104,6 +125,36 @@ interface VisitStatsVO {
|
||||
const router = useRouter();
|
||||
const current = ref<number>(0);
|
||||
|
||||
// 搜索相关
|
||||
const searchValue = ref("");
|
||||
|
||||
// 导航栏相关数据
|
||||
const statusBarHeight = ref(0); // 状态栏高度
|
||||
const navBarHeight = ref(88); // 导航栏高度(rpx)
|
||||
const searchWidth = ref("100%"); // 搜索框宽度
|
||||
|
||||
// 初始化导航栏信息
|
||||
onMounted(() => {
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
statusBarHeight.value = systemInfo.statusBarHeight || 0;
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序:获取胶囊按钮信息
|
||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
// 计算导航栏高度:(胶囊底部 - 状态栏高度) + (胶囊顶部 - 状态栏高度)
|
||||
navBarHeight.value =
|
||||
menuButtonInfo.bottom - statusBarHeight.value + (menuButtonInfo.top - statusBarHeight.value);
|
||||
// 搜索框宽度:胶囊左侧位置 - 左右边距
|
||||
searchWidth.value = `${menuButtonInfo.left - 30}px`;
|
||||
// #endif
|
||||
|
||||
// #ifdef H5 || APP-PLUS
|
||||
// H5 和 App 使用默认高度和 100% 宽度
|
||||
navBarHeight.value = 88;
|
||||
searchWidth.value = "100%";
|
||||
// #endif
|
||||
});
|
||||
|
||||
const visitStatsData = ref<VisitStatsVO>({
|
||||
todayUvCount: 1234,
|
||||
uvGrowthRate: 15.6,
|
||||
@@ -171,6 +222,14 @@ const navList = reactive([
|
||||
},
|
||||
]);
|
||||
|
||||
// 处理搜索
|
||||
function handleSearch() {
|
||||
uni.showToast({
|
||||
title: "搜索功能开发中",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
|
||||
// 处理导航点击
|
||||
function handleNavClick(item: any) {
|
||||
// 使用路由系统进行导航,这样会触发路由守卫
|
||||
@@ -267,4 +326,29 @@ onReady(() => {
|
||||
"layout": "tabbar"
|
||||
}
|
||||
</route>
|
||||
<style setup lang="scss"></style>
|
||||
<style lang="scss" scoped>
|
||||
// 自定义导航栏
|
||||
.custom-navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
background-color: var(--wot-color-bg);
|
||||
}
|
||||
|
||||
// 占位符,避免内容被固定导航栏遮挡
|
||||
.navbar-placeholder {
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
.navbar-content {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 88rpx;
|
||||
padding: 0 20rpx;
|
||||
background-color: var(--wot-color-bg);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="login-page dark:text-[var(--wot-dark-color)]">
|
||||
<view class="login-page dark:text-[var(--wot-color-text)]">
|
||||
<!-- 背景图 -->
|
||||
<image src="/static/images/login-bg.svg" mode="aspectFill" class="login-page__bg" />
|
||||
|
||||
@@ -294,9 +294,9 @@ const navigateToPrivacy = () => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center; // 垂直居中
|
||||
min-height: 100vh;
|
||||
overflow: hidden;
|
||||
background-color: var(--wot-color-bg-container);
|
||||
|
||||
// 背景图
|
||||
&__bg {
|
||||
@@ -313,11 +313,13 @@ const navigateToPrivacy = () => {
|
||||
.login-card {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 80%; // 进一步减少宽度,增加更多左右间距
|
||||
padding: 40rpx;
|
||||
margin-top: 200rpx;
|
||||
background-color: var(--wot-card-bg);
|
||||
width: 80%;
|
||||
max-width: 600rpx; // 限制最大宽度
|
||||
padding: 50rpx 40rpx;
|
||||
background-color: var(--wot-color-bg);
|
||||
border: 1rpx solid var(--wot-color-border);
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
// 登录表单
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-card>
|
||||
<view class="about-header">
|
||||
<wd-img
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<view>
|
||||
<view class="text-center font-600">
|
||||
<text>长按关注「有来技术」公众号,获取交流群二维码。</text>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-text size="small">选填,最多上传3张图片</wd-text>
|
||||
<wd-form ref="formRef" :model="formData" :rules="rules">
|
||||
<wd-form-item label="问题类型" prop="feedbackType">
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<!-- 用户信息卡片 -->
|
||||
<view class="user-profile">
|
||||
<view class="blur-bg"></view>
|
||||
|
||||
<view class="user-info">
|
||||
<view class="avatar-container" @click="navigateToProfile">
|
||||
<image
|
||||
@@ -30,17 +31,15 @@
|
||||
</wd-button>
|
||||
</block>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<view class="user-profile__action" @click="navigateToSettings">
|
||||
<wd-icon name="setting1" size="22" :color="themeStore.isDark ? '#fff' : '#333'" />
|
||||
|
||||
<!-- 操作按钮区域 - 放在用户信息右侧 -->
|
||||
<view class="action-buttons">
|
||||
<view class="action-btn" @click="navigateToSettings">
|
||||
<wd-icon name="setting1" size="22" />
|
||||
</view>
|
||||
<view
|
||||
v-if="isLogin"
|
||||
class="user-profile__action relative ml-16rpx"
|
||||
@click="navigateToSection('messages')"
|
||||
>
|
||||
<view v-if="isLogin" class="action-btn relative" @click="navigateToSection('messages')">
|
||||
<wd-icon name="notification" size="22" />
|
||||
<view v-if="true" class="user-profile__badge">2</view>
|
||||
<view v-if="true" class="action-badge">2</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -71,7 +70,7 @@
|
||||
</wd-card>
|
||||
|
||||
<!-- 常用工具 -->
|
||||
<wd-card custom-class="tools-card">
|
||||
<wd-card>
|
||||
<template #header>
|
||||
<view class="flex-start">
|
||||
<wd-icon name="tools" size="18" :color="currentThemeColor" />
|
||||
@@ -116,7 +115,7 @@
|
||||
</wd-card>
|
||||
|
||||
<!-- 推荐服务 -->
|
||||
<wd-card custom-class="services-card">
|
||||
<wd-card>
|
||||
<template #header>
|
||||
<view class="flex-start">
|
||||
<wd-icon name="star" size="18" :color="currentThemeColor" />
|
||||
@@ -170,7 +169,7 @@
|
||||
</wd-card>
|
||||
|
||||
<!-- 退出登录按钮 -->
|
||||
<view v-if="isLogin">
|
||||
<view v-if="isLogin" class="flex-center mt-20rpx">
|
||||
<wd-button custom-class="logout-button" plain @click="handleLogout">退出登录</wd-button>
|
||||
</view>
|
||||
|
||||
@@ -178,6 +177,14 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"name": "mine",
|
||||
"style": { "navigationStyle": "custom" },
|
||||
"layout": "tabbar"
|
||||
}
|
||||
</route>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useToast } from "wot-design-uni";
|
||||
import { useUserStore, useThemeStore } from "@/store";
|
||||
@@ -255,19 +262,11 @@ const navigateToSection = (section: string, subSection?: string) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"name": "mine",
|
||||
"style": { "navigationStyle": "custom" },
|
||||
"layout": "tabbar"
|
||||
}
|
||||
</route>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 用户信息卡片
|
||||
.user-profile {
|
||||
position: relative;
|
||||
padding: 30rpx;
|
||||
padding: calc(var(--status-bar-height) + 80rpx) 30rpx 30rpx; // 顶部:状态栏高度 + 操作按钮区域(80rpx)
|
||||
overflow: hidden;
|
||||
|
||||
.blur-bg {
|
||||
@@ -276,7 +275,7 @@ const navigateToSection = (section: string, subSection?: string) => {
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
height: 240rpx;
|
||||
height: 320rpx;
|
||||
background: linear-gradient(135deg, var(--wot-color-theme, #165dff) 0%, #667eea 100%);
|
||||
}
|
||||
|
||||
@@ -321,30 +320,29 @@ const navigateToSection = (section: string, subSection?: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
// BEM命名规范的用户操作按钮
|
||||
.user-profile__action {
|
||||
// 操作按钮区域
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
background-color: rgba(255, 255, 255, 0.25);
|
||||
backdrop-filter: blur(10rpx);
|
||||
border-radius: 50%;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
transform: scale(0.9);
|
||||
}
|
||||
}
|
||||
|
||||
// 通知徽章 - 超过5个原子类,使用CSS类
|
||||
.user-profile__badge {
|
||||
.action-badge {
|
||||
position: absolute;
|
||||
top: -6rpx;
|
||||
right: -6rpx;
|
||||
z-index: 2;
|
||||
z-index: 3;
|
||||
min-width: 32rpx;
|
||||
height: 32rpx;
|
||||
padding: 0 6rpx;
|
||||
@@ -352,13 +350,17 @@ const navigateToSection = (section: string, subSection?: string) => {
|
||||
line-height: 32rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #ff4757; // 明确的红色
|
||||
background-color: #ff4757;
|
||||
border: 2rpx solid #fff;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.stats-card) {
|
||||
margin: 20rpx 30rpx !important;
|
||||
}
|
||||
|
||||
// 服务图标
|
||||
.service-icon {
|
||||
display: flex;
|
||||
@@ -366,56 +368,8 @@ const navigateToSection = (section: string, subSection?: string) => {
|
||||
justify-content: center;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background-color: var(--wot-color-bg-light, #f3f4f6);
|
||||
background-color: var(--wot-color-bg-light);
|
||||
border-radius: 16rpx;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
background-color: var(--wot-color-theme, #165dff);
|
||||
transform: scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
// 数据统计项
|
||||
.stats-item {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
background-color: var(--wot-color-bg-light, #f8f9fa);
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
// 卡片动画
|
||||
:deep(.stats-card) {
|
||||
margin: 20rpx 30rpx;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
|
||||
transform: translateY(-2rpx);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.tools-card),
|
||||
:deep(.services-card) {
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
|
||||
transform: translateY(-2rpx);
|
||||
}
|
||||
}
|
||||
|
||||
// 服务项动画
|
||||
:deep(.service-cell) {
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:active {
|
||||
background-color: var(--wot-color-bg-light, #f8f9fa) !important;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
// 登录按钮样式
|
||||
@@ -426,7 +380,7 @@ const navigateToSection = (section: string, subSection?: string) => {
|
||||
|
||||
// 退出登录按钮样式
|
||||
:deep(.logout-button) {
|
||||
width: 100% !important;
|
||||
width: 80% !important;
|
||||
height: 80rpx !important;
|
||||
font-size: 32rpx !important;
|
||||
font-weight: bold !important;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<!-- 头部标题 -->
|
||||
<view class="header">
|
||||
<view class="title">完善个人信息</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-card v-if="userProfile" custom-style="margin-top: 20rpx">
|
||||
<wd-cell-group border>
|
||||
<wd-cell class="avatar-cell" title="头像" center is-link>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-card>
|
||||
<wd-cell-group border>
|
||||
<wd-cell
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-collapse v-model="activeNames" accordion>
|
||||
<wd-collapse-item
|
||||
v-for="(section, index) in agreementContent"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-cell-group>
|
||||
<wd-cell v-if="isLogin" title="个人资料" icon="user" is-link @click="navigateToProfile" />
|
||||
<wd-cell
|
||||
@@ -26,7 +26,7 @@
|
||||
</wd-cell-group>
|
||||
|
||||
<view v-if="isLogin" class="logout-section">
|
||||
<wd-button class="logout-btn" @click="handleLogout">退出登录</wd-button>
|
||||
<wd-button custom-class="logout-btn" plain @click="handleLogout">退出登录</wd-button>
|
||||
</view>
|
||||
|
||||
<!-- 使用wot-design-uni的Loading组件 -->
|
||||
@@ -210,27 +210,21 @@ onLoad(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 20rpx;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 90%;
|
||||
height: 90rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
background-color: var(--wot-color-theme, var(--primary-color));
|
||||
border: none;
|
||||
border-radius: 45rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(22, 93, 255, 0.3);
|
||||
transition: opacity 0.2s;
|
||||
// 退出登录按钮样式
|
||||
:deep(.logout-btn) {
|
||||
width: 80% !important;
|
||||
height: 80rpx !important;
|
||||
font-size: 32rpx !important;
|
||||
font-weight: bold !important;
|
||||
border-radius: 40rpx !important;
|
||||
transition: all 0.3s ease !important;
|
||||
|
||||
&:active {
|
||||
opacity: 0.85;
|
||||
opacity: 0.8 !important;
|
||||
transform: scale(0.98) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<!-- 网络状态展示 -->
|
||||
<wd-card>
|
||||
<wd-cell-group border>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<view class="app-container">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<!-- 暗黑模式设置 -->
|
||||
<wd-card custom-class="mx-30rpx my-20rpx">
|
||||
<template #header>
|
||||
<view class="flex-start">
|
||||
<wd-icon name="moon" size="20" :color="isDarkMode ? '#FFD700' : '#666'" />
|
||||
<wd-icon name="moon" size="20" />
|
||||
<text class="ml-12rpx text-28rpx font-600">外观模式</text>
|
||||
</view>
|
||||
</template>
|
||||
@@ -18,7 +18,7 @@
|
||||
<wd-card custom-class="mx-30rpx my-20rpx">
|
||||
<template #header>
|
||||
<view class="flex-start">
|
||||
<wd-icon name="palette" size="20" color="#666" />
|
||||
<wd-icon name="palette" size="20" />
|
||||
<text class="ml-12rpx text-28rpx font-600">主题色彩</text>
|
||||
</view>
|
||||
</template>
|
||||
@@ -65,7 +65,7 @@
|
||||
<!-- 自定义颜色 -->
|
||||
<wd-cell title="自定义颜色" is-link @click="showCustomInput">
|
||||
<template #icon>
|
||||
<wd-icon name="edit" size="16" :color="themeStore.isDark ? '#fff' : '#999'" />
|
||||
<wd-icon name="edit" size="16" />
|
||||
</template>
|
||||
</wd-cell>
|
||||
</wd-card>
|
||||
@@ -103,12 +103,7 @@
|
||||
<view class="custom-color-popup">
|
||||
<view class="custom-color-popup__header">
|
||||
<text class="custom-color-popup__title">自定义主题色</text>
|
||||
<wd-icon
|
||||
name="close"
|
||||
size="20"
|
||||
:color="themeStore.isDark ? '#999' : '#666'"
|
||||
@click="showCustomColorInput = false"
|
||||
/>
|
||||
<wd-icon name="close" size="20" @click="showCustomColorInput = false" />
|
||||
</view>
|
||||
|
||||
<view class="custom-color-popup__content">
|
||||
@@ -356,7 +351,7 @@ onShow(() => {
|
||||
// 自定义颜色弹窗
|
||||
.custom-color-popup {
|
||||
min-height: 400rpx;
|
||||
background-color: var(--wot-card-bg);
|
||||
background-color: var(--wot-color-bg);
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
|
||||
&__header {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="app-container dark:text-[var(--wot-dark-color)]">
|
||||
<view class="app-container dark:text-[var(--wot-color-text)]">
|
||||
<wd-status-tip type="search" tip="建设中..." />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<svg width="100%" height="100%" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="100%" height="100%" viewBox="0 0 750 1334" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- 背景渐变 -->
|
||||
<defs>
|
||||
<!-- 主背景渐变 - 蓝色系 -->
|
||||
@@ -31,18 +31,18 @@
|
||||
<rect width="100%" height="50%" fill="url(#bgGradient)" />
|
||||
|
||||
<!-- 左侧装饰图形 -->
|
||||
<rect x="100" y="150" width="120" height="120" rx="15" fill="url(#shapeGradient)" transform="rotate(-10, 160, 210)" opacity="0.7" />
|
||||
<rect x="190" y="90" width="80" height="80" rx="10" fill="url(#shapeGradient)" transform="rotate(15, 230, 130)" opacity="0.6" />
|
||||
<rect x="60" y="250" width="100" height="100" rx="10" fill="url(#shapeGradient)" transform="rotate(-5, 110, 300)" opacity="0.5" />
|
||||
<rect x="60" y="120" width="110" height="110" rx="15" fill="url(#shapeGradient)" transform="rotate(-10, 115, 175)" opacity="0.7" />
|
||||
<rect x="140" y="70" width="75" height="75" rx="10" fill="url(#shapeGradient)" transform="rotate(15, 177, 107)" opacity="0.6" />
|
||||
<rect x="30" y="220" width="90" height="90" rx="10" fill="url(#shapeGradient)" transform="rotate(-5, 75, 265)" opacity="0.5" />
|
||||
|
||||
<!-- 右侧装饰图形 -->
|
||||
<circle cx="750" cy="150" r="60" fill="url(#shapeGradient)" opacity="0.7" />
|
||||
<circle cx="820" cy="230" r="90" fill="url(#shapeGradient)" opacity="0.5" />
|
||||
<circle cx="690" cy="250" r="40" fill="url(#shapeGradient)" opacity="0.6" />
|
||||
<!-- 右侧装饰图形(对称) -->
|
||||
<circle cx="635" cy="120" r="55" fill="url(#shapeGradient)" opacity="0.7" />
|
||||
<circle cx="573" cy="70" r="37" fill="url(#shapeGradient)" opacity="0.6" />
|
||||
<circle cx="675" cy="220" r="45" fill="url(#shapeGradient)" opacity="0.5" />
|
||||
|
||||
<!-- 底部波浪形状,适配深色和浅色模式 -->
|
||||
<path d="M0,900 C200,800 350,950 550,870 C750,790 850,900 1000,850 L1000,1000 L0,1000 Z" fill="url(#waveGradient)" class="wave-light" />
|
||||
<path d="M0,900 C200,800 350,950 550,870 C750,790 850,900 1000,850 L1000,1000 L0,1000 Z" fill="#1A1A1A" opacity="0" class="wave-dark" />
|
||||
<path d="M0,1200 C150,1100 260,1250 410,1150 C560,1050 640,1180 750,1150 L750,1334 L0,1334 Z" fill="url(#waveGradient)" class="wave-light" />
|
||||
<path d="M0,1200 C150,1100 260,1250 410,1150 C560,1050 640,1180 750,1150 L750,1334 L0,1334 Z" fill="#1A1A1A" opacity="0" class="wave-dark" />
|
||||
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@@ -51,4 +51,4 @@
|
||||
.wave-dark { opacity: 0.7; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -9,9 +9,8 @@ page {
|
||||
|
||||
/* 自定义扩展变量 */
|
||||
--wot-button-normal-bg: #ffffff;
|
||||
--wot-card-bg: #ffffff;
|
||||
--wot-color-bg: #ffffff;
|
||||
--wot-color-bg-light: #f3f4f6;
|
||||
--wot-dark-color: #333333;
|
||||
|
||||
/* 文本颜色变量 */
|
||||
--wot-color-text: #333333;
|
||||
@@ -20,7 +19,6 @@ page {
|
||||
|
||||
/* 边框和背景变量 */
|
||||
--wot-color-border: #e5e7eb;
|
||||
--wot-color-bg-container: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 暗黑主题 (dark) */
|
||||
@@ -32,17 +30,12 @@ page {
|
||||
--wot-color-danger: #ff4757;
|
||||
|
||||
/* 自定义扩展变量 */
|
||||
--wot-button-normal-bg: #2a2a2a;
|
||||
--wot-card-bg: #1b1b1b;
|
||||
--wot-color-bg: #1b1b1b;
|
||||
--wot-color-bg-light: #2a2a2a;
|
||||
--wot-dark-color: #ffffff;
|
||||
|
||||
/* 暗黑模式下的文本颜色变量 */
|
||||
--wot-color-text: #ffffff;
|
||||
--wot-color-text-secondary: #cccccc;
|
||||
--wot-color-text-placeholder: #999999;
|
||||
|
||||
/* 暗黑模式下的边框和背景变量 */
|
||||
--wot-color-border: #374151;
|
||||
--wot-color-bg-container: #111111;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user