优化:底部导航菜单

This commit is contained in:
2025-07-11 21:47:48 +08:00
parent 8375c2d6e4
commit 2a7ca140c7
13 changed files with 521 additions and 87 deletions

View File

@@ -30,6 +30,7 @@ const Index = () => {
// 当前栏目信息
if (navs) {
setNavigation(navs);
Taro.setNavigationBarTitle({title: `${navs.title}`})
}
// 获取子级栏目
if (childCateogry) {

View File

@@ -0,0 +1,209 @@
/* H5专用TabBar样式 */
.simple-h5-tabbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
background-color: #ffffff;
border-top: 1px solid #e5e5e5;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
.h5-tabbar-container {
display: flex;
height: 60px;
align-items: center;
justify-content: space-around;
padding: 0 16px;
width: 100%;
.h5-tabbar-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
position: relative;
cursor: pointer;
transition: all 0.3s ease;
// 普通图标样式
.h5-normal-icon {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
margin-bottom: 4px;
transition: transform 0.3s ease;
.h5-icon-emoji {
font-size: 20px;
transition: transform 0.3s ease;
}
}
// 特殊AI按钮样式
.h5-special-icon {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: -8px;
.h5-ai-circle {
width: 48px;
height: 48px;
border-radius: 50%;
background: #ffffff;
display: flex;
align-items: center;
justify-content: center;
position: relative;
top: -20px;
transition: all 0.3s ease;
.h5-ai-text {
color: #ffffff;
font-size: 14px;
font-weight: bold;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
// 光晕效果
&::before {
content: '';
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
border-radius: 50%;
opacity: 0;
transition: opacity 0.3s ease;
}
&:active {
transform: scale(0.95);
}
}
}
// 文字样式
.h5-tabbar-text {
font-size: 12px;
color: #8a8a8a;
transition: color 0.3s ease;
text-align: center;
line-height: 1.2;
&.selected {
color: #d81e06;
font-weight: 500;
}
&.special-text {
color: #ff6b35;
font-weight: 500;
margin-top: -12px;
}
}
// 选中状态
&.selected {
.h5-normal-icon {
transform: translateY(-2px);
.h5-icon-emoji {
transform: scale(1.1);
}
}
}
// 特殊项目样式
&.special {
.h5-special-icon .h5-ai-circle {
&::before {
opacity: 1;
}
}
&.selected {
.h5-special-icon .h5-ai-circle {
background: linear-gradient(135deg, #ff6b35 0%, #ff4500 100%);
box-shadow: 0 6px 16px rgba(255, 69, 0, 0.5);
&::before {
background: linear-gradient(135deg, rgba(255, 107, 53, 0.5) 0%, rgba(255, 69, 0, 0.5) 100%);
}
}
}
}
// 点击效果
&:active {
.h5-tabbar-text {
transform: scale(0.95);
}
}
}
}
}
// H5全屏适配 - 移除PC端限制因为项目只用于H5端
// 暗色主题支持
@media (prefers-color-scheme: dark) {
.simple-h5-tabbar {
background-color: #1a1a1a;
border-top-color: #333;
.h5-tabbar-container .h5-tabbar-item {
.h5-tabbar-text {
color: #999;
&.selected {
color: #d81e06;
}
&.special-text {
color: #ff6b35;
}
}
}
}
}
// 动画效果
@keyframes h5-bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-4px);
}
60% {
transform: translateY(-2px);
}
}
// 选中时的弹跳效果
.simple-h5-tabbar .h5-tabbar-container .h5-tabbar-item.selected .h5-normal-icon {
animation: h5-bounce 0.6s ease;
}
// AI按钮的脉冲效果
@keyframes h5-pulse {
0% {
box-shadow: 0 4px 12px rgba(255, 107, 53, 0.4);
}
50% {
box-shadow: 0 4px 20px rgba(255, 107, 53, 0.6);
}
100% {
box-shadow: 0 4px 12px rgba(255, 107, 53, 0.4);
}
}
.simple-h5-tabbar .h5-tabbar-container .h5-tabbar-item.special.selected .h5-special-icon .h5-ai-circle {
animation: h5-pulse 2s infinite;
}

View File

@@ -0,0 +1,95 @@
import {useState, useEffect} from 'react';
import {View, Text} from '@tarojs/components';
import Taro from '@tarojs/taro';
import './SimpleH5TabBar.scss';
import {Image} from '@nutui/nutui-react-taro'
interface TabBarProps {
current?: number;
}
interface TabBarItem {
pagePath: string;
text: string;
icon: string;
isSpecial?: boolean;
}
const tabBarData: TabBarItem[] = [
{
pagePath: 'pages/index/index',
text: '首页',
icon: 'https://oss.wsdns.cn/20250711/3f000045aac44a0480b4be0a2c225fe1.png',
},
{
pagePath: 'pages/ai/index',
text: 'AI问答',
icon: 'https://oss.wsdns.cn/20250711/86fdc1ad45a041d797b582ba42c34698.png',
isSpecial: true,
},
{
pagePath: 'pages/user/user',
text: '我的',
icon: 'https://oss.wsdns.cn/20250711/2baaec717bca49e7b58f36a3bd75fc14.png',
},
];
function SimpleH5TabBar({current}: TabBarProps) {
const [selected, setSelected] = useState(current || 0);
useEffect(() => {
console.log('SimpleH5TabBar 组件已挂载, current:', current);
if (typeof current === 'number') {
setSelected(current);
}
}, [current]);
const switchTab = (index: number) => {
console.log('SimpleH5TabBar 点击项目:', index);
setSelected(index);
const urls = [
'/pages/index/index',
'/pages/ai/index',
'/pages/user/user'
];
Taro.switchTab({
url: urls[index],
success: () => console.log('跳转成功:', urls[index]),
fail: (error) => console.error('跳转失败:', error)
});
};
return (
<View className="simple-h5-tabbar">
<View className="h5-tabbar-container">
{tabBarData.map((item, index) => (
<View
key={index}
className={`h5-tabbar-item ${selected === index ? 'selected' : ''} ${item.isSpecial ? 'special' : ''}`}
onClick={() => switchTab(index)}
>
{item.isSpecial ? (
<View className="h5-special-icon">
<View className="h5-ai-circle">
<Image src={item.icon} width={'24px'} height={'24px'}/>
</View>
</View>
) : (
<View className="h5-normal-icon">
<Image src={item.icon} width={'24px'} height={'24px'}/>
</View>
)}
<Text
className={`h5-tabbar-text ${selected === index ? 'selected' : ''} ${item.isSpecial ? 'special-text' : ''}`}>
{item.text}
</Text>
</View>
))}
</View>
</View>
);
}
export default SimpleH5TabBar;

View File

@@ -1,5 +0,0 @@
import SimpleTabBar from '../components/SimpleTabBar';
export default function CustomTabBarWrapper() {
return <SimpleTabBar />;
}

View File

@@ -1,3 +0,0 @@
export default definePageConfig({
navigationBarTitleText: '红色资源'
})

View File

@@ -1,75 +0,0 @@
import {useEffect, useState} from "react";
import {pageCmsArticle} from "@/api/cms/cmsArticle";
import {CmsArticle} from "@/api/cms/cmsArticle/model";
import Taro from '@tarojs/taro'
import {useRouter} from '@tarojs/taro'
import {Image} from '@nutui/nutui-react-taro'
import {getCmsNavigation} from "@/api/cms/cmsNavigation";
import {CmsNavigation} from "@/api/cms/cmsNavigation/model";
/**
* 文章终极列表
* @constructor
*/
const Article = () => {
const {params} = useRouter();
const [navigation, setNavigation] = useState<CmsNavigation>()
const [list, setList] = useState<CmsArticle[]>([])
const reload = async () => {
const categoryId = Number(params.id);
const nav = await getCmsNavigation(categoryId);
const articles = await pageCmsArticle({categoryId});
if(nav){
setNavigation(nav);
}
if(articles){
setList(articles?.list)
}
}
useEffect(() => {
reload()
}, [])
return (
<div className="mobile-container">
<Image
src={navigation?.style}
style={{width: '100%', height: 'auto'}}
mode="widthFix"
/>
<div className={'bg-white rounded-lg py-3 px-2'}>
{/* 宫格布局容器 */}
<div className={'grid grid-cols-3'}>
{
list.map((item, index) => {
return (
<div
key={index}
className={'flex flex-col items-center cursor-pointer my-1'}
onClick={() => Taro.navigateTo({url: `/pages/article/detail?id=${item.articleId}`})}
>
{/* 图片容器 */}
<div className={'w-full mb-2 flex justify-center'}>
<img
className={'object-cover rounded-lg'}
src={item.image}
alt={item.title || ''}
/>
</div>
{/* 标题 */}
<div className={'text-xs text-center text-gray-800 leading-tight px-1'}>
{item.title}
</div>
</div>
)
})
}
</div>
</div>
</div>
)
}
export default Article

View File

@@ -32,6 +32,7 @@ const Index = () => {
const navs = await getCmsNavigation(categoryId);
if (navs) {
setNavigation(navs);
Taro.setNavigationBarTitle({title: `${navs.title}`})
}
// 加载第一页数据

View File

@@ -30,6 +30,7 @@ const Index = () => {
// 当前栏目信息
if (navs) {
setNavigation(navs);
Taro.setNavigationBarTitle({title: `${navs.title}`})
}
// 获取子级栏目
if (childCateogry) {

View File

@@ -29,6 +29,7 @@ const List = () => {
const navs = await getCmsNavigation(categoryId);
if (navs) {
setNavigation(navs);
Taro.setNavigationBarTitle({title: `${navs.title}`})
}
}
@@ -62,7 +63,7 @@ const List = () => {
const nextPage = page + 1;
console.log('honor/list 加载更多 - 下一页:', nextPage);
setPage(nextPage);
reload(nextPage);
reload(nextPage).then();
}
useEffect(() => {
@@ -72,7 +73,7 @@ const List = () => {
setList([]);
setHasMore(true);
// 加载第一页数据
reload(1);
reload(1).then();
}, [])
return (

View File

@@ -30,6 +30,7 @@ const Index = () => {
// 当前栏目信息
if (navs) {
setNavigation(navs);
Taro.setNavigationBarTitle({title: `${navs.title}`})
}
// 获取子级栏目
if (childCateogry) {
@@ -42,7 +43,7 @@ const Index = () => {
}
useEffect(() => {
reload()
reload().then()
}, [])
return (

View File

@@ -28,6 +28,7 @@ const Index = () => {
// 当前栏目信息
if (navs) {
setNavigation(navs);
Taro.setNavigationBarTitle({title: `${navs.title}`})
}
// 新闻列表
if (articles) {
@@ -36,7 +37,7 @@ const Index = () => {
}
useEffect(() => {
reload()
reload().then()
}, [])
return (