Files
91fans_h5/src/components/TabBar/index.vue
T
2026-09-17 15:11:31 +07:00

316 lines
8.7 KiB
Vue

<template>
<div class="tab_wrapper">
<van-tabbar
v-model="activeName"
route
fixed
placeholder
:border="false"
:safe-area-inset-bottom="true"
@change="onChange"
data-ignore-track
>
<!-- :icon="activeName == 'home' ? homeIconActived : homeIcon" -->
<van-tabbar-item to="/home" name="home" replace>
<span class="tabbar-item-text" v-if="isHomeTop" @click="backTop('home')">顶部</span>
<span v-else class="tabbar-item-text">主页</span>
<template #icon="props">
<div
class="tabbar-item"
@click="backTop('home')"
:class="[props.active ? (isHomeTop ? 'top' : 'homeActive') : 'home']"
></div>
</template>
</van-tabbar-item>
<van-tabbar-item to="/shortVideo" name="shortVideo" replace>
<span class="tabbar-item-text">抖音</span>
<template #icon="props">
<div class="tabbar-item" :class="[props.active ? 'liveActive' : 'live']"></div>
</template>
</van-tabbar-item>
<van-tabbar-item to="/darkNet" name="darkNet" replace v-if="darkWebEnable">
<span class="tabbar-item-text" v-if="isDarkNetTop" @click="backTop('darkNet')">顶部</span>
<span v-else class="tabbar-item-text">
<template v-if="darkWebIconName">
{{ darkWebIconName }}
</template>
<template v-else>暗网</template>
</span>
<template #icon="props">
<template v-if="darkWebIcon">
<lazyImg :src="darkWebIcon" alt="darkWebIcon" v-if="props.active && !isDarkNetTop" />
<div
v-else
class="tabbar-item"
@click="backTop('darkNet')"
:class="[props.active ? (isDarkNetTop ? 'top' : 'darkNetActive') : 'darkNet']"
></div>
</template>
<template v-else>
<div
class="tabbar-item"
@click="backTop('darkNet')"
:class="[props.active ? (isDarkNetTop ? 'top' : 'darkNetActive') : 'darkNet']"
></div>
</template>
</template>
</van-tabbar-item>
<van-tabbar-item to="/aiUndress2" name="aiUndress2" replace>
<span class="tabbar-item-text">AI</span>
<template #icon="props">
<div class="tabbar-item" :class="[props.active ? 'aiActive' : 'ai']"></div>
</template>
</van-tabbar-item>
<van-tabbar-item to="/community" name="community" replace>
<span class="tabbar-item-text" v-if="isCommunityTop" @click="backTop('community')">顶部</span>
<span v-else class="tabbar-item-text">社区</span>
<template #icon="props">
<div
class="tabbar-item"
@click="backTop('community')"
:class="[props.active ? (isCommunityTop ? 'top' : 'communityActive') : 'community']"
></div>
</template>
</van-tabbar-item>
<van-tabbar-item to="/mine" name="mine" replace>
<span class="tabbar-item-text">我的</span>
<template #icon="props">
<div class="tabbar-item" :class="[props.active ? 'mineActive' : 'mine']"></div>
</template>
<div v-if="showRedDot" class="newsTip"></div>
</van-tabbar-item>
</van-tabbar>
<!-- warning提示 -->
<van-popup class="waringBox" v-model:show="state.showWarning" :close-on-click-overlay="false">
<div class="waringBoxTip">
<div class="title">WANRNING</div>
<div class="content">该板块内容极度危险,心理承受弱者请自行离开,切记挑战自己好奇害死猫,请您确认还要继续吗?</div>
<div class="btnBox flex-center-between">
<div class="btn" @click.stop="leave">离开</div>
<div class="btn red" @click="state.showWarning = false">确认</div>
</div>
</div>
</van-popup>
</div>
</template>
<script lang="ts">
export default {
name: 'TabBar',
};
</script>
<script lang="ts" setup>
import { ref, toRefs, watch, reactive, onActivated, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import UserApi from '@/service/user';
import { useUserStore } from '@/stores/user';
import { useConfigStore } from '@/stores/config';
import { useGlobalStore } from '@/stores/global';
import setTheme from '@/assets/theme/index';
const configStore = useConfigStore();
const globalStore = useGlobalStore();
setTheme(configStore.appConfig.festivalUi);
const darkWebEnable = computed(() => {
return configStore.appConfig.darkWebEnable;
});
const darkWebIcon = computed(() => {
return configStore.appConfig.darkWebIcon;
});
const darkWebIconName = computed(() => {
return configStore.appConfig.darkWebIconName;
});
const router = useRouter();
const route = useRoute();
const activeName = ref('home');
const state = reactive({
showWarning: false,
userInfo: <Types.User.UserInfoType>{},
});
const refreshRoute = (name: any) => {
activeName.value = name;
};
watch(route, (newVal) => {
refreshRoute(newVal.name);
});
/**
* 获取用户信息
* @param uid
*/
const getInfo = async () => {
try {
let res: any = await UserApi.queryUserInfo(null);
state.userInfo = res;
} catch (e) {
console.log(e);
}
};
getInfo();
const change = (activeName: any) => {
if (activeName == 'darkNet') {
if (state.userInfo.isVip) {
state.showWarning = true;
}
}
};
const leave = () => {
activeName.value = 'home';
router.replace('/home');
state.showWarning = false;
};
const UserStore = useUserStore();
onActivated(() => {
refreshRoute(route.name);
UserStore.getCheckMessageTip();
});
const onChange = (name: string) => {
UserStore.getCheckMessageTip();
};
const { isNewsTip } = toRefs(UserStore);
/** 我的页红点:业务未读 */
const showRedDot = computed(() => Boolean(isNewsTip.value));
const backTop = (path: string) => {
let dom: any = null;
if (path == 'home') {
if (!isHomeTop.value) return;
dom = document.getElementById(path + globalStore.activeIndex);
} else if (path == 'darkNet') {
if (!isDarkNetTop.value) return;
dom = document.getElementById(path + globalStore.darkNetActiveIndex);
} else if (path == 'community') {
if (!isCommunityTop.value) return;
dom = document.getElementById(path + globalStore.communityActiveIndex);
}
dom?.scrollTo({ top: 0, behavior: 'smooth' });
const arr = globalStore.keepScroll[`/${path}`];
arr.map((item: any) => {
if (item.scrollObj == globalStore.activeIndex) {
item.showBackTopBtn = false;
}
return item;
});
globalStore.keepScroll[`/${path}`] = arr;
};
const isHomeTop = computed(() => {
return (
activeName.value == 'home' &&
globalStore.keepScroll['/home']?.find((item) => item.scrollObj == globalStore.activeIndex)?.showBackTopBtn
);
});
const isDarkNetTop = computed(() => {
return (
activeName.value == 'darkNet' &&
globalStore.keepScroll['/darkNet']?.find((item) => item.scrollObj == globalStore.darkNetActiveIndex)?.showBackTopBtn
);
});
const isCommunityTop = computed(() => {
return (
activeName.value == 'community' &&
globalStore.keepScroll['/community']?.find((item) => item.scrollObj == globalStore.communityActiveIndex)
?.showBackTopBtn
);
});
</script>
<style lang="scss" scoped>
@media (min-height: 700px) {
.tab_wrapper {
.marqueeBar {
top: -64px !important;
}
}
}
:deep(.van-tabbar) {
background: rgb(0, 0, 0);
height: 55px;
z-index: 1000;
}
.van-tabbar-item--active {
background: rgb(0, 0, 0);
}
:deep(.van-tabbar--fixed) {
max-width: 780px;
margin: 0 auto;
left: 50%;
transform: translateX(-50%);
}
:deep(.van-tabbar__placeholder) {
margin: 0 auto;
}
:deep(.van-icon__image) {
width: 24px;
height: 24px;
}
:deep(.van-tabbar-item__text) {
font-size: 12px;
}
.tab_wrapper {
position: relative;
.marqueeBar {
height: 31px;
width: 100%;
padding: 6px 10px;
position: absolute;
left: 0;
top: -32px;
z-index: 999;
}
}
.waringBox {
.waringBoxTip {
height: 235px;
width: 307px;
background-color: rgb(34, 34, 34);
border-radius: 8px;
overflow: hidden;
.title {
height: 60px;
background-color: rgb(255, 50, 48);
font-size: 24px;
text-align: center;
line-height: 60px;
}
.content {
font-size: 16px;
padding: 23px 20px;
line-height: 20px;
}
.btnBox {
padding: 0 20px;
.btn {
font-size: 15px;
height: 40px;
width: 120px;
background-color: rgb(61, 61, 61);
text-align: center;
line-height: 40px;
border-radius: 40px;
}
.red {
background-color: rgb(255, 50, 48);
}
}
}
}
.newsTip {
position: absolute;
bottom: 16px;
right: 0;
width: 6px;
height: 6px;
border-radius: 50%;
background: #fd0563;
}
</style>