Browse Source

增加词条滚动功能

wangyi/feature-20251022162725-启动页登录注册
wangyetao 1 month ago
parent
commit
2a2a772462
  1. 105
      pages/deepMate/deepMate.vue

105
pages/deepMate/deepMate.vue

@ -33,11 +33,10 @@
</view> </view>
<!-- 功能标签栏 --> <!-- 功能标签栏 -->
<view class="function-tabs" v-if="messages.length === 0" scroll-x="true" show-scrollbar="false">
<view class="tab-item ">个股诊断</view>
<view class="tab-item">市场情绪温度计</view>
<view class="tab-item">买卖时机提示</view>
<view class="tab-item">个股</view>
<view class="function-tabs" v-if="messages.length === 0">
<view ref="tabsTrack" class="tabs-track" :style="{ transform: 'translate3d(-' + marqueeOffset + 'px,0,0)' }">
<view class="tab-item" v-for="(tab, idx) in marqueeList" :key="idx">{{ tab }}</view>
</view>
</view> </view>
<!-- 特斯拉推荐卡片 --> <!-- 特斯拉推荐卡片 -->
@ -135,7 +134,7 @@
<script setup> <script setup>
const { safeAreaInsets } = uni.getSystemInfoSync(); const { safeAreaInsets } = uni.getSystemInfoSync();
import { ref, onMounted, nextTick } from "vue";
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue";
const inputMessage = ref(""); const inputMessage = ref("");
const isSending = ref(false); const isSending = ref(false);
@ -164,17 +163,96 @@ const hotTopics = ref([
} }
]); ]);
// tabs
const tabsList = ref(['个股诊断', '市场情绪温度计', '买卖时机提示', '个股']);
const marqueeList = computed(() => tabsList.value.concat(tabsList.value));
// /App
const tabsTrack = ref(null);
const marqueeOffset = ref(0);
let tabsTickId = 0;
const marqueeSpeed = 0.6; // /
let currentThreshold = 0; // ()
let contentWidthHalf = 0; //
// raf/caf rAF
const hasRAF = typeof requestAnimationFrame === 'function';
const startFrame = (fn) => hasRAF ? requestAnimationFrame(fn) : setTimeout(fn, 16);
const stopFrame = (id) => hasRAF ? cancelAnimationFrame(id) : clearTimeout(id);
// DOM
const measureContentWidth = (cb) => {
const q = uni.createSelectorQuery();
q.select('.function-tabs .tabs-track').boundingClientRect();
q.exec(res => {
const rect = res && res[0];
if (rect && rect.width) {
contentWidthHalf = rect.width / 2;
if (typeof cb === 'function') cb(contentWidthHalf);
} else {
setTimeout(() => measureContentWidth(cb), 16);
}
});
};
// measureFirstThreshold
const measureFirstThreshold = (cb) => {
if (!tabsList.value.length) { currentThreshold = 0; if (cb) cb(0); return; }
const q = uni.createSelectorQuery();
q.selectAll('.function-tabs .tab-item').boundingClientRect();
q.exec(res => {
if (res && res[0] && res[0].length) {
const firstRect = res[0][0];
const marginRightPx = uni.upx2px(20);
currentThreshold = (firstRect?.width || 0) + marginRightPx;
if (typeof cb === 'function') cb(currentThreshold);
} else {
//
setTimeout(() => measureFirstThreshold(cb), 16);
}
});
};
const startTabsMarquee = () => {
stopFrame(tabsTickId);
if (tabsList.value.length <= 1) return; //
marqueeOffset.value = 0;
nextTick(() => {
measureContentWidth(() => {
const step = () => {
marqueeOffset.value += marqueeSpeed;
if (contentWidthHalf > 0 && marqueeOffset.value >= contentWidthHalf) {
marqueeOffset.value = 0; // 0
}
tabsTickId = startFrame(step);
};
step();
});
});
};
// //
onMounted(() => { onMounted(() => {
initUUID(); initUUID();
//
if (messages.value.length === 0) {
nextTick(startTabsMarquee);
}
if (messages.value.length > 0) { if (messages.value.length > 0) {
nextTick(() => {
scrollToBottom();
nextTick(() => { scrollToBottom(); });
}
}); });
//
watch(messages, (val) => {
if (val.length === 0) {
nextTick(startTabsMarquee);
} else {
stopFrame(tabsTickId);
} }
}); });
onUnmounted(() => { stopFrame(tabsTickId); });
// UUID // UUID
const initUUID = () => { const initUUID = () => {
let storedUUID = uni.getStorageSync('user_uuid'); let storedUUID = uni.getStorageSync('user_uuid');
@ -412,10 +490,17 @@ const scrollToTop = () => {
} }
.function-tabs { .function-tabs {
display: flex;
display: block;
overflow: hidden;
margin-bottom: 30rpx; margin-bottom: 30rpx;
} }
.tabs-track {
display: inline-flex;
white-space: nowrap;
will-change: transform;
}
.tab-item { .tab-item {
padding: 5rpx 20rpx; padding: 5rpx 20rpx;
border-radius: 20rpx; border-radius: 20rpx;

Loading…
Cancel
Save