refactor: improve home page components and nav
Replace uni-app navigation with vue router in MoreService, update route paths Refactor FindTabs scroll logic, remove unused imports and legacy code Fix tab indicator image swap and switch from tap to click event Adjust UI icons, padding and popup background across components Remove unnecessary wrapper around FindTabs in Discovery component
This commit is contained in:
@@ -43,7 +43,7 @@
|
|||||||
<!-- 录音按钮 -->
|
<!-- 录音按钮 -->
|
||||||
<RecordingWaveBtn v-if="visibleWaveBtn" ref="recordingWaveBtnRef" />
|
<RecordingWaveBtn v-if="visibleWaveBtn" ref="recordingWaveBtnRef" />
|
||||||
|
|
||||||
<div class="text-center text-[9px] leading-[12px] text-[#A5AAB4]">
|
<div class="text-center text-[9px] leading-[12px] text-[#A5AAB4] pb-[6px]">
|
||||||
内容由AI大模型生成,请仔细鉴别
|
内容由AI大模型生成,请仔细鉴别
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-[44px] flex items-center pl-[12px] pr-[12px]">
|
<div class="h-[44px] flex items-center pl-[12px] pr-[12px]">
|
||||||
<div class="w-[24px] h-[24px] flex items-center justify-center">
|
<div class="w-[24px] h-[24px] flex items-center justify-center">
|
||||||
<van-icon name="setting" size="24" color="#fff" @click="showDrawer" />
|
<van-icon name="wap-nav" size="24" color="#fff" @click="showDrawer" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 隐藏 -->
|
<!-- 隐藏 -->
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-full bg-transparent">
|
<div class="w-full bg-transparent">
|
||||||
<div class="w-full overflow-x-auto scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden"
|
<div ref="tabsScrollRef"
|
||||||
:scroll-left="scrollLeft" scroll-with-animation="true" @scroll="handleScroll">
|
class="tabs-scroll w-full overflow-x-auto scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden">
|
||||||
<div class="flex items-end h-[50px] gap-4 flex-nowrap px-3">
|
<div class="flex items-end h-[50px] gap-4 flex-nowrap px-3">
|
||||||
<div v-for="(tab, idx) in tabs" :key="idx" :id="getTabId(idx)"
|
<div v-for="(tab, idx) in tabs" :key="idx" :id="getTabId(idx)"
|
||||||
class="relative inline-flex items-center justify-center h-[50px] shrink-0" @tap="handleSwitch(tab, idx)">
|
class="relative inline-flex items-center justify-center h-[50px] shrink-0" @click="handleSwitch(tab, idx)">
|
||||||
<div class="relative flex items-center justify-center h-[50px]">
|
<div class="relative flex items-center justify-center h-[50px]">
|
||||||
<div class="relative inline-flex items-center justify-center">
|
<div class="relative inline-flex items-center justify-center">
|
||||||
<span
|
<span
|
||||||
:class="['relative text-base font-medium text-[#808c99]/90 z-10 px-1 leading-none', modelValue === idx ? 'text-[#0b0b0b] font-bold' : '']">
|
:class="['relative text-base z-10 px-1 leading-none', modelValue === idx ? 'text-[#0b0b0b] font-bold' : 'font-medium text-[#808c99]/90']">
|
||||||
{{ tab.label }}
|
{{ tab.label }}
|
||||||
</span>
|
</span>
|
||||||
<img v-if="modelValue === idx && (isZhiNian ? indicatorSrcB : indicatorSrc)"
|
<img v-if="modelValue === idx && (isZhiNian ? indicatorSrcB : indicatorSrc)"
|
||||||
:src="isZhiNian ? indicatorSrcB : indicatorSrc"
|
:src="isZhiNian ? indicatorSrc : indicatorSrcB"
|
||||||
class="absolute -bottom-[6px] left-1/2 -translate-x-1/2 w-[56px] h-auto z-[1]" />
|
class="absolute -bottom-[6px] left-1/2 -translate-x-1/2 w-[56px] h-auto z-[1]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -23,13 +23,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance, nextTick, onMounted, ref, watch } from "vue";
|
import { nextTick, onMounted, ref, watch } from "vue";
|
||||||
import { isZhiNian } from "@/constants/base";
|
import { isZhiNian } from "@/constants/base";
|
||||||
import indicatorSrc from "./images/selected_tabs_icon.png";
|
import indicatorSrc from "./images/selected_tabs_icon.png";
|
||||||
import indicatorSrcB from "./images/selected_tabs_icon_b.png";
|
import indicatorSrcB from "./images/selected_tabs_icon_b.png";
|
||||||
|
|
||||||
const instance = getCurrentInstance();
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: Number, default: 0 },
|
modelValue: { type: Number, default: 0 },
|
||||||
tabs: {
|
tabs: {
|
||||||
@@ -40,37 +38,32 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['update:modelValue', 'change']);
|
const emit = defineEmits(['update:modelValue', 'change']);
|
||||||
|
|
||||||
const scrollLeft = ref(0);
|
const tabsScrollRef = ref(null);
|
||||||
let currentScrollLeft = 0;
|
|
||||||
|
|
||||||
const getTabId = (idx) => `find-tab-${idx}`;
|
const getTabId = (idx) => `find-tab-${idx}`;
|
||||||
|
|
||||||
const handleScroll = (e) => {
|
|
||||||
currentScrollLeft = e.detail?.scrollLeft || 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
const centerActiveTab = async () => {
|
const centerActiveTab = async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
const activeIndex = props.modelValue;
|
const activeIndex = props.modelValue;
|
||||||
if (activeIndex < 0 || activeIndex >= props.tabs.length) return;
|
if (activeIndex < 0 || activeIndex >= props.tabs.length) return;
|
||||||
if (!instance || typeof uni === "undefined" || !uni.createSelectorQuery) return;
|
|
||||||
|
|
||||||
const query = uni.createSelectorQuery().in(instance);
|
const scrollEl = tabsScrollRef.value;
|
||||||
query.select(".tabs-scroll").boundingClientRect();
|
const activeEl = scrollEl?.querySelector(`#${getTabId(activeIndex)}`);
|
||||||
query.select(".tabs-scroll").scrollOffset();
|
if (!scrollEl || !activeEl) return;
|
||||||
query.select(`#${getTabId(activeIndex)}`).boundingClientRect();
|
|
||||||
query.exec((res) => {
|
|
||||||
const [scrollRect, scrollOffset, activeRect] = res || [];
|
|
||||||
if (!scrollRect || !activeRect) return;
|
|
||||||
|
|
||||||
const currentLeft = scrollOffset?.scrollLeft ?? currentScrollLeft;
|
const scrollRect = scrollEl.getBoundingClientRect();
|
||||||
const targetScrollLeft =
|
const activeRect = activeEl.getBoundingClientRect();
|
||||||
currentLeft +
|
const maxScrollLeft = Math.max(0, scrollEl.scrollWidth - scrollEl.clientWidth);
|
||||||
activeRect.left - scrollRect.left -
|
const targetScrollLeft =
|
||||||
(scrollRect.width - activeRect.width) / 2;
|
scrollEl.scrollLeft +
|
||||||
|
activeRect.left - scrollRect.left -
|
||||||
|
(scrollRect.width - activeRect.width) / 2;
|
||||||
|
const nextScrollLeft = Math.min(Math.max(0, targetScrollLeft), maxScrollLeft);
|
||||||
|
|
||||||
scrollLeft.value = Math.max(0, targetScrollLeft);
|
scrollEl.scrollTo({
|
||||||
|
left: nextScrollLeft,
|
||||||
|
behavior: "smooth",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col h-full overflow-hidden">
|
<div class="flex flex-col h-full overflow-hidden">
|
||||||
<div class="shrink-0">
|
<FindTabs v-if="discoveryTabs.length" v-model="activeIndex" :tabs="discoveryTabs" @change="handleTabChange" />
|
||||||
<FindTabs v-if="discoveryTabs.length" v-model="activeIndex" :tabs="discoveryTabs" @change="handleTabChange" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="discovery-scroll flex-1" overflow-y @touchstart="emitScrollTouchStart" @touchmove="emitScrollTouch"
|
<div class="discovery-scroll flex-1" overflow-y @touchstart="emitScrollTouchStart" @touchmove="emitScrollTouch"
|
||||||
@scroll="emitScrollTouch">
|
@scroll="emitScrollTouch">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="bg-white rounded-[6px] pl-[12px] mb-[10px]">
|
<div class="bg-white rounded-[6px] pl-[12px] mb-[10px]">
|
||||||
<div class="flex justify-between items-center py-[12px] pr-[12px] pl-0 border-b border-[#f0f0f0] last:border-b-0">
|
<div class="flex justify-between items-center py-[12px] pr-[12px] pl-0 border-b border-[#f0f0f0] last:border-b-0">
|
||||||
<span class="text-[14px] text-[#333]">头像 </span>
|
<span class="text-[14px] text-[#333]">头像 </span>
|
||||||
<van-icon name="phone" size="20" color="#ccc"></van-icon>
|
<van-icon name="contact" size="20" color="#ccc"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center py-[12px] pr-[12px] pl-0 border-b border-[#f0f0f0] last:border-b-0">
|
<div class="flex justify-between items-center py-[12px] pr-[12px] pl-0 border-b border-[#f0f0f0] last:border-b-0">
|
||||||
<span class="text-[14px] text-[#333]">昵称</span>
|
<span class="text-[14px] text-[#333]">昵称</span>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<van-popup ref="popup" position="bottom" v-model:show="show">
|
<van-popup ref="popup" position="bottom" v-model:show="show" style="background: transparent;">
|
||||||
<div class="popup-content bg-[#f5f7fa] rounded-t-[15px] pt-[12px] pl-[12px] pr-[12px] pb-[30px]">
|
<div class="popup-content bg-[#f5f7fa] rounded-t-[15px] pt-[12px] pl-[12px] pr-[12px] pb-[30px]">
|
||||||
<div class="flex items-center pb-[12px]">
|
<div class="flex items-center pb-[12px]">
|
||||||
<div class="title flex-1 text-center text-[17px] text-black font-medium ml-24">更多服务</div>
|
<div class="title flex-1 text-center text-[17px] text-black font-medium ml-24">更多服务</div>
|
||||||
@@ -32,11 +32,13 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
import { Command } from "@/constants/ChatModel";
|
import { Command } from "@/constants/ChatModel";
|
||||||
import { SEND_MESSAGE_COMMAND_TYPE } from "@/constants/constant";
|
import { SEND_MESSAGE_COMMAND_TYPE } from "@/constants/constant";
|
||||||
import { checkToken } from "@/hooks/useGoLogin";
|
import { checkToken } from "@/hooks/useGoLogin";
|
||||||
import { emitter } from '@/utils/events'
|
import { emitter } from '@/utils/events'
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
const popup = ref(null);
|
const popup = ref(null);
|
||||||
|
|
||||||
const list = ref([
|
const list = ref([
|
||||||
@@ -46,7 +48,7 @@ const list = ref([
|
|||||||
content: "预定门票、房间、餐食",
|
content: "预定门票、房间、餐食",
|
||||||
btnText: "去预定",
|
btnText: "去预定",
|
||||||
type: Command.quickBooking,
|
type: Command.quickBooking,
|
||||||
path: "/pages-quick/list",
|
path: "/quick",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "https://oss.nianxx.cn/mp/static/version_101/home/tsfx.png",
|
icon: "https://oss.nianxx.cn/mp/static/version_101/home/tsfx.png",
|
||||||
@@ -62,7 +64,7 @@ const list = ref([
|
|||||||
content: "查看门票、住宿、餐饮等订单",
|
content: "查看门票、住宿、餐饮等订单",
|
||||||
btnText: "去查看",
|
btnText: "去查看",
|
||||||
type: Command.myOrder,
|
type: Command.myOrder,
|
||||||
path: "/pages-order/order/list",
|
path: "/order",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "https://oss.nianxx.cn/mp/static/version_101/home/wdgd.png",
|
icon: "https://oss.nianxx.cn/mp/static/version_101/home/wdgd.png",
|
||||||
@@ -70,7 +72,7 @@ const list = ref([
|
|||||||
content: "查看呼叫服务、进度与处理情况",
|
content: "查看呼叫服务、进度与处理情况",
|
||||||
btnText: "去查看",
|
btnText: "去查看",
|
||||||
type: Command.myWorkOrder,
|
type: Command.myWorkOrder,
|
||||||
path: "/pages-service/order/list",
|
path: "/service",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "https://oss.nianxx.cn/mp/static/version_101/home/fkyj.png",
|
icon: "https://oss.nianxx.cn/mp/static/version_101/home/fkyj.png",
|
||||||
@@ -97,7 +99,7 @@ const handleClick = (item) => {
|
|||||||
|
|
||||||
if (item.path) {
|
if (item.path) {
|
||||||
checkToken().then(() => {
|
checkToken().then(() => {
|
||||||
uni.navigateTo({ url: item.path });
|
router.push({ path: item.path });
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user